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.tnsl174
1 files changed, 145 insertions, 29 deletions
diff --git a/tnslc/compile/struct.tnsl b/tnslc/compile/struct.tnsl
index d175aef..79d3267 100644
--- a/tnslc/compile/struct.tnsl
+++ b/tnslc/compile/struct.tnsl
@@ -3,44 +3,160 @@ struct Struct {
~uint8 name,
~Module methods,
utils.Vector members,
- int size
+ int size,
+
+ ~parse.Node _up
}
+~uint8 PRIMITIVE_1 = "bool,uint8,int8"
+~uint8 PRIMITIVE_2 = "uint16,int16"
+~uint8 PRIMITIVE_4 = "uint32,int32,float32"
+~uint8 PRIMITIVE_8 = "uint64,int64,float64,int,uint,float,void"
+
+/; 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 prim type
+ /; if (parse._in_csv(PRIMITIVE_1, n`.data) == true)
+ return 1
+ ;; else if (parse._in_csv(PRIMITIVE_2, n`.data) == true)
+ return 2
+ ;; else if (parse._in_csv(PRIMITIVE_4, n`.data) == true)
+ return 4
+ ;; else if (parse._in_csv(PRIMITIVE_8, n`.data) == true)
+ return 8
+ ;/
+
+ # Check for ref
+ n = tn`.sub.get(tn`.sub.count - 1)
+ /; if (n`._type == parse.NTYPE_POST_OP)
+ return 8
+ ;/
+
+ return 0
+;/
+
/; 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)
+ ;/
+
+ /; add_member(~Var v)
+ 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 (~Module parent)
+ /; if (self.size !== 0)
+ return
+ ;/
+
+ self.size = self.size - 1
- /; add_member(~Var v)
- self.members.push(v)
- ;/
+ int total = 0
+ ~parse.Node up = self._dlist()
+ ~parse.Node n
+ int add_size = 0
+ /; loop (int i = 0; i < up`.sub.count) [i++]
+ n = up`.sub.get(i)
+
+ /; if (n`._type == parse.NTYPE_TYPE)
+ # Check for primitive type
+ add_size = is_primitive(n)
+ /; if (add_size == 0)
+ # Find type, compute size, set add_size to type size
+ ~Struct ft = self._find_type(parent, n)
+ /; if (ft`.size < 0)
+ # Cyclical dependency
+ return
+ ;/
+ add_size = ft`.size
+ ;/
+ ;; else if (n`._type == parse.NTYPE_ID)
+ total = total + add_size
+ ;/
+ ;/
- /; get_member(~uint8 name) [~Var]
- ~Var out = NULL
+ self.size = total
+ ;/
- ~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
- ;/
- ;/
+ /; _find_type (~Module parent, ~parse.Node tn) [~Struct]
+ # First loop through all the names and create a vector of strings
+ utils.Vector sv
+ sv.init(8)
+ ~void str
+ ~parse.Node n
+ /; 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)
+ ;; else
+ i = tn`.sub.count
+ ;/
+ ;/
- return out
- ;/
+ # Find struct and compute its size
+ ~Struct out = parent.find(SEARCH_STRUCT, ~sv)
+ sv.pop()
+ ~Module outp = parent
+ /; if (sv.count !== 0)
+ outp = parent.find(SEARCH_SUB, ~sv)
+ ;/
+ sv.end()
+ out._compute_size(outp)
+ 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()
+ ;/
;/