summaryrefslogtreecommitdiff
path: root/tnslc
diff options
context:
space:
mode:
authorKai Gunger <kgunger12@gmail.com>2026-01-01 23:23:12 -0500
committerKai Gunger <kgunger12@gmail.com>2026-01-01 23:23:12 -0500
commit4289c90cc90a9798091a741c3e18861b47836402 (patch)
treea390a28f251c19648d7b7a44ae22d554181e8a98 /tnslc
parent8682fb7aad90f053375937fe391a65e7e269e2c1 (diff)
poor implementation of tmp vars + returns i guess
Diffstat (limited to 'tnslc')
-rw-r--r--tnslc/compile/function.tnsl87
-rw-r--r--tnslc/compile/scope.tnsl21
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
#