diff options
Diffstat (limited to 'tnslc/compile')
| -rw-r--r-- | tnslc/compile/compbuf.tnsl | 74 | ||||
| -rw-r--r-- | tnslc/compile/function.tnsl | 55 | ||||
| -rw-r--r-- | tnslc/compile/scope.tnsl | 9 | ||||
| -rw-r--r-- | tnslc/compile/var.tnsl | 67 |
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) |