diff options
| author | Kai Gunger <kgunger12@gmail.com> | 2026-01-01 23:23:12 -0500 |
|---|---|---|
| committer | Kai Gunger <kgunger12@gmail.com> | 2026-01-01 23:23:12 -0500 |
| commit | 4289c90cc90a9798091a741c3e18861b47836402 (patch) | |
| tree | a390a28f251c19648d7b7a44ae22d554181e8a98 /tnslc | |
| parent | 8682fb7aad90f053375937fe391a65e7e269e2c1 (diff) | |
poor implementation of tmp vars + returns i guess
Diffstat (limited to 'tnslc')
| -rw-r--r-- | tnslc/compile/function.tnsl | 87 | ||||
| -rw-r--r-- | tnslc/compile/scope.tnsl | 21 |
2 files changed, 107 insertions, 1 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl index c9ab985..bd3438e 100644 --- a/tnslc/compile/function.tnsl +++ b/tnslc/compile/function.tnsl @@ -237,7 +237,94 @@ struct Function { ;/ ;/ + /; _check_return (~parse.Node n) [bool] + int expected = self.outputs.count + int have = 0 + + ~parse.Node val + /; if (n`.sub.count > 0) + val = n`.sub.get(0) + val = val`.sub.get(0) + /; if (expected > 1 && val`._type == parse.NTYPE_VLIST) + have = val`.sub.count + ;; else + have = 1 + ;/ + ;/ + + /; if (have == expected) + return true + ;/ + + _print_num("ERROR: Number of return values (%d) does not match expected (\0", have) + _print_num("%d)\n\0", expected) + _printf("ERROR: A list of return values should be enclosed by {}\n\0") + + return false + ;/ + + /; _compile_return_vals (~Scope s, ~parse.Node n) + _printf("Compiling return vals!\n\0") + /; if (self.outputs.count == 0) + return + ;/ + + /; if (self.outputs.count > 1) + n = n`.sub.get(0) + n = n`.sub.get(0) + ;/ + + ~Var out + Var tmp, cmp + utils.Vector tmps + tmps.init(len cmp) + + s`.cb`.add_c("\n ; STARTING RETURN\n\0") + + # Compile all values + ~parse.Node val_node + /; loop (int i = 0; i < self.outputs.count) [i++] + val_node = n`.sub.get(i) + out = self.outputs.get(i) + + tmp = s`.mk_tmp(out) + cmp = self._compile_value(s, val_node, out) + tmp.set(s, ~cmp) + cmp.end() + tmps.push(~tmp) + ;/ + + # Set all outputs + ~Var tt + /; loop (int i = 0; i < self.outputs.count) [i++] + out = self.outputs.get(i) + tt = tmps.get(i) + out`.set(s`.cb, tmp) + tt`.end() + ;/ + + s`.free_tmp(tmps.count, false) + tmps.end() + ;/ + /; _return (~Scope s, ~parse.Node n) + /; if (self._check_return(n) !== true) + return + ;/ + + # Compute all return values and set the output variables properly + self._compile_return_vals(s, n) + + # Find root scope of function + /; loop (s`.parent !== NULL) + s = s`.parent + ;/ + + # Generate jump instruction + ~uint8 lab = s`.end_label() + s`.cb`.add_c(" jmp \0") + s`.cb`.add_c(lab) + s`.cb`.add_c("\n\0") ;/ # Should handle break, continue, and return diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl index 62bbf68..b199abe 100644 --- a/tnslc/compile/scope.tnsl +++ b/tnslc/compile/scope.tnsl @@ -5,7 +5,7 @@ struct Scope { ~Scope parent, - utils.Vector vars, + utils.Vector vars, tmps, int unique } @@ -47,6 +47,7 @@ struct Scope { Var v self.vars.init(len v) + self.tmps.init(len v) ;/ /; end @@ -58,6 +59,12 @@ struct Scope { v`.end() ;/ self.vars.end() + + /; loop (int i = 0; i < self.tmps.count) [i++] + v = self.tmps.get(i) + v`.end() + ;/ + self.tmps.end() ;/ # @@ -236,6 +243,18 @@ struct Scope { return v ;/ + # Make a temp variable in register or stack for use in computations + /; mk_tmp (~Var base) [Var] + Var v = base`.copy() + return v + ;/ + + # Free n tmp variables (starts from most recently created) + # If you want to generate code to set the stack pointer then + # set code to true + /; free_tmp (int tmps, bool code) + ;/ + # # Sub scope # |