diff options
| author | Kai Gunger <kgunger12@gmail.com> | 2026-03-20 17:22:32 -0400 |
|---|---|---|
| committer | Kai Gunger <kgunger12@gmail.com> | 2026-03-20 17:22:32 -0400 |
| commit | 34a791931c82d0fc0b0be954b7498e474086c5a9 (patch) | |
| tree | 83f0a86972dccb4e4bb2e7ea8836ec701ff29a8d /tnslc | |
| parent | 6fcd9b168c2667c3e757bce7f68377954917224a (diff) | |
[tnslc] fix bug in scope for getting stack locationsorigin
Diffstat (limited to 'tnslc')
| -rw-r--r-- | tnslc/compile/function.tnsl | 2 | ||||
| -rw-r--r-- | tnslc/compile/scope.tnsl | 84 | ||||
| -rw-r--r-- | tnslc/compile/var.tnsl | 75 | ||||
| -rw-r--r-- | tnslc/test.tnsl | 10 |
4 files changed, 134 insertions, 37 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl index 6f7fceb..a57aa76 100644 --- a/tnslc/compile/function.tnsl +++ b/tnslc/compile/function.tnsl @@ -140,6 +140,8 @@ struct Function { ;/ # Write label and opening + # Nieve implementation: r10-r15 are callee saved registers + # in the TNSL style ABI out.place_base_label() cb`.add_c(" push rbp\n\0") cb`.add_c(" lea rbp, [rsp + 8]\n\0") diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl index d3f86a9..e3348dd 100644 --- a/tnslc/compile/scope.tnsl +++ b/tnslc/compile/scope.tnsl @@ -6,7 +6,8 @@ struct Scope { ~Scope parent, utils.Vector vars, tmps, - + + # Used for generating unique sub-scope labels int unique } @@ -109,7 +110,7 @@ struct Scope { ~Var v /; loop (int i = 0; i < self.tmps.count) [i++] - v = self.vars.get(i) + v = self.tmps.get(i) /; if (v`.loc > 1) out++ /; if (out > 4) @@ -158,7 +159,6 @@ struct Scope { Var mk = v`.copy() mk.offset = 0 - # TODO: Make sure this works properly /; if (mk.loc > 0) mk.loc = 1 ;/ @@ -175,7 +175,7 @@ struct Scope { tp = sub ;; else if (sub`._type == parse.NTYPE_ID) /; if (tp == NULL) - _printf("COMPILER ERROR: Should have type node before first id in decl node\n\0") + _printf("COMPILER ERROR: Should have type node before first id in decl/dlist node\n\0") return ;/ @@ -184,11 +184,12 @@ struct Scope { v.init(tp, sub) v._resolve_type(self.mod) - # TODO: Make sure this works properly + # Compute weather we can put it in a register /; if (v.regable() == true) v.loc = 1 ;; else - v.loc = 0 - 1 + v.loc = 0 + v.loc = v.loc - 1 ;/ v.offset = 0 @@ -198,14 +199,47 @@ struct Scope { /; if (sub`.sub.count > 0) sub = sub`.sub.get(0) /; if (sub`._type == parse.NTYPE_VALUE) - self.precheck_stmt(n) + self.precheck_stmt(sub) ;/ ;/ ;/ ;/ ;/ + /; try_move (~parse.Node n) + /; loop (n`._type == parse.NTYPE_PRE_OP) + /; if (n`.sub.count < 1) + return + ;/ + n = n`.sub.get(0) + ;/ + + /; if (n`._type == parse.NTYPE_ID) + ~Var to_move = self._find_var(n`.data) + /; if (to_move == NULL) + return + ;/ + + /; if (to_move`.loc > 0) + int negative = 0 + to_move`.loc = negative - 1 + ;/ + ;/ + ;/ + /; precheck_stmt (~parse.Node n) + /; if (n`._type == parse.NTYPE_PRE_OP) + /; if (utils.strcmp(n`.data, "~\0") == true) + self.try_move(n) + return + ;/ + ;/ + + ~parse.Node sub + /; loop (int i = 0; i < n`.sub.count) [i++] + sub = n`.sub.get(i) + self.precheck_stmt(sub) + ;/ ;/ /; _find_var (~uint8 name) [~Var] @@ -260,6 +294,17 @@ struct Scope { ;/ ;/ + /; if (v`.loc < 0) + int stk = v`.actual_size() + ~uint8 stk_str = utils.int_to_str(stk) + self.cb`.add_c(" sub rsp, \0") + self.cb`.add_c(stk_str) + self.cb`.add_c(" ; Create stack space for local variable \0") + self.cb`.add_c(v`.name) + self.cb`.add_c("\n\0") + _delete(stk_str) + ;/ + return v ;/ @@ -270,24 +315,12 @@ struct Scope { return NULL ;/ - ~int32 p = v`.top_ptrc() - /; if (p == NULL) - v`.set(self.cb, src) - ;; else if (p` == 0) + /; if (v`.is_ref() == true) v`.set_ref(self.cb, src) ;; else v`.set(self.cb, src) ;/ - /; if (v`.loc < 0) - int stk = v`.actual_size() - ~uint8 stk_str = utils.int_to_str(stk) - self.cb`.add_c(" sub rsp, \0") - self.cb`.add_c(stk_str) - self.cb`.add_c("\n\0") - _delete(stk_str) - ;/ - return v ;/ @@ -316,7 +349,7 @@ struct Scope { ~uint8 stk_str = utils.int_to_str(stk) self.cb`.add_c(" sub rsp, \0") self.cb`.add_c(stk_str) - self.cb`.add_c("\n\0") + self.cb`.add_c(" ; Create stack space for tmp variable\n\0") _delete(stk_str) ;/ @@ -349,7 +382,7 @@ struct Scope { ~uint8 stk_mv_str = utils.int_to_str(stk_mv) self.cb`.add_c(" add rsp, \0") self.cb`.add_c(stk_mv_str) - self.cb`.add_c("\n\0") + self.cb`.add_c(" ; Free stack space (freeing tmp variables)\n\0") _delete(stk_mv_str) ;/ ;/ @@ -378,7 +411,7 @@ struct Scope { true_name.push_char('#') true_name.push_cstr(name) _delete(u) - + Scope out = self.mk_sub(true_name.as_cstr()) true_name.end() @@ -389,14 +422,13 @@ struct Scope { ;/ # Get closest breakable scope - /; _closest_break [~Scope] /; if (utils.ends_with(self.name, "#wrap\0")) return ~self ;; else if (utils.ends_with(self.name, "#loop\0")) return ~self ;/ - + /; if (self.parent == NULL) return NULL ;/ @@ -438,7 +470,7 @@ struct Scope { # Label generation # - + /; _base_label [utils.Vector] utils.Vector out out.init(1) diff --git a/tnslc/compile/var.tnsl b/tnslc/compile/var.tnsl index e5608bb..b684c33 100644 --- a/tnslc/compile/var.tnsl +++ b/tnslc/compile/var.tnsl @@ -134,6 +134,15 @@ struct Var { return out ;/ + /; is_ref [bool] + ~int32 p = self.top_ptrc() + /; if (p == NULL) + return false + ;/ + + return p` == 0 + ;/ + /; _print (int idt) _indent(idt) _printf("{ Var : \0") @@ -410,11 +419,24 @@ struct Var { # Set this Variable to the value of other /; set (~CompBuf buf, ~Var other) - self.standard_op(buf, other, "mov\0") + # Options: + # - If builtin then move based on size (byte, word, dword, qword) + # - If pointer then move qword + # - If struct then move via rep movsb + + # Changes need to be made based on whether either is on the stack + # or if either is a reference + + # Can move to/from stack if only one is on stack/reference + # otherwise we must pre-mov the source into RSI and then + # we can move into the recipiant's address + + /; if () + ;/ ;/ # Set the address which this reference points to - /; set_ref(~CompBuf buf, ~Var other) + /; set_ref (~CompBuf buf, ~Var other) ;/ # Generate a variable which can actually be used for operations @@ -474,6 +496,28 @@ struct Var { /; product_op (~CompBuf buf, ~Var other, ~uint8 op_str, int read_reg) + Var cpy = self.copy() + cpy.loc = 1 + cpy.offset = 0 + + # Set RAX register for product operation + cpy.set(buf, ~self) + + ~uint8 from_str = other`.gen_loc() + + buf`.add_c(" \0") + buf`.add_c(op_str) + buf`.add_c(" \0") + buf`.add_c(from_str) + buf`.add_c("\n\0") + + _delete(from_str) + + # Set back the var from the read_reg + cpy.loc = read_reg + self.set(buf, cpy) + + cpy.end() ;/ /; add (~CompBuf buf, ~Var other) @@ -497,7 +541,12 @@ struct Var { self.offset = self.offset * other`.offset return ;/ - self.product_op(buf, other, "imul", 1) + + /; if (self.name{0} == 'u') + self.product_op(buf, other, "mul", 1) + ;; else + self.product_op(buf, other, "imul", 1) + ;/ ;/ /; div (~CompBuf buf, ~Var other) @@ -506,10 +555,10 @@ struct Var { return ;/ - /; if ("signed") - self.product_op(buf, other, "idiv", 1) - ;; else + /; if (self.name{0} == 'u') self.product_op(buf, other, "div", 1) + ;; else + self.product_op(buf, other, "idiv", 1) ;/ ;/ @@ -519,10 +568,10 @@ struct Var { return ;/ - /; if ("signed") - self.product_op(buf, other, "idiv", 4) - ;; else + /; if (self.name{0} == 'u') self.product_op(buf, other, "div", 4) + ;; else + self.product_op(buf, other, "idiv", 4) ;/ ;/ @@ -538,6 +587,14 @@ struct Var { self.standard_op(buf, other, "xor") ;/ + /; not (~CompBuf buf) + ~uint8 to_str = self.gen_loc() + buf`.add_c(" not \0") + buf`.add_c(to_str) + buf`.add_c("\n\0") + _delete(to_str) + ;/ + /; member (~CompBuf buf, ~uint8 name) [Var] Var out return out diff --git a/tnslc/test.tnsl b/tnslc/test.tnsl index bedadcb..ddc10d1 100644 --- a/tnslc/test.tnsl +++ b/tnslc/test.tnsl @@ -1,5 +1,11 @@ -/; main [int] - return 0 +/; main (int argc, ~~uint8 argv) [int] + int i = 0 + /; if (len args > 1) + i = len args + ;; else + i = ~args + ;/ + return i ;/ |