summaryrefslogtreecommitdiff
path: root/tnslc
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc')
-rw-r--r--tnslc/compile/function.tnsl2
-rw-r--r--tnslc/compile/scope.tnsl84
-rw-r--r--tnslc/compile/var.tnsl75
-rw-r--r--tnslc/test.tnsl10
4 files changed, 134 insertions, 37 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl
index 6f7fceb..a57aa76 100644
--- a/tnslc/compile/function.tnsl
+++ b/tnslc/compile/function.tnsl
@@ -140,6 +140,8 @@ struct Function {
;/
# Write label and opening
+ # Nieve implementation: r10-r15 are callee saved registers
+ # in the TNSL style ABI
out.place_base_label()
cb`.add_c(" push rbp\n\0")
cb`.add_c(" lea rbp, [rsp + 8]\n\0")
diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl
index d3f86a9..e3348dd 100644
--- a/tnslc/compile/scope.tnsl
+++ b/tnslc/compile/scope.tnsl
@@ -6,7 +6,8 @@ struct Scope {
~Scope parent,
utils.Vector vars, tmps,
-
+
+ # Used for generating unique sub-scope labels
int unique
}
@@ -109,7 +110,7 @@ struct Scope {
~Var v
/; loop (int i = 0; i < self.tmps.count) [i++]
- v = self.vars.get(i)
+ v = self.tmps.get(i)
/; if (v`.loc > 1)
out++
/; if (out > 4)
@@ -158,7 +159,6 @@ struct Scope {
Var mk = v`.copy()
mk.offset = 0
- # TODO: Make sure this works properly
/; if (mk.loc > 0)
mk.loc = 1
;/
@@ -175,7 +175,7 @@ struct Scope {
tp = sub
;; else if (sub`._type == parse.NTYPE_ID)
/; if (tp == NULL)
- _printf("COMPILER ERROR: Should have type node before first id in decl node\n\0")
+ _printf("COMPILER ERROR: Should have type node before first id in decl/dlist node\n\0")
return
;/
@@ -184,11 +184,12 @@ struct Scope {
v.init(tp, sub)
v._resolve_type(self.mod)
- # TODO: Make sure this works properly
+ # Compute weather we can put it in a register
/; if (v.regable() == true)
v.loc = 1
;; else
- v.loc = 0 - 1
+ v.loc = 0
+ v.loc = v.loc - 1
;/
v.offset = 0
@@ -198,14 +199,47 @@ struct Scope {
/; if (sub`.sub.count > 0)
sub = sub`.sub.get(0)
/; if (sub`._type == parse.NTYPE_VALUE)
- self.precheck_stmt(n)
+ self.precheck_stmt(sub)
;/
;/
;/
;/
;/
+ /; try_move (~parse.Node n)
+ /; loop (n`._type == parse.NTYPE_PRE_OP)
+ /; if (n`.sub.count < 1)
+ return
+ ;/
+ n = n`.sub.get(0)
+ ;/
+
+ /; if (n`._type == parse.NTYPE_ID)
+ ~Var to_move = self._find_var(n`.data)
+ /; if (to_move == NULL)
+ return
+ ;/
+
+ /; if (to_move`.loc > 0)
+ int negative = 0
+ to_move`.loc = negative - 1
+ ;/
+ ;/
+ ;/
+
/; precheck_stmt (~parse.Node n)
+ /; if (n`._type == parse.NTYPE_PRE_OP)
+ /; if (utils.strcmp(n`.data, "~\0") == true)
+ self.try_move(n)
+ return
+ ;/
+ ;/
+
+ ~parse.Node sub
+ /; loop (int i = 0; i < n`.sub.count) [i++]
+ sub = n`.sub.get(i)
+ self.precheck_stmt(sub)
+ ;/
;/
/; _find_var (~uint8 name) [~Var]
@@ -260,6 +294,17 @@ struct Scope {
;/
;/
+ /; if (v`.loc < 0)
+ int stk = v`.actual_size()
+ ~uint8 stk_str = utils.int_to_str(stk)
+ self.cb`.add_c(" sub rsp, \0")
+ self.cb`.add_c(stk_str)
+ self.cb`.add_c(" ; Create stack space for local variable \0")
+ self.cb`.add_c(v`.name)
+ self.cb`.add_c("\n\0")
+ _delete(stk_str)
+ ;/
+
return v
;/
@@ -270,24 +315,12 @@ struct Scope {
return NULL
;/
- ~int32 p = v`.top_ptrc()
- /; if (p == NULL)
- v`.set(self.cb, src)
- ;; else if (p` == 0)
+ /; if (v`.is_ref() == true)
v`.set_ref(self.cb, src)
;; else
v`.set(self.cb, src)
;/
- /; if (v`.loc < 0)
- int stk = v`.actual_size()
- ~uint8 stk_str = utils.int_to_str(stk)
- self.cb`.add_c(" sub rsp, \0")
- self.cb`.add_c(stk_str)
- self.cb`.add_c("\n\0")
- _delete(stk_str)
- ;/
-
return v
;/
@@ -316,7 +349,7 @@ struct Scope {
~uint8 stk_str = utils.int_to_str(stk)
self.cb`.add_c(" sub rsp, \0")
self.cb`.add_c(stk_str)
- self.cb`.add_c("\n\0")
+ self.cb`.add_c(" ; Create stack space for tmp variable\n\0")
_delete(stk_str)
;/
@@ -349,7 +382,7 @@ struct Scope {
~uint8 stk_mv_str = utils.int_to_str(stk_mv)
self.cb`.add_c(" add rsp, \0")
self.cb`.add_c(stk_mv_str)
- self.cb`.add_c("\n\0")
+ self.cb`.add_c(" ; Free stack space (freeing tmp variables)\n\0")
_delete(stk_mv_str)
;/
;/
@@ -378,7 +411,7 @@ struct Scope {
true_name.push_char('#')
true_name.push_cstr(name)
_delete(u)
-
+
Scope out = self.mk_sub(true_name.as_cstr())
true_name.end()
@@ -389,14 +422,13 @@ struct Scope {
;/
# 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
;/
@@ -438,7 +470,7 @@ struct Scope {
# Label generation
#
-
+
/; _base_label [utils.Vector]
utils.Vector out
out.init(1)
diff --git a/tnslc/compile/var.tnsl b/tnslc/compile/var.tnsl
index e5608bb..b684c33 100644
--- a/tnslc/compile/var.tnsl
+++ b/tnslc/compile/var.tnsl
@@ -134,6 +134,15 @@ struct Var {
return out
;/
+ /; is_ref [bool]
+ ~int32 p = self.top_ptrc()
+ /; if (p == NULL)
+ return false
+ ;/
+
+ return p` == 0
+ ;/
+
/; _print (int idt)
_indent(idt)
_printf("{ Var : \0")
@@ -410,11 +419,24 @@ struct Var {
# Set this Variable to the value of other
/; set (~CompBuf buf, ~Var other)
- self.standard_op(buf, other, "mov\0")
+ # Options:
+ # - If builtin then move based on size (byte, word, dword, qword)
+ # - If pointer then move qword
+ # - If struct then move via rep movsb
+
+ # Changes need to be made based on whether either is on the stack
+ # or if either is a reference
+
+ # Can move to/from stack if only one is on stack/reference
+ # otherwise we must pre-mov the source into RSI and then
+ # we can move into the recipiant's address
+
+ /; if ()
+ ;/
;/
# Set the address which this reference points to
- /; set_ref(~CompBuf buf, ~Var other)
+ /; set_ref (~CompBuf buf, ~Var other)
;/
# Generate a variable which can actually be used for operations
@@ -474,6 +496,28 @@ struct Var {
/; product_op (~CompBuf buf, ~Var other, ~uint8 op_str, int read_reg)
+ Var cpy = self.copy()
+ cpy.loc = 1
+ cpy.offset = 0
+
+ # Set RAX register for product operation
+ cpy.set(buf, ~self)
+
+ ~uint8 from_str = other`.gen_loc()
+
+ buf`.add_c(" \0")
+ buf`.add_c(op_str)
+ buf`.add_c(" \0")
+ buf`.add_c(from_str)
+ buf`.add_c("\n\0")
+
+ _delete(from_str)
+
+ # Set back the var from the read_reg
+ cpy.loc = read_reg
+ self.set(buf, cpy)
+
+ cpy.end()
;/
/; add (~CompBuf buf, ~Var other)
@@ -497,7 +541,12 @@ struct Var {
self.offset = self.offset * other`.offset
return
;/
- self.product_op(buf, other, "imul", 1)
+
+ /; if (self.name{0} == 'u')
+ self.product_op(buf, other, "mul", 1)
+ ;; else
+ self.product_op(buf, other, "imul", 1)
+ ;/
;/
/; div (~CompBuf buf, ~Var other)
@@ -506,10 +555,10 @@ struct Var {
return
;/
- /; if ("signed")
- self.product_op(buf, other, "idiv", 1)
- ;; else
+ /; if (self.name{0} == 'u')
self.product_op(buf, other, "div", 1)
+ ;; else
+ self.product_op(buf, other, "idiv", 1)
;/
;/
@@ -519,10 +568,10 @@ struct Var {
return
;/
- /; if ("signed")
- self.product_op(buf, other, "idiv", 4)
- ;; else
+ /; if (self.name{0} == 'u')
self.product_op(buf, other, "div", 4)
+ ;; else
+ self.product_op(buf, other, "idiv", 4)
;/
;/
@@ -538,6 +587,14 @@ struct Var {
self.standard_op(buf, other, "xor")
;/
+ /; not (~CompBuf buf)
+ ~uint8 to_str = self.gen_loc()
+ buf`.add_c(" not \0")
+ buf`.add_c(to_str)
+ buf`.add_c("\n\0")
+ _delete(to_str)
+ ;/
+
/; member (~CompBuf buf, ~uint8 name) [Var]
Var out
return out
diff --git a/tnslc/test.tnsl b/tnslc/test.tnsl
index bedadcb..ddc10d1 100644
--- a/tnslc/test.tnsl
+++ b/tnslc/test.tnsl
@@ -1,5 +1,11 @@
-/; main [int]
- return 0
+/; main (int argc, ~~uint8 argv) [int]
+ int i = 0
+ /; if (len args > 1)
+ i = len args
+ ;; else
+ i = ~args
+ ;/
+ return i
;/