summaryrefslogtreecommitdiff
path: root/tnslc/compile/struct.tnsl
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc/compile/struct.tnsl')
-rw-r--r--tnslc/compile/struct.tnsl263
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()
+ ;/
;/