diff options
Diffstat (limited to 'tnslc/compile/struct.tnsl')
| -rw-r--r-- | tnslc/compile/struct.tnsl | 263 |
1 files changed, 234 insertions, 29 deletions
diff --git a/tnslc/compile/struct.tnsl b/tnslc/compile/struct.tnsl index d175aef..eba1488 100644 --- a/tnslc/compile/struct.tnsl +++ b/tnslc/compile/struct.tnsl @@ -3,44 +3,249 @@ struct Struct { ~uint8 name, ~Module methods, utils.Vector members, - int size + int size, + + ~parse.Node _up } +~uint8 PRIMITIVE_1 = "bool,uint8,int8\0" +~uint8 PRIMITIVE_2 = "uint16,int16\0" +~uint8 PRIMITIVE_4 = "uint32,int32,float32\0" +~uint8 PRIMITIVE_8 = "uint64,int64,float64,int,uint,float,void\0" + +/; is_primitive (~parse.Node tn) [int] + /; if (tn`.sub.count < 1) + return 0 + ;/ + + ~parse.Node n = tn`.sub.get(0) + + # Check for pointer, array + /; if (n`._type == parse.NTYPE_PRE_OP) + return 8 + ;/ + + # Check for ref + n = tn`.sub.get(tn`.sub.count - 1) + /; if (n`._type == parse.NTYPE_POST_OP) + return 8 + ;/ + + return 0 +;/ + +/; _print_type(~parse.Node tn) + ~parse.Node n + bool seen_id = false + /; loop (int i = 0; i < tn`.sub.count) [i++] + + n = tn`.sub.get(i) + + /; if (n`._type == parse.NTYPE_ID) + /; if (seen_id == true) + _printf(".\0") + ;/ + _printf(n`.data) + seen_id = true + ;; else + return + ;/ + ;/ +;/ + +# Might be wrong +/; _type_is_ptr (~parse.Node n) [bool] + # Sanity + /; if (n`.sub.count < 1) + return false + ;/ + + ~parse.Node op = n`.sub.get(0) + /; if (op`._type == parse.NTYPE_PRE_OP) + return true + ;/ + + op = n`.sub.get(n`.sub.count - 1) + /; if (op`._type == parse.NTYPE_POST_OP) + return true + ;/ + + return false +;/ + /; method Struct - /; init (~uint8 name) - self.name = name - Var v - self.members.init(len v) - ;/ + /; init (~parse.Node node) + self._up = node + self.size = 0 + self.methods = NULL + self.name = utils.strcpy(node`.data) + Var v + self.members.init(len v) + ;/ + + /; _print (int idt) + _indent(idt) + _printf("{ Struct : \0") + _printf(self.name) + _printf("\n\0") + + _indent(idt) + _print_num(" size: %d\n\0", self.size) + + _indent(idt) + _printf(" members:\n\0") + + ~Var v + /; loop (int i = 0; i < self.members.count) [i++] + v = self.members.get(i) + v`._print(idt + 1) + ;/ + + _indent(idt) + _printf("}\n\0") + ;/ + + /; add_member(~parse.Node tn, ~parse.Node id) + Var v + v.init(tn, id) + v._resolve_type(self.methods) + self.members.push(~v) + ;/ + + /; get_member(~uint8 name) [~Var] + ~Var out = NULL + + ~Var v + /; loop (int i = 0; i < self.members.count) [i++] + v = self.members.get(i) + /; if (utils.strcmp(v`.name, name) == true) + return v + ;/ + ;/ + + return out + ;/ + + /; _dlist [~parse.Node] + ~parse.Node up = self._up + ~parse.Node n + /; loop (int i = 0; i < up`.sub.count) [i++] + n = up`.sub.get(i) + /; if (n`._type == parse.NTYPE_DLIST) + return n + ;/ + ;/ + return NULL + ;/ + + /; _compute_size + /; if (self.size !== 0) + return + ;/ + + self.size = self.size - 1 + + int total = 0 + ~parse.Node up = self._dlist() + ~parse.Node tn = NULL + ~parse.Node n = NULL + int add_size = 0 + /; loop (int i = 0; i < up`.sub.count) [i++] + n = up`.sub.get(i) + + /; if (n`._type == parse.NTYPE_TYPE) + # Store for generating new variables + tn = n + add_size = self._compute_type_size(n) + /; if (add_size == 0) + return + ;/ + ;; else if (n`._type == parse.NTYPE_ID) + /; if (tn == NULL) + _printf("ERROR: Unable to find type when trying to create member for struct '\0") + _printf(self.name) + _printf("\n\0") + return + ;/ + self.add_member(tn, n) + total = total + add_size + ;/ + ;/ + + self.size = total + ;/ + + /; _compute_type_size(~parse.Node tn) [int] + ~Struct ft = self._find_type(tn) + + /; if (ft == NULL) + # Type not found + _printf("ERROR: Unable to find type '\0") + _print_type(tn) + _printf("' for use in struct '\0") + _printf(self.name) + _printf("'\n\0") + return 0 + ;/ + + /; if (_type_is_ptr(tn) == true) + return 8 + ;/ + + /; if (ft !== NULL && ft`.size == 0) + ft`._compute_size() + ;/ + + /; if (ft`.size < 0) + # Cyclical dependency + _printf("ERROR: Cyclic struct definition: '\0") + _printf(ft`.name) + _printf("' imported from '\0") + _printf(self.name) + _printf("'\n\0") + return 0 + ;/ + + return ft`.size + ;/ - /; add_member(~Var v) - self.members.push(v) - ;/ + /; _find_type (~parse.Node tn) [~Struct] + + # Init vector of strings + utils.Vector sv + sv.init(8) - /; get_member(~uint8 name) [~Var] - ~Var out = NULL + ~uint8 str + ~parse.Node n + bool seen_id = false - ~Var v - /; loop (int i = 0; i < self.members.count) [i++] - v = self.members.get(i) - /; if (utils.strcmp(v`.name, name) == true) - return v - ;/ - ;/ + /; loop (int i = 0; i < tn`.sub.count) [i++] + n = tn`.sub.get(i) + /; if (n`._type == parse.NTYPE_ID) + str = n`.data + sv.push(~str) + seen_id = true + ;; else if (seen_id == true) + i = tn`.sub.count + ;/ + ;/ - return out - ;/ + # Find struct and compute its size + ~Struct out = self.methods`.find(SEARCH_STRUCT, ~sv) + sv.end() + return out + ;/ - /; end - _delete(self.name) - ~Var v - /; loop (int i = 0; i < self.members.count) [i++] - v = self.members.get(i) - v`.end() - ;/ - self.members.end() - ;/ + /; end + _delete(self.name) + ~Var v + /; loop (int i = 0; i < self.members.count) [i++] + v = self.members.get(i) + v`.end() + ;/ + self.members.end() + ;/ ;/ |