summaryrefslogtreecommitdiff
path: root/tnslc/compile
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc/compile')
-rw-r--r--tnslc/compile/compbuf.tnsl74
-rw-r--r--tnslc/compile/function.tnsl55
-rw-r--r--tnslc/compile/scope.tnsl9
-rw-r--r--tnslc/compile/var.tnsl67
4 files changed, 149 insertions, 56 deletions
diff --git a/tnslc/compile/compbuf.tnsl b/tnslc/compile/compbuf.tnsl
index d4bc640..94f4e9b 100644
--- a/tnslc/compile/compbuf.tnsl
+++ b/tnslc/compile/compbuf.tnsl
@@ -1,45 +1,55 @@
struct CompBuf {
- utils.Vector
- sec_head,
- sec_data,
- sec_code
+ utils.Vector
+ sec_head,
+ sec_data,
+ sec_code
}
/; method CompBuf
- /; init
- self.sec_head.init(1)
- self.sec_data.init(1)
- self.sec_code.init(1)
- ;/
+ /; init
+ self.sec_head.init(1)
+ self.sec_data.init(1)
+ self.sec_code.init(1)
+ ;/
- /; add_h(~uint8 text)
- self.sec_head.push_cstr(text)
- ;/
+ /; add_h(~uint8 text)
+ self.sec_head.push_cstr(text)
+ ;/
- /; add_d(~uint8 text)
- self.sec_data.push_cstr(text)
- ;/
-
- /; add_c(~uint8 text)
- self.sec_code.push_cstr(text)
- ;/
+ /; add_d(~uint8 text)
+ self.sec_data.push_cstr(text)
+ ;/
- /; write_to(~utils.File fout)
- fout`.write_cstr("BITS 64\n\0")
- fout`.write_cstr(self.sec_head.as_cstr())
+ /; add_c(~uint8 text)
+ self.sec_code.push_cstr(text)
+ ;/
- fout`.write_cstr("\nsection .data\n\n\0")
- fout`.write_cstr(self.sec_data.as_cstr())
+ /; write_to(~utils.File fout)
+ fout`.write_cstr("BITS 64\n\0")
+ fout`.write_cstr(self.sec_head.as_cstr())
- fout`.write_cstr("\nsection .text\n\n\0")
- fout`.write_cstr(self.sec_code.as_cstr())
- ;/
+ fout`.write_cstr("\nsection .data\n\n\0")
+ fout`.write_cstr(self.sec_data.as_cstr())
- /; end
- self.sec_head.end()
- self.sec_data.end()
- self.sec_code.end()
- ;/
+ fout`.write_cstr("\nsection .text\n\n\0")
+ fout`.write_cstr(self.sec_code.as_cstr())
+ ;/
+
+ /; end
+ self.sec_head.end()
+ self.sec_data.end()
+ self.sec_code.end()
+ ;/
+
+ /; append (~CompBuf to_append)
+ ~uint8 tmp
+ tmp = to_append`.sec_head.as_cstr()
+ self.add_h(tmp)
+ tmp = to_append`.sec_data.as_cstr()
+ self.add_d(tmp)
+ tmp = to_append`.sec_code.as_cstr()
+ self.add_c(tmp)
+ ;/
;/
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl
index 29ec748..849bae1 100644
--- a/tnslc/compile/function.tnsl
+++ b/tnslc/compile/function.tnsl
@@ -967,9 +967,9 @@ struct Function {
# compile all parameters and put them into tmp vars
~parse.Node pnode
/; loop (int i = use_self; i < f`.inputs.count) [i++]
- pnode = params`.sub.get(i)
+ pnode = params`.sub.get(i - use_self)
inp = tmps.get(i)
-
+
Var param = self._compile_value(s, pnode)
inp`.set(s`.cb, ~param)
/; if (s`.is_tmp(~param))
@@ -1175,6 +1175,11 @@ struct Function {
/; if (base`._type !== parse.NTYPE_ID)
_printf("TODO: tnslc does not currently support dot-chains with literals or non-identifiers as primary\n\0")
_printf(" will look into either intuiting the type from context or requiring a cast in the future\n\0")
+ _printf(" Offending token was: \"\0")
+ _printf(base`.data)
+ _printf("\" of type \0")
+ parse.print_node_type(base)
+ _printf("\n\0")
v`.end()
v`.count = 0
return result
@@ -1407,8 +1412,6 @@ struct Function {
working.loc = 0
return working
;/
- _printf("Member:\n\0")
- mbr._print(0)
working.end()
working = mbr
@@ -1660,7 +1663,6 @@ struct Function {
# If we are setting
/; if (utils.strcmp(n`.data, "=\0") == true)
Var lhs = self._compile_value(s, lhn)
- lhs._print(0)
/; if (s`.is_tmp(~lhs) == true)
s`.free_after(~lhs, true)
@@ -1778,7 +1780,33 @@ struct Function {
out = self._compile_value(s, sub)
out.inc(s`.cb)
;; else if (utils.strcmp(n`.data, "len\0") == true)
- _printf("len not impl\n\0")
+ # generate a false compile buffer to do the computation in
+ CompBuf f_buff
+ f_buff.init()
+ # generate a false sub scope to do the computation in
+ Scope f_scope = s`.gen_sub("len\0")
+ f_scope.cb = ~f_buff
+
+ ~parse.Node sub = n`.sub.get(0)
+ Var tmp = self._compile_value(~f_scope, sub)
+
+ # Generate the length
+ ~Struct t = self._find_literal_type(s, "uint\0")
+ out = tmp._len(~f_buff, t)
+
+ # cleanup
+ tmp.end()
+ /; if (out.loc !== VLOC_LITL)
+ # Len is based on a dynamic array, function call, or other runtime value
+ # rather than something that can be statically parsed (at this time) so
+ # append the comp buf on to the current context before continuing
+ int tmps = f_scope.tmps.count
+ f_scope.free_tmp(tmps, true)
+ ~CompBuf cb = s`.cb
+ cb`.append(~f_buff)
+ ;/
+ f_scope.end()
+ f_buff.end()
;; else
_printf("COMPILER ERROR: \"\0")
_printf(n`.data)
@@ -1892,6 +1920,20 @@ struct Function {
return out
;/
+ /; _print_artifact (~utils.Vector tmp)
+
+ ~~uint8 str
+ /; loop (int i = 0; i < tmp`.count)
+ str = tmp`.get(i)
+ _printf(str`)
+
+ i++
+ /; if (i < tmp`.count)
+ _printf(".\0")
+ ;/
+ ;/
+ ;/
+
# Should handle computing a value, delegate to other funcs when needed
/; _compile_value (~Scope s, ~parse.Node n) [Var]
/; if (n`._type == parse.NTYPE_VALUE)
@@ -1907,6 +1949,7 @@ struct Function {
Var out = self._compile_chain_r_base(s, n, ~tmp)
/; if (tmp.count !== 0)
tmp.end()
+ out.end()
;; else
return out
;/
diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl
index dda3d9c..8a6747e 100644
--- a/tnslc/compile/scope.tnsl
+++ b/tnslc/compile/scope.tnsl
@@ -519,14 +519,19 @@ struct Scope {
;/
int stk_mv = 0
-
+ int tmp_count = self.tmps.count
+
~Var tmp
/; loop (int i = 1; i !> tmps) [i++]
- tmp = self.tmps.get(self.tmps.count - i)
+ tmp = self.tmps.get(tmp_count - i)
+
/; if (tmp`.loc < 0)
stk_mv = stk_mv + tmp`.actual_size()
;/
tmp`.end()
+ ;/
+
+ /; loop (int i = 0; i < tmps) [i++]
self.tmps.pop()
;/
diff --git a/tnslc/compile/var.tnsl b/tnslc/compile/var.tnsl
index a840437..8babc1b 100644
--- a/tnslc/compile/var.tnsl
+++ b/tnslc/compile/var.tnsl
@@ -483,7 +483,7 @@ struct Var {
######################
/; _static_compile_arr(~parse.Node n, ~utils.Vector out, int depth) [~uint8]
- return utils.strcpy("TODO\0")
+ return utils.strcpy("TODO ; Static compile array\0")
;/
/; _static_compile_ptr(~parse.Node n, ~utils.Vector out, int depth) [~uint8]
@@ -553,17 +553,24 @@ struct Var {
;/
# Literal not string - literal address
- # TODO
+ utils.Vector vout
+ vout.from_cstr(" dq \0")
+ vout.push_cstr(n`.data)
+ vout.push_cstr("\n\0")
+ return vout.as_cstr()
+
;; else if (n`._type == parse.NTYPE_VLIST)
return self._static_compile_arr(n, out, depth)
;/
# Do a literal evaluation and then
- return utils.strcpy("TODO\0")
+ _printf("ERROR: Static compile pointer\n\0")
+ self._print(0)
+ return utils.strcpy("TODO ; Static compile ptr\0")
;/
/; _static_compile_struct(~parse.Node n, ~utils.Vector out) [~uint8]
- return utils.strcpy("TODO\0")
+ return utils.strcpy("TODO ; Static compile struct\0")
;/
/; _static_comp_prim_r_dot(~parse.Node n) [Var]
@@ -1002,8 +1009,8 @@ struct Var {
buf`.add_c("] ; initial struct addr move\n\0")
- # For as many more times as there are references
- /; loop (int i = 1; i < self.ptrc.count) [i++]
+ # For as many more times as there are references ( minus one )
+ /; loop (int i = 2; i < self.ptrc.count) [i++]
buf`.add_c(" mov \0")
buf`.add_c(r)
buf`.add_c(", [\0")
@@ -1047,7 +1054,7 @@ struct Var {
;/
# Helper to properly get the lhs of a set
- /; _set_prim_l (~CompBuf buf) [~uint8]
+ /; _set_prim_l_base (~CompBuf buf, uint sz) [~uint8]
/; if (self.loc == 0)
_printf("SET WAS CALLED ON A LITERAL! THIS IS A COMPILER ERROR!\0")
return utils.strcpy("ERR SHOULD NOT HAPPEN - TRIED TO SETPRIML ON A LITERAL\0")
@@ -1077,7 +1084,6 @@ struct Var {
out = vout.as_cstr()
;/
;; else
- uint sz = self.type_size()
out = reg_string(self.loc, sz)
;/
;; else
@@ -1143,14 +1149,13 @@ struct Var {
/; if (out{0} == '[')
utils.Vector vout
- uint ts = self.type_size()
- /; if (ts == 1)
+ /; if (sz == 1)
vout.from_cstr("byte \0")
- ;; else if (ts == 2)
+ ;; else if (sz == 2)
vout.from_cstr("word \0")
- ;; else if (ts == 4)
+ ;; else if (sz == 4)
vout.from_cstr("dword \0")
- ;; else if (ts == 8)
+ ;; else if (sz == 8)
vout.from_cstr("qword \0")
;/
vout.push_cstr(out)
@@ -1162,6 +1167,11 @@ struct Var {
return out
;/
+ /; _set_prim_l (~CompBuf buf) [~uint8]
+ uint sz = self.type_size()
+ return self._set_prim_l_base(buf, sz)
+ ;/
+
# Helper to properly get the rhs of a set
/; _set_prim_r (~CompBuf buf, ~Var lhs) [~uint8]
/; if (self.loc == 0)
@@ -1169,13 +1179,14 @@ struct Var {
return o
;/
- ~uint8 out = self._set_prim_l(buf)
+ ~uint8 out
# Sign extend if required
bool ext = false
uint R = self.type_size()
uint L = lhs`.type_size()
/; if (R < L)
+ out = self._set_prim_l(buf)
ext = true
~uint8 vout = reg_string(5, L)
@@ -1199,6 +1210,8 @@ struct Var {
buf`.add_c("\n\0")
_delete(out)
out = vout
+ ;; else
+ out = self._set_prim_l_base(buf, L)
;/
/; if (ext == false)
@@ -1629,7 +1642,7 @@ struct Var {
buf`.add_c(" idiv \0")
;; else
# Zero out
- buf`.add_c(" xor ")
+ buf`.add_c(" xor \0")
/; if (sz == 1)
buf`.add_c("ah, ah\n\0")
;; else if (sz == 2)
@@ -1730,7 +1743,6 @@ struct Var {
return
;/
- self._print(0)
/; if (self.first_non_ref() < 0)
int idx = self.first_non_ref_idx()
Var vv
@@ -1847,6 +1859,7 @@ struct Var {
;/
/; member (~CompBuf buf, ~uint8 name) [Var]
+
/; if (self.is_struct() == false)
_printf("ERROR: Attempted to get a member named \"\0")
_printf(name)
@@ -1887,6 +1900,28 @@ struct Var {
return out
;/
+ # Len (generates differently based on whether we are an array pointer or normal variable)
+ /; _len (~CompBuf buf, ~Struct out_type) [Var]
+ Var out
+ out._init(out_type)
+
+ int32 ptr = self.first_non_ref()
+
+ /; if (ptr == 1)
+ # We are an array pointer, just deref it into an integer (size is at the beginning)
+ _printf("TODO: array len\n\0")
+ ;; else if (ptr > 1)
+ out.offset = ptr
+ ;; else if (ptr !== 0)
+ out.offset = 8
+ ;; else
+ # Just a normal variable, return the size of the type
+ out.offset = self._type`.size
+ ;/
+
+ return out
+ ;/
+
# Printing
/; _print (int idt)