summaryrefslogtreecommitdiff
path: root/tnslc/compile
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc/compile')
-rw-r--r--tnslc/compile/function.tnsl55
-rw-r--r--tnslc/compile/scope.tnsl1
-rw-r--r--tnslc/compile/struct.tnsl5
-rw-r--r--tnslc/compile/var.tnsl170
4 files changed, 210 insertions, 21 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl
index 481b1b6..a8517cb 100644
--- a/tnslc/compile/function.tnsl
+++ b/tnslc/compile/function.tnsl
@@ -440,6 +440,45 @@ struct Function {
return found
;/
+ /; _compile_set (~Scope s, ~parse.Node n, ~Var type_hint) [Var]
+ # TODO
+ Var out
+ return out
+ ;/
+
+ /; _compile_bin (~Scope s, ~parse.Node n, ~Var type_hint) [Var]
+ # TODO
+ Var out
+ return out
+ ;/
+
+ /; _compile_pre (~Scope s, ~parse.Node n, ~Var type_hint) [Var]
+ Var out
+
+ /; if (utils.strcmp(n`.data, "-\0") == true)
+ ~parse.Node sub = n`.sub.get(0)
+ out = self._compile_value(s, sub, type_hint)
+ out.neg(s`.cb)
+ ;; else if (utils.strcmp(n`.data, "!\0") == true)
+ _printf("! not impl\n\0")
+ ;; else if (utils.strcmp(n`.data, "~\0") == true)
+ _printf("~ not impl\n\0")
+ ;; else if (utils.strcmp(n`.data, "--\0") == true)
+ _printf("-- not impl\n\0")
+ ;; else if (utils.strcmp(n`.data, "++\0") == true)
+ _printf("++ not impl\n\0")
+ ;; else if (utils.strcmp(n`.data, "len\0") == true)
+ _printf("len not impl\n\0")
+ ;; else
+ _printf("COMPILER ERROR: \"\0")
+ _printf(n`.data)
+ _printf("\" NOT RECOGNIZED AS A VALID PREOP\n\0")
+ out = type_hint`.copy()
+ ;/
+
+ return out
+ ;/
+
# Should handle computing a value, delegate to other funcs when needed
/; _compile_value (~Scope s, ~parse.Node n, ~Var type_hint) [Var]
/; if (n`._type == parse.NTYPE_VALUE)
@@ -456,12 +495,28 @@ struct Function {
out.offset = self._compile_literal(n)
return out
;/
+
+ _printf("Could not compile literal \"\0")
+ _printf(n`.data)
+ _printf("\" in scope \0")
+ ~uint8 bl = s`.base_label()
+ _printf(bl)
+ _delete(bl)
+ _printf(" since the type was struct \"\0")
+ _printf(type_hint`._type`.name)
+ _printf("\"\n\0")
;; else if (n`._type == parse.NTYPE_ID)
~Var o = self._compile_base_id(s, n)
/; if (o !== NULL)
return o`.copy()
;/
+
+ ;; else if (n`._type == parse.NTYPE_PRE_OP)
+ return self._compile_pre(s, n, type_hint)
+
+ ;; else if (n`._type == parse.NTYPE_BIN_OP)
+ return self._compile_bin(s, n, type_hint)
;/
Var out = type_hint`.copy()
diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl
index e94fc8d..6faf596 100644
--- a/tnslc/compile/scope.tnsl
+++ b/tnslc/compile/scope.tnsl
@@ -338,6 +338,7 @@ struct Scope {
/; if (v`.is_ref() == true)
int rc = v`.max_ref()
+ rc = rc - 1
v`.set_ref(self.cb, src, rc)
;; else
v`.set(self.cb, src)
diff --git a/tnslc/compile/struct.tnsl b/tnslc/compile/struct.tnsl
index 5eded31..ed0b76a 100644
--- a/tnslc/compile/struct.tnsl
+++ b/tnslc/compile/struct.tnsl
@@ -136,10 +136,11 @@ struct Struct {
_printf("}\n\0")
;/
- /; add_member(~parse.Node tn, ~parse.Node id)
+ /; add_member(~parse.Node tn, ~parse.Node id, int offset)
Var v
v.init(tn, id)
v._resolve_type(self.methods)
+ v.offset = offset
self.members.push(~v)
;/
@@ -198,7 +199,7 @@ struct Struct {
_printf("\n\0")
return
;/
- self.add_member(tn, n)
+ self.add_member(tn, n, total)
total = total + add_size
;/
;/
diff --git a/tnslc/compile/var.tnsl b/tnslc/compile/var.tnsl
index e323e8d..85b5d22 100644
--- a/tnslc/compile/var.tnsl
+++ b/tnslc/compile/var.tnsl
@@ -183,31 +183,35 @@ struct Var {
return out
;/
- # Returns true if the variable is a reference
- /; is_ref [bool]
- ~int32 p = self.top_ptrc()
- /; if (p == NULL)
+ /; is_ptrc (int idx, int32 ptype) [bool]
+ /; if (idx !< self.ptrc.count)
return false
;/
+
+ idx = self.ptrc.count - idx
+ idx = idx - 1
+ ~int32 chk = self.ptrc.get(idx)
+ return chk` == ptype
+ ;/
- return p` == 0
+ # Returns true if the variable is a reference
+ /; is_ref [bool]
+ return self.is_ptrc(0, 0)
;/
# Returns true if two or more ref layers
/; double_ref [bool]
- /; if (self.ptrc.count < 2)
+ /; if (self.is_ref() == false)
return false
;/
- ~int32 p = self.ptrc.get(1)
- return p` == 0
+ return self.is_ptrc(1, 0)
;/
# Ref level
/; max_ref [int]
int out = 0
/; loop (int i = 0; i < self.ptrc.count)
- ~int32 p = self.ptrc.get(i)
- /; if (p` == 0)
+ /; if (self.is_ptrc(i, 0) == true)
out++
;; else
i = self.ptrc.count
@@ -566,6 +570,24 @@ struct Var {
/; if (self.loc > 0)
/; if (self.in_mem() == true)
out = reg_string(self.loc, 8)
+ /; if (self.offset !== 0)
+ utils.Vector vout
+ vout.from_cstr(out)
+
+ int off = self.offset
+ /; if (off < 0)
+ off = 0 - off
+ vout.push_cstr(" - \0")
+ ;; else if (off > 0)
+ vout.push_cstr(" + \0")
+ ;/
+
+ _delete(out)
+ out = utils.int_to_str(off)
+ vout.push_cstr(out)
+ _delete(out)
+ out = vout.as_cstr()
+ ;/
;; else
uint sz = self.type_size()
out = reg_string(self.loc, sz)
@@ -619,11 +641,10 @@ struct Var {
# Loop and make sure we are dereferencing properly
/; loop (int i = 1; i < self.ptrc.count) [i++]
- ~int pc = self.ptrc.get(i)
- /; if (pc` !== 0)
- i = self.ptrc.count
- ;; else
+ /; if (self.is_ptrc(i, 0) == true)
buf`.add_c(" mov rdi, [rdi] ; auto deref\n\0")
+ ;; else
+ i = self.ptrc.count
;/
;/
@@ -741,22 +762,78 @@ struct Var {
# count how many refs
int max_depth = self.max_ref()
- /; if (max_depth < depth)
- _print_num("Unable to set reference, depth %d exceeds max_depth \0", depth)
+ /; if (depth !< max_depth)
+ _print_num("ERROR: Unable to set reference, depth %d equals or exceeds max_depth \0", depth)
_print_num("%d\n\0", max_depth)
+ _printf(" When taking ref of variable \"\0")
+ _printf(other`.name)
+ _printf("\" into variable \"\0")
+ _printf(self.name)
+ _printf("\"\n\0")
return
;/
int32 set = 0
set = set - 1
+ max_depth = copy.ptrc.count - max_depth
+
Var copy = self.copy()
- ~int32 ptr = copy.ptrc.get(max_depth - depth)
+ ~int32 ptr = copy.ptrc.get(max_depth + depth)
ptr` = set
copy.set(buf, other)
copy.end()
;/
+ # Copy the pointer to this variable into the output reg (or not if not needed)
+ /; take_ptr (~CompBuf buf, int reg) [Var]
+ Var vcpy = self.copy()
+ /; if (self.in_mem() == false)
+ _printf("COMPILER ERROR: UNABLE TO GET REFERENCE OF VAR \"\0")
+ _printf(self.name)
+ _printf("\" PLEASE REPORT THIS BUG!\n\0")
+ return vcpy
+ ;/
+
+ int32 set = 0
+ set = set - 1
+ /; if (vcpy.is_ref() == true)
+ # If we are a ref, we want to set the first one and that's it
+ int idx = 0
+ /; loop (int i = 0; i < vcpy.ptrc.count) [i++]
+ /; if (vcpy.is_ptrc(i, 0) == false)
+ i = vcpy.ptrc.count
+ ;; else
+ set++
+ ;/
+ ;/
+
+ idx = vcpy.ptrc.count - idx
+ ~int32 p = vcpy.ptrc.get(idx)
+ p` = set
+ ;; else
+ /; if (self.is_struct() == true)
+ self._set_struct_r(buf, reg)
+ ;; else
+ ~uint8 source = self._set_prim_l(buf)
+ ~uint8 rstr = reg_string(reg, 8)
+ buf`.add_c(" lea \0")
+ buf`.add_c(rstr)
+ buf`.add_c(", \0")
+ buf`.add_c(source)
+ buf`.add_c("\n\0")
+ _delete(source)
+ _delete(rstr)
+ ;/
+
+ vcpy.loc = reg
+ vcpy.offset = 0
+ vcpy.ptr_push(set)
+ ;/
+
+ return vcpy
+ ;/
+
#######################
# Standard operations #
#######################
@@ -989,12 +1066,67 @@ struct Var {
_delete(to_str)
;/
+ /; neg (~CompBuf buf)
+ /; if (self.loc == VLOC_LITL)
+ int off = 0
+ self.offset = off - self.offset
+ return
+ ;/
+
+ ~uint8 to_str = self._set_prim_l(buf)
+ buf`.add_c(" neg \0")
+ /; if (self.in_mem() == true)
+ uint sz = self.type_size()
+ /; if (sz == 1)
+ buf`.add_c("byte \0")
+ ;; else if (sz == 2)
+ buf`.add_c("word \0")
+ ;; else if (sz == 4)
+ buf`.add_c("dword \0")
+ ;; else if (sz == 8)
+ buf`.add_c("qword \0")
+ ;/
+ ;/
+ buf`.add_c(to_str)
+ buf`.add_c("\n\0")
+ _delete(to_str)
+ ;/
+
/; member (~CompBuf buf, ~uint8 name) [Var]
- Var out
+ /; if (self.is_struct() == false)
+ _printf("ERROR: Attempted to get a member named \"\0")
+ _printf(name)
+ _printf("\" from a primitive type \"\0")
+ _printf(self._type`.name)
+ _printf("\"\n\0")
+ _printf(" (If the previous type was in fact a structure then the variable was probably a pointer)\n\0")
+ return self.copy()
+ ;/
+
+ ~Var mbr = self`._type`.get_member(name)
+
+ /; if (mbr == NULL)
+ _printf("ERROR: member \"\0")
+ _printf(name)
+ _printf("\" not found in struct \"\0")
+ _printf(self._type`.name)
+ _printf("\n\0")
+ return self.copy()
+ ;/
+
+ Var out = mbr`.copy()
+
+ /; if (self.is_ref() == true)
+ self._set_struct_r(buf, 5)
+ out.loc = 5
+ ;; else
+ out.loc = self.loc
+ out.offset = out.offset + self.offset
+ ;/
+
return out
;/
-
# Printing
/; _print (int idt)