From d84ce6ccd476791d13350be21f0285d694dbf9fe Mon Sep 17 00:00:00 2001
From: Kyle Gunger <kgunger12@gmail.com>
Date: Fri, 17 Feb 2023 03:19:25 -0500
Subject: Support modules

---
 tnslc/test.tnsl  |  16 ++++----
 tnslc/tnslc.tnsl | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 109 insertions(+), 16 deletions(-)

diff --git a/tnslc/test.tnsl b/tnslc/test.tnsl
index c6ffe08..ae039a1 100644
--- a/tnslc/test.tnsl
+++ b/tnslc/test.tnsl
@@ -30,13 +30,15 @@ enum EN_ARR [PTR_TEST] {
 
 uint WAMM = 31, WAM2 = 34
 
-struct A {
-    B nxta
-}
-
-struct B {
-    ~A dat
-}
+/; module Alpha
+    struct A {
+        B nxta
+    }
+
+    struct B {
+        ~A dat
+    }
+;/
 
 /; main [int]
     return EN_ARR.A.dat
diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl
index 7b90db1..5aaab21 100644
--- a/tnslc/tnslc.tnsl
+++ b/tnslc/tnslc.tnsl
@@ -688,6 +688,18 @@
         ;return _find_function(artifact, 0)
     ;/
 
+    /; find_sub ({}uint8 s_mod) [~Module]
+        ;{}uint8 v1 = string_add("_#", s_mod)
+        ;{}uint8 v2 = string_add("__#", s_mod)
+        /; loop (int i = 0; i < len (self.sub)) [i++]
+            /; if (string_equate(self.sub{i}.name, s_mod) || string_equate(self.sub{i}.name, v1) || string_equate(self.sub{i}.name, v2))
+                ;return ~(self.sub{i})
+            ;/
+        ;/
+
+        ;return ~self
+    ;/
+
     /; full_path [{}uint8]
         /; if (string_equate(self.name, ""))
             ;return ""
@@ -1018,18 +1030,19 @@
         ;return "]"
     ;; else if (d.cmp("{"))
         ;return "}"
+    ;; else if (d.cmp("/;"))
+        ;return ";/"
     ;/
-    ;tnsl.io.println(string_add("Error, unrecognized delim: ", d))
+    ;tnsl.io.println(string_add("Error, unrecognized delim: ", d.data))
 ;/
 
 # Finds closing bracket
 /; find_closing (~{}Token tok, ~int cur) [int]
     ;int bl = 0, p = 0, br = 0, c = 0
     ;{}uint8 cl = closing_for(tok`{cur`})
-
     /; loop (int i = cur` + 1; i < len tok`) [i++]
         /; if (bl == 0 && p == 0 && br == 0 && c == 0)
-            /; if ((tok`{i}.cmp(";;") || tok`{i}.cmp(";:")) && string_equate(cl, "/;"))
+            /; if ((tok`{i}.cmp(";;") || tok`{i}.cmp(";:")) && string_equate(cl, ";/"))
                 ;return i
             ;; else if (tok`{i}.cmp(cl))
                 ;return i
@@ -1072,25 +1085,102 @@
 ;/
 
 # TODO:
-/; compile_function (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope) [Function]
+/; compile_function (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope)
 
 ;/
 
 # TODO:
-/; compile_method (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope) [Function]
+/; compile_method (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope)
+
+;/
+
+/; compile_block (~{}Token tok, ~int cur, ~Module current, ~CompData out)
 
 ;/
 
 # First pass on a module
 # Generates structs, enums, and submodules
 /; module_pass_one (~{}Token tok, ~int cur, ~Module current)
+    ;int max = find_closing(tok, cur)
+    ;Module new = {current, false, "", {}, {}, {}, {}}
+    /; loop (cur`++; cur` < len tok`) [cur`++]
+        /; if (tok`{cur`}.type_is(TOKEN.DEFWORD))
+            ;new.name = tok`{cur`}.data
+        ;; else if (tok`{cur`}.cmp("export"))
+            ;new.exp = true
+        ;; else if (!(tok`{cur`}.cmp("module")))
+            ;break
+        ;/
+    ;/
 
+    ;tnsl.io.println("boop")
+    /; loop (cur` < max) [cur`++]
+        ;tnsl.io.print(".")
+        /; if (tok`{cur`}.cmp(":"))
+            ;tnsl.io.println("INCLUDE")
+            /; if (tok`{cur` + 2}.type_is(TOKEN.LITERAL))
+                ;CompData tmp = compile_file_pass_one(f.relative(unquote_str(tok`{cur` + 2}.data)), ~new)
+                ;cur` = cur` + 2
+            ;/
+            ;continue
+        ;; else if (tok`{cur`}.cmp("/;") || tok`{cur`}.cmp(";;"))
+            /; if (tok`{cur` + 1}.cmp("export") || tok`{cur` + 1}.cmp("module"))
+                ;module_pass_one(tok, cur, ~new)
+            ;/
+        ;; else if (tok`{cur`}.cmp("struct"))
+            ;new_type(tok, cur, ~new)
+        ;/
+    ;/
+    ;current`.sub.append(new)
 ;/
 
 # Second pass on a module
 # Generates code and calls compile_file_second_pass if an include happens
-/; module_pass_two (~{}Token tok, ~int cur, ~Module current)
-
+/; module_pass_two (~{}Token tok, ~int cur, ~Module current, ~CompData out)
+    ;int max = find_closing(tok, cur)
+    
+    /; loop (cur`++; cur` < len tok`) [cur`++]
+        /; if (tok`{cur`}.type_is(TOKEN.DEFWORD))
+            ;current = current`.find_sub(tok`{cur`}.data)
+            ;cur`++
+            ;break
+        ;/
+    ;/
+    
+    /; loop (cur` < max) [cur`++]
+        ;tnsl.io.print(".")
+        /; if (tok`{cur`}.cmp(":"))
+            ;tnsl.io.println("INCLUDE")
+            /; if (tok`{cur` + 2}.type_is(TOKEN.LITERAL))
+                ;CompData tmp = compile_file_pass_two(f.relative(unquote_str(tok`{cur` + 2}.data)), current)
+                ;out.hsec = string_add(out.hsec, tmp.hsec)
+                ;out.dsec = string_add(out.dsec, tmp.dsec)
+                ;out.csec = string_add(out.csec, tmp.csec)
+                ;cur` = cur` + 2
+            ;/
+            ;continue
+        ;; else if (tok`{cur`}.cmp("/;") || tok`{cur`}.cmp(";;"))
+            ;tnsl.io.print("block")
+            /; if (tok`{cur` + 1}.cmp("export") || tok`{cur` + 1}.cmp("module"))
+                ;module_pass_two(tok, cur, current, out)
+            ;; else
+                ;compile_block(tok, cur, current, out)
+            ;/
+        ;; else if (tok`{cur`}.cmp("struct"))
+            ;tnsl.io.print("struct")
+            ;skip_struct(tok, cur)
+        ;; else if (tok`{cur`}.cmp("enum"))
+            ;tnsl.io.print("enum")
+            ;compile_enum(tok, cur, current, ~out)
+        ;; else if (is_definition(tok, cur, current))
+            ;tnsl.io.print("def")
+            ;compile_file_def(tok, cur, current, ~out)
+        ;; else if (!(tok`{cur`}.cmp("\n")))
+            ;tnsl.io.println("Failed to recognize file-level statement")
+            ;tok`{cur`}.print()
+            ;break
+        ;/
+    ;/
 ;/
 
 # First compiler pass on a file
@@ -1177,9 +1267,10 @@
         ;; else if (tok{i}.cmp("/;") || tok{i}.cmp(";;"))
             ;tnsl.io.print("block")
             /; if (tok{i + 1}.cmp("export") || tok{i + 1}.cmp("module"))
-                ;module_pass_two(~tok, ~i, current)
+                ;module_pass_two(~tok, ~i, current, ~out)
+            ;; else
+                ;compile_block(~tok, ~i, current, ~out)
             ;/
-            ;compile_function
         ;; else if (tok{i}.cmp("struct"))
             ;tnsl.io.print("struct")
             ;skip_struct(~tok, ~i)
-- 
cgit v1.2.3