diff options
| -rw-r--r-- | tnslc/compile/function.tnsl | 55 | ||||
| -rw-r--r-- | tnslc/compile/scope.tnsl | 1 | ||||
| -rw-r--r-- | tnslc/compile/struct.tnsl | 5 | ||||
| -rw-r--r-- | tnslc/compile/var.tnsl | 170 | ||||
| -rw-r--r-- | tnslc/test.tnsl | 8 |
5 files changed, 216 insertions, 23 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl index 481b1b6..a8517cb 100644 --- a/tnslc/compile/function.tnsl +++ b/tnslc/compile/function.tnsl @@ -440,6 +440,45 @@ struct Function { return found ;/ + /; _compile_set (~Scope s, ~parse.Node n, ~Var type_hint) [Var] + # TODO + Var out + return out + ;/ + + /; _compile_bin (~Scope s, ~parse.Node n, ~Var type_hint) [Var] + # TODO + Var out + return out + ;/ + + /; _compile_pre (~Scope s, ~parse.Node n, ~Var type_hint) [Var] + Var out + + /; if (utils.strcmp(n`.data, "-\0") == true) + ~parse.Node sub = n`.sub.get(0) + out = self._compile_value(s, sub, type_hint) + out.neg(s`.cb) + ;; else if (utils.strcmp(n`.data, "!\0") == true) + _printf("! not impl\n\0") + ;; else if (utils.strcmp(n`.data, "~\0") == true) + _printf("~ not impl\n\0") + ;; else if (utils.strcmp(n`.data, "--\0") == true) + _printf("-- not impl\n\0") + ;; else if (utils.strcmp(n`.data, "++\0") == true) + _printf("++ not impl\n\0") + ;; else if (utils.strcmp(n`.data, "len\0") == true) + _printf("len not impl\n\0") + ;; else + _printf("COMPILER ERROR: \"\0") + _printf(n`.data) + _printf("\" NOT RECOGNIZED AS A VALID PREOP\n\0") + out = type_hint`.copy() + ;/ + + return out + ;/ + # Should handle computing a value, delegate to other funcs when needed /; _compile_value (~Scope s, ~parse.Node n, ~Var type_hint) [Var] /; if (n`._type == parse.NTYPE_VALUE) @@ -456,12 +495,28 @@ struct Function { out.offset = self._compile_literal(n) return out ;/ + + _printf("Could not compile literal \"\0") + _printf(n`.data) + _printf("\" in scope \0") + ~uint8 bl = s`.base_label() + _printf(bl) + _delete(bl) + _printf(" since the type was struct \"\0") + _printf(type_hint`._type`.name) + _printf("\"\n\0") ;; else if (n`._type == parse.NTYPE_ID) ~Var o = self._compile_base_id(s, n) /; if (o !== NULL) return o`.copy() ;/ + + ;; else if (n`._type == parse.NTYPE_PRE_OP) + return self._compile_pre(s, n, type_hint) + + ;; else if (n`._type == parse.NTYPE_BIN_OP) + return self._compile_bin(s, n, type_hint) ;/ Var out = type_hint`.copy() diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl index e94fc8d..6faf596 100644 --- a/tnslc/compile/scope.tnsl +++ b/tnslc/compile/scope.tnsl @@ -338,6 +338,7 @@ struct Scope { /; if (v`.is_ref() == true) int rc = v`.max_ref() + rc = rc - 1 v`.set_ref(self.cb, src, rc) ;; else v`.set(self.cb, src) diff --git a/tnslc/compile/struct.tnsl b/tnslc/compile/struct.tnsl index 5eded31..ed0b76a 100644 --- a/tnslc/compile/struct.tnsl +++ b/tnslc/compile/struct.tnsl @@ -136,10 +136,11 @@ struct Struct { _printf("}\n\0") ;/ - /; add_member(~parse.Node tn, ~parse.Node id) + /; add_member(~parse.Node tn, ~parse.Node id, int offset) Var v v.init(tn, id) v._resolve_type(self.methods) + v.offset = offset self.members.push(~v) ;/ @@ -198,7 +199,7 @@ struct Struct { _printf("\n\0") return ;/ - self.add_member(tn, n) + self.add_member(tn, n, total) total = total + add_size ;/ ;/ diff --git a/tnslc/compile/var.tnsl b/tnslc/compile/var.tnsl index e323e8d..85b5d22 100644 --- a/tnslc/compile/var.tnsl +++ b/tnslc/compile/var.tnsl @@ -183,31 +183,35 @@ struct Var { return out ;/ - # Returns true if the variable is a reference - /; is_ref [bool] - ~int32 p = self.top_ptrc() - /; if (p == NULL) + /; is_ptrc (int idx, int32 ptype) [bool] + /; if (idx !< self.ptrc.count) return false ;/ + + idx = self.ptrc.count - idx + idx = idx - 1 + ~int32 chk = self.ptrc.get(idx) + return chk` == ptype + ;/ - return p` == 0 + # Returns true if the variable is a reference + /; is_ref [bool] + return self.is_ptrc(0, 0) ;/ # Returns true if two or more ref layers /; double_ref [bool] - /; if (self.ptrc.count < 2) + /; if (self.is_ref() == false) return false ;/ - ~int32 p = self.ptrc.get(1) - return p` == 0 + return self.is_ptrc(1, 0) ;/ # Ref level /; max_ref [int] int out = 0 /; loop (int i = 0; i < self.ptrc.count) - ~int32 p = self.ptrc.get(i) - /; if (p` == 0) + /; if (self.is_ptrc(i, 0) == true) out++ ;; else i = self.ptrc.count @@ -566,6 +570,24 @@ struct Var { /; if (self.loc > 0) /; if (self.in_mem() == true) out = reg_string(self.loc, 8) + /; if (self.offset !== 0) + utils.Vector vout + vout.from_cstr(out) + + int off = self.offset + /; if (off < 0) + off = 0 - off + vout.push_cstr(" - \0") + ;; else if (off > 0) + vout.push_cstr(" + \0") + ;/ + + _delete(out) + out = utils.int_to_str(off) + vout.push_cstr(out) + _delete(out) + out = vout.as_cstr() + ;/ ;; else uint sz = self.type_size() out = reg_string(self.loc, sz) @@ -619,11 +641,10 @@ struct Var { # Loop and make sure we are dereferencing properly /; loop (int i = 1; i < self.ptrc.count) [i++] - ~int pc = self.ptrc.get(i) - /; if (pc` !== 0) - i = self.ptrc.count - ;; else + /; if (self.is_ptrc(i, 0) == true) buf`.add_c(" mov rdi, [rdi] ; auto deref\n\0") + ;; else + i = self.ptrc.count ;/ ;/ @@ -741,22 +762,78 @@ struct Var { # count how many refs int max_depth = self.max_ref() - /; if (max_depth < depth) - _print_num("Unable to set reference, depth %d exceeds max_depth \0", depth) + /; if (depth !< max_depth) + _print_num("ERROR: Unable to set reference, depth %d equals or exceeds max_depth \0", depth) _print_num("%d\n\0", max_depth) + _printf(" When taking ref of variable \"\0") + _printf(other`.name) + _printf("\" into variable \"\0") + _printf(self.name) + _printf("\"\n\0") return ;/ int32 set = 0 set = set - 1 + max_depth = copy.ptrc.count - max_depth + Var copy = self.copy() - ~int32 ptr = copy.ptrc.get(max_depth - depth) + ~int32 ptr = copy.ptrc.get(max_depth + depth) ptr` = set copy.set(buf, other) copy.end() ;/ + # Copy the pointer to this variable into the output reg (or not if not needed) + /; take_ptr (~CompBuf buf, int reg) [Var] + Var vcpy = self.copy() + /; if (self.in_mem() == false) + _printf("COMPILER ERROR: UNABLE TO GET REFERENCE OF VAR \"\0") + _printf(self.name) + _printf("\" PLEASE REPORT THIS BUG!\n\0") + return vcpy + ;/ + + int32 set = 0 + set = set - 1 + /; if (vcpy.is_ref() == true) + # If we are a ref, we want to set the first one and that's it + int idx = 0 + /; loop (int i = 0; i < vcpy.ptrc.count) [i++] + /; if (vcpy.is_ptrc(i, 0) == false) + i = vcpy.ptrc.count + ;; else + set++ + ;/ + ;/ + + idx = vcpy.ptrc.count - idx + ~int32 p = vcpy.ptrc.get(idx) + p` = set + ;; else + /; if (self.is_struct() == true) + self._set_struct_r(buf, reg) + ;; else + ~uint8 source = self._set_prim_l(buf) + ~uint8 rstr = reg_string(reg, 8) + buf`.add_c(" lea \0") + buf`.add_c(rstr) + buf`.add_c(", \0") + buf`.add_c(source) + buf`.add_c("\n\0") + _delete(source) + _delete(rstr) + ;/ + + vcpy.loc = reg + vcpy.offset = 0 + vcpy.ptr_push(set) + ;/ + + return vcpy + ;/ + ####################### # Standard operations # ####################### @@ -989,12 +1066,67 @@ struct Var { _delete(to_str) ;/ + /; neg (~CompBuf buf) + /; if (self.loc == VLOC_LITL) + int off = 0 + self.offset = off - self.offset + return + ;/ + + ~uint8 to_str = self._set_prim_l(buf) + buf`.add_c(" neg \0") + /; if (self.in_mem() == true) + uint sz = self.type_size() + /; if (sz == 1) + buf`.add_c("byte \0") + ;; else if (sz == 2) + buf`.add_c("word \0") + ;; else if (sz == 4) + buf`.add_c("dword \0") + ;; else if (sz == 8) + buf`.add_c("qword \0") + ;/ + ;/ + buf`.add_c(to_str) + buf`.add_c("\n\0") + _delete(to_str) + ;/ + /; member (~CompBuf buf, ~uint8 name) [Var] - Var out + /; if (self.is_struct() == false) + _printf("ERROR: Attempted to get a member named \"\0") + _printf(name) + _printf("\" from a primitive type \"\0") + _printf(self._type`.name) + _printf("\"\n\0") + _printf(" (If the previous type was in fact a structure then the variable was probably a pointer)\n\0") + return self.copy() + ;/ + + ~Var mbr = self`._type`.get_member(name) + + /; if (mbr == NULL) + _printf("ERROR: member \"\0") + _printf(name) + _printf("\" not found in struct \"\0") + _printf(self._type`.name) + _printf("\n\0") + return self.copy() + ;/ + + Var out = mbr`.copy() + + /; if (self.is_ref() == true) + self._set_struct_r(buf, 5) + out.loc = 5 + ;; else + out.loc = self.loc + out.offset = out.offset + self.offset + ;/ + return out ;/ - # Printing /; _print (int idt) diff --git a/tnslc/test.tnsl b/tnslc/test.tnsl index 5688724..7bf76ce 100644 --- a/tnslc/test.tnsl +++ b/tnslc/test.tnsl @@ -1,5 +1,9 @@ -/; pass_a (int a) [int] - return a +/; five [int] + return 5 +;/ + +/; main (int argc, ~~uint8 argv) [int] + return five() ;/ |