summaryrefslogtreecommitdiff
path: root/tnslc/compile
diff options
context:
space:
mode:
authorKai Gunger <kgunger12@gmail.com>2025-12-30 23:16:01 -0500
committerKai Gunger <kgunger12@gmail.com>2025-12-30 23:16:01 -0500
commitaef2a1e4fae812220b29ec939be239cee5225b1a (patch)
tree7464ef01fb4957b8a4e726ea2072ce57ec677077 /tnslc/compile
parent3a98cbd4d96041e78cb8748d674e9d5ea311054e (diff)
finding parent scopes
Diffstat (limited to 'tnslc/compile')
-rw-r--r--tnslc/compile/function.tnsl26
-rw-r--r--tnslc/compile/scope.tnsl45
2 files changed, 71 insertions, 0 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl
index 5db1bd3..1f0fb3f 100644
--- a/tnslc/compile/function.tnsl
+++ b/tnslc/compile/function.tnsl
@@ -240,7 +240,33 @@ struct Function {
/; if (utils.strcmp(n`.data, "return\0") == true)
# Compute value and return
self._compile_value(s, n)
+ ;; else if (utils.strcmp(n`.data, "continue\0") == true)
+ ~Scope lp = s`.closest_loop()
+ /; if (lp == NULL)
+ return
+ ;/
+
+ ~uint8 lab = lp`.rep_label()
+ s`.cb`.add_c(" jmp \0")
+ s`.cb`.add_c(lab)
+ s`.cb`.add_c("\n\0")
+ ;; else if (utils.strcmp(n`.data, "break\0") == true)
+ ~Scope br = s`.closest_break()
+ /; if (br == NULL)
+ return
+ ;/
+
+ ~uint8 lab = br`.rep_label()
+ s`.cb`.add_c(" jmp \0")
+ s`.cb`.add_c(lab)
+ s`.cb`.add_c("\n\0")
;/
+
+ _printf("COMPILER ERROR: The following was detected as flow control, but we do not handle it: '\0")
+ _printf(n`.data)
+ _printf("'\n\0")
+ _printf("COMPILER ERROR: this is likely a bug with the compiler, please report it along with the\n\0")
+ _printf("COMPILER ERROR: code snippit which caused the bug!\n\0")
;/
# Should handle computing a value, delegate to other funcs when needed
diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl
index 900d626..b7df075 100644
--- a/tnslc/compile/scope.tnsl
+++ b/tnslc/compile/scope.tnsl
@@ -241,6 +241,51 @@ struct Scope {
return out
;/
+ # 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
+ ;/
+
+ return self.parent`.closest_loop()
+ ;/
+
+ /; closest_break [~Scope]
+ /; if (self.parent == NULL)
+ return NULL
+ ;/
+
+ ~uint8 pname = self.parent`.name
+ /; if (utils.ends_with(pname, "#wrap\0"))
+ ~Scope par2 = self.parent`.parent
+ /; if (par2 !== NULL)
+ return par2`._closest_break()
+ ;/
+ ;/
+
+ return self._closest_break()
+ ;/
+
+ # Get closest loop
+ /; closest_loop [~Scope]
+ /; if (utils.ends_with(self.name, "#loop\0"))
+ return ~self
+ ;/
+
+ /; if (self.parent == NULL)
+ return NULL
+ ;/
+
+ return self.parent`.closest_loop()
+ ;/
+
#
# Label generation