From 72fa7d598bfe67e9a12c695648243f031f5e1aaf Mon Sep 17 00:00:00 2001
From: Kyle Gunger <kgunger12@gmail.com>
Date: Fri, 24 Mar 2023 19:10:30 -0400
Subject: Parse input parameters

---
 tnslc/simple.tnsl | 27 +++++++++++++----------
 tnslc/tnslc.tnsl  | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/tnslc/simple.tnsl b/tnslc/simple.tnsl
index b140c7a..d871e92 100644
--- a/tnslc/simple.tnsl
+++ b/tnslc/simple.tnsl
@@ -1,15 +1,18 @@
 
 {}uint8 str1 = "abcd"
-{}uint8 str2 = "abce"
-
-/; main [int]
-    /; loop (int i = 0; i < 4) [i++]
-        /; if (str1{i} !== str2{i})
-            /; if (str2{i} == 'e')
-                return 3
-            ;/
-            return 1
-        ;/
-    ;/
-    return 0
+{}uint8 str2 = "abcd"
+
+/; call_me [int]
+    return 4
+;/
+
+/; main (int argc, ~~uint argv) [int]
+    # On windows, the first two arguments are passed in RCX and RDX, so we need to
+    # update their positions here or else tnsl willhave garbage values in r8 and r9
+    asm "mov r8, rcx"
+    asm "mov r9, rdx"
+    # If on linux, you would use rdi and rsi instead of rcx and rdx, respectively
+
+    # return the number of arguments
+    return argc
 ;/
diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl
index df2eb54..9eee55a 100644
--- a/tnslc/tnslc.tnsl
+++ b/tnslc/tnslc.tnsl
@@ -1504,6 +1504,10 @@
                 ;out = out + self.vars{i}.norm_size()
             ;/
         ;/
+        
+        /; if (!(self.is_cf()) && !(self.r))
+            ;return out + 80
+        ;/
 
         ;return out
     ;/
@@ -1521,6 +1525,65 @@
             ;{}uint8 intro = "\tpush rbp\n\tlea rbp, [rsp + 8]\n\tpush r8\n\tpush r9\n\tpush r10\n\tpush r11\n\tpush r12\n\tpush r13\n\tpush r14\n\tpush r15\n"
             ;out`.csec = string_add(out`.csec, intro)
         ;/
+
+        # pre-stack loop
+        /; loop (int i = 0; i < len (self.vars)) [i++]
+            ;int loc = self.next_loc(self.vars{i}.data_type)
+            /; if (loc !< 0)
+                ;self.vars{i}.location = loc
+                ;self.vars{i}.loc_type = LOCATION.REGISTER
+                ;out`.csec = string_join( {
+                    out`.csec,
+                    "\tmov ", get_reg(loc, 8), ", ", get_reg(loc - 8, 8), "\n"
+                }, "")
+            ;/
+        ;/
+
+        ;int accum = 0
+        /; if (!(self.r))
+            ;accum = 80
+        ;/
+
+        ;{}uint8 moves = string_join( {
+            "lea rsi, [rbp]\n"
+        }, "")
+        
+        # Move extra variables
+        /; loop (int i = len (self.vars) - 1; i !< 0) [i = i - 1]
+            /; if (self.vars{i}.loc_type == LOCATION.LITERAL)
+                ;self.vars{i}.loc_type = LOCATION.STACK
+                ;int sz = self.vars{i}.norm_size()
+                ;accum = accum + sz
+                ;self.vars{i}.location = accum
+                /; if (len (self.vars{i}.data_type.ptr_chain) > 0)
+                    ;moves.csec = string_join( {
+                        moves.csec,
+                        "\tmov rdi, qword [rsi]\n",
+                        "\tmov qword [rbp - ", int_to_string(accum), "], rdi\n",
+                        "\tadd rsi, 8\n"
+                    }, "")
+                ;; else if (self.vars{i}.is_prim())
+                    ;moves.csec = string_join( {
+                        moves.csec,
+                        "\tmov ", get_reg(5, sz), ", ", mov_by_size(sz), "[rsi]\n",
+                        "\tmov ", mov_by_size(sz), "[rbp - ", int_to_string(accum), "], ", get_reg(5, sz),"\n",
+                        "\tadd rsi, ", int_to_string(sz), "\n"
+                    }, "")
+                ;; else
+                    ;moves.csec = string_join( {
+                        moves.csec,
+                        "\tlea rdi, [rbp - ", int_to_string(accum), "]\n",
+                        "\tmov rcx", int_to_string(sz), "\n",
+                        "\tmovsb\n",
+                        "\tadd rsi, ", int_to_string(sz), "\n"
+                    }, "")
+                ;/
+            ;/
+        ;/
+        
+        /; if (accum > 80 && !(self.r))
+            ;out`.csec = string_add(out`.csec, moves)
+        ;/
     ;/
     
     /; end_scope (~CompData out)
@@ -2000,7 +2063,7 @@
     /; loop (cur` = next_non_nl(tok, cur` + 1); cur` < max) [cur` = next_non_nl(tok, cur` + 1)]
         ;int nnl = next_non_nl(tok, cur` + 1)
         /; if (tok`{nnl}.cmp(",") || nnl == max)
-            ;out.append({tok`{cur`}.data, t, 0, 0})
+            ;out.append({tok`{cur`}.data, t, 0, LOCATION.LITERAL})
             /; if (tok`{nnl}.cmp(","))
                 ;cur`++
             ;/
-- 
cgit v1.2.3