From d21c66af96878e5efff081ec861af4350d37bffe Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sat, 18 Mar 2023 17:16:50 -0400 Subject: Reference and dereference --- tnslc/tnslc.tnsl | 316 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 217 insertions(+), 99 deletions(-) (limited to 'tnslc/tnslc.tnsl') diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl index 20a7ef3..582afbd 100644 --- a/tnslc/tnslc.tnsl +++ b/tnslc/tnslc.tnsl @@ -1,3 +1,31 @@ +## +## LOG UTILITIES +## + +;{}uint8 log_level = "2" + +/; log_err ({}uint8 msg) + ;tnsl.io.print("\n[TNSLC] [ERR]: ") + ;tnsl.io.println(msg) + ;tnsl.exit() +;/ + +/; log_info ({}uint8 msg) + ;uint l = string_to_int(log_level) + /; if (l > 0) + ;tnsl.io.print("\n[TNSLC] [INFO]: ") + ;tnsl.io.println(msg) + ;/ +;/ + +/; log_debug ({}uint8 msg) + ;uint l = string_to_int(log_level) + /; if (l > 1) + ;tnsl.io.print("\n[TNSLC] [DEBUG]: ") + ;tnsl.io.println(msg) + ;/ +;/ + ## ## UTIL FUNCS ## @@ -350,6 +378,20 @@ members } +/; method Type + /; sprint [{}uint8] + ;log_debug("Sprinting Type") + ;{}uint8 out = string_join( {"{ ", int_to_string(self.s), ", ", self.name, ", ", self.mod_name, ", { "}, "") + ;{}{}uint8 pch = {} + /; loop (int i = 0; i < len(self.ptr_chain)) [i++] + ;pch.append(int_to_string(self.ptr_chain{i})) + ;/ + ;out = string_add(out, string_join(pch, ", ")) + ;out = string_add(out, " } }") + ;return out + ;/ +;/ + ;{}{}uint8 PRIM_NAMES = { "uint8", "uint16", "uint32", "uint64", "uint", "int8", "int16", "int32", "int64", "int", @@ -485,18 +527,24 @@ ;return string_join( {pre, "[", str, offset, "]" }, "") ;/ -/; strip_one({}int p) [{}int] +/; strip_int({}int p) [{}int] ;{}int out = {} - /; loop (int i = 0; i < len p) [i++] + /; loop (int i = 0; i < len p - 1) [i++] ;out.append(p{i}) ;/ ;return out ;/ -# Methods assume that the rax, rdx, rsi, and rdi registers are fair game. +# Methods on variables assume that the rax, rdx, rsi, and rdi registers are fair game. # /; method Variable + /; sprint [{}uint8] + ;return string_join( { + "{ ", self.name, ", ", self.data_type.sprint(), ", ", int_to_string(self.location), ", ", int_to_string(self.loc_type), " }" + },"") + ;/ + /; norm_loc (int sz) [{}uint8] /; if (self.loc_type == LOCATION.LABEL) ;return loc_from_str(string_add("rel ", self.name), string_add(" + ", int_to_string(self.location)), sz) @@ -513,11 +561,16 @@ ;/ /; norm_size [int] - /; if (len (self.data_type.ptr_chain) > 0) + /; if (len (self.data_type.ptr_chain) > 1) ;return 8 - ;; else + ;; else if (len (self.data_type.ptr_chain) == 0) ;return self.data_type.s ;/ + + /; if (self.data_type.ptr_chain{0} == PTYPE.REFERENCE) + ;return self.data_type.s + ;/ + ;return 8 ;/ # TODO: Match a type to another type if possible @@ -554,29 +607,41 @@ ;return false ;/ - /; strip_refs (Variable to_strip, ~CompData data) [Variable] - ;int pc = len (self.data_type.ptr_chain) - + /; strip_one (~CompData data) ;data`.csec = string_join( { data`.csec, - "\tmov rsi, ", to_strip.norm_loc(8), "\n" + "\tmov rsi, [rsi]\n" }, "") - ;to_strip.loc_type = LOCATION.REGISTER - ;to_strip.location = 4 + ;self.data_type.ptr_chain = strip_int(self.data_type.ptr_chain) + ;/ - /; loop (pc > 1) [pc = len (to_strip.data_type.ptr_chain)] - /; if (to_strip.data_type.ptr_chain{pc - 1} == PTYPE.REFERENCE && to_strip.data_type.ptr_chain{pc - 2} == PTYPE.REFERENCE) - ;data`.csec = string_join( { - data`.csec, - "\tmov rsi, [rsi]\n" - }, "") - ;to_strip.data_type.ptr_chain = strip_one(to_strip.data_type.ptr_chain) + /; strip_refs (~CompData data) [Variable] + ;int pc = len (self.data_type.ptr_chain) + + /; if (self.loc_type == LOCATION.REGISTER) + ;data`.csec = string_join( { + data`.csec, + "\tmov rsi, ", get_reg(self.location, 8), "\n" + }, "") + ;; else + ;data`.csec = string_join( { + data`.csec, + "\tmov rsi, ", self.norm_loc(8), "\n" + }, "") + ;/ + ;Variable out = {"#ref", self.data_type, 4, LOCATION.REGISTER} + + /; loop (pc > 1) [pc = len (out.data_type.ptr_chain)] + /; if (out.data_type.ptr_chain{pc - 1} == PTYPE.REFERENCE) + ;log_debug("Stripping") + ;out.strip_one(data) ;; else + ;log_debug("Breaking") ;break ;/ ;/ - - ;return to_strip + ;log_debug("Strip complete") + ;return out ;/ # functions that do work on this variable @@ -739,10 +804,19 @@ ;/ ;/ + /; move_register (int new_reg, ~CompData data) + ;int sz = self.norm_size() + ;data`.csec = string_join( { + data`.csec, + "\tmov ", get_reg(new_reg, sz), ", ", get_reg(self.location, sz), "\n" + }, "") + ;/ + /; ref (Variable to_ref, ~CompData data) ;int l = len (to_ref.data_type.ptr_chain) /; if (l > 0) /; if (to_ref.data_type.ptr_chain{l - 1} == PTYPE.REFERENCE) + ;to_ref.data_type.ptr_chain{l - 1} = PTYPE.POINTER ;self.set(to_ref, data) ;; else ;data`.csec = string_join( { @@ -760,46 +834,18 @@ ;/ ;/ - /; deref (Variable to_deref, ~CompData data) - ;to_deref = self.strip_refs(to_deref, data) - ;int dpc = len (to_deref.data_type.ptr_chain) - ;int spc = len (self.data_type.ptr_chain) - /; if (dpc == 0) - ;tnsl.io.println("Can not deref a variable that is not a pointer (ERR: ONPTRC)") - ;tnsl.quit - ;; else if (spc == 0) - ;tnsl.io.println("Can not deref into a variable that is not a reference (ERR: SNPTRC)") - ;tnsl.quit + /; deref (~CompData data) [Variable] + ;Variable out = self.strip_refs(data) + ;int opc = len (out.data_type.ptr_chain) + /; if (opc == 0) + ;log_err("Can not deref a variable that is not a pointer (ERR: SNPTRC)") ;/ - - ;data`.csec = string_join( { - data`.csec, - "\tmov rsi, ", to_deref.norm_loc(8), "\n", - "\tmov ", self.norm_loc(8), ", rsi\n" - }, "") - ;/ - - # for use on tmp variables or in a dotchain - /; deref_self (~CompData data) - ;int pc = len (self.data_type.ptr_chain) - /; if (pc == 0) - ;tnsl.io.println("Can not self_deref into a variable that is not a reference (ERR: SNPTRC)") - ;tnsl.quit - ;; else if (pc > 1 && self.data_type.ptr_chain{pc - 1} == PTYPE.REFERENCE) - ;data`.csec = string_join( { - data`.csec, - "\tmov rsi, ", self.norm_loc(8), "\n", - "\tmov ", self.norm_loc(8), ", [rsi]\n" - }, "") - ;self.data_type.ptr_chain = strip_one(self.data_type.ptr_chain) - ;pc = pc - 1 - ;/ - - ;self.data_type.ptr_chain{pc - 1} = PTYPE.REFERENCE + ;out.data_type.ptr_chain{opc - 1} = PTYPE.REFERENCE + ;return out ;/ /; member (Variable s, ~CompData data, {}uint8 name) - ;tnsl.io.println("member") + ;log_debug("member") ;int accum = 0 ;self.data_type.name = "" ;int i = 0 @@ -831,21 +877,12 @@ ;/ ;/ - /; index (Variable a, ~CompData data, Variable i) - /; if (a.loc_type == LOCATION.REGISTER) - ;data`.csec = string_join( { - data`.csec, - "\tlea rsi, ", a.norm_loc(8), "\n" - }, "") - ;; else - ;data`.csec = string_join( { - data`.csec, - "\tmov rsi, ", a.norm_loc(8), "\n" - }, "") - ;/ + /; index (Variable i, ~CompData data) [Variable] + ;Variable out = self.strip_refs(data) - ;int sz = self.norm_size() - ;bool ts_arr = a.data_type.ptr_chain{0} == PTYPE.ARRAY + ;int sz = out.norm_size() + ;int opc = len (out.data_type.ptr_chain) + ;bool ts_arr = out.data_type.ptr_chain{opc - 1} == PTYPE.ARRAY ;Variable t = {"#tmp", a.data_type, 4, LOCATION.REGISTER} /; if (ts_arr) @@ -874,13 +911,14 @@ }, "") ;/ - ;self.deref(t, data) + ;return out.deref(data) ;/ /; length_of (Variable a, ~CompData data) - ;Variable t = {"#tmp", get_primitive(is_primitive("uint")), 0, LOCATION.REGISTER} - ;t.deref(a, data) - ;self.set(t, data) + ;a.data_type.name = "uint" + ;a.data_type.s = 8 + ;a.data_type.ptr_chain = {PTYPE.REFERENCE} + ;self.set(a, data) ;/ # Uses rax, does not resolve any ending state after function returns @@ -964,7 +1002,7 @@ ;/ /; loop (int i = 0; i < len (self.vars) && out < 16) [i++] - /; if (is_primitive(self.vars{i}.data_type.name) !< 0 || len (self.vars{i}.data_type.ptr_chain) > 0) + /; if (self.vars{i}.loc_type == LOCATION.REGISTER) ;out++ ;/ ;/ @@ -1091,11 +1129,11 @@ ;new.location = self.next_loc(t) ;; else ;new.loc_type = LOCATION.STACK - ;new.location = self.get_full_stack() - ;new.location = new.location + t.s - ;out`.csec = string_add(out`.csec, "\tsub rsp, ") - ;out`.csec = string_add(out`.csec, int_to_string(t.s)) - ;out`.csec.append('\n') + ;new.location = self.get_full_stack() + new.norm_size() + ;out`.csec = string_join( { + out`.csec, + "\tsub rsp, ", int_to_string(new.norm_size()), "\n" + }, "") ;/ ;self.vars.append(new) ;/ @@ -1113,6 +1151,59 @@ ;return self.parent`.find_var(artifact, current) ;/ + /; find_reg_variable (int reg) [~Variable] + /; loop (int i = 0; i < len (self.vars)) [i++] + /; if (self.vars{i}.loc_type == LOCATION.REGISTER && self.vars{i}.location == reg) + ;return ~(self.vars{i}) + ;/ + ;/ + + /; if (!(self.is_cf())) + ;tnsl.io.print(reg) + ;log_err("Can't move variable to stack as it does not exist in the current context") + ;/ + ;return self.parent`.find_reg_variable(reg) + ;/ + + /; move_to_stack (int reg, ~CompData out) [Variable] + ;int last_var = self.next_register() + /; if (last_var < 0) + ;last_var = 16 + ;/ + + /; if (reg < 8 || reg > last_var - 1) + ;tnsl.io.println(reg) + ;log_err("Can't move a register to stack as it is not in scope.") + ;/ + + ;log_debug(string_join( { + "Attempting to move variable at register ", + int_to_string(reg), " to stack. last_var = ", int_to_string(last_var) + }, "")) + + ;~Variable rv = self.find_reg_variable(reg) + ;Variable copy = {rv`.name, rv`.data_type, 0, 0} + ;copy.loc_type = LOCATION.STACK + ;copy.location = self.get_full_stack() + copy.norm_size() + ;out`.csec = string_join( { + out`.csec, + "\tsub rsp, ", int_to_string(copy.norm_size()), "\n" + }, "") + ;copy.set(rv`, out) + ;rv` = copy + + /; if (reg < last_var) + ;rv = self.find_reg_variable(last_var - 1) + ;log_debug(string_join({ + "Moving variable from ", int_to_string(last_var - 1), " to ", int_to_string(reg), ". ", + "Variable name: ", rv`.name + }, "")) + ;rv`.move_register(reg, out) + ;/ + + ;return copy + ;/ + /; next_const [{}uint8] /; if (self.is_cf()) ;return self.parent`.next_const() @@ -1193,18 +1284,23 @@ /; _find_def ({}{}uint8 artifact, int r) [Variable] /; if (len artifact !> r) - ;retirn {{}, "", 0, 0, 0} + ;return {"", NO_TYPE, 0, 0} ;/ /; if (len artifact - 1 > r) /; loop (int i = 0; i < len (self.sub)) [i++] /; if (string_equate(artifact{r}, self.sub{i}.name)) - ;return self.sub{i}._find_type(artifact, r + 1) + ;log_debug(artifact{r}) + ;return self.sub{i}._find_def(artifact, r + 1) ;/ ;/ ;; else if (len artifact - 1 == r) + ;{}uint8 true_name = self.full_path() + /; if (len true_name > 0) + ;true_name.append('.') + ;/ + ;true_name = string_add(true_name, artifact{r}) /; loop (int i = 0; i < len (self.defs)) [i++] - ;{}uint8 true_name = string_add(self.full_path(), artifact{r}) /; if (string_equate(self.defs{i}.name, true_name)) ;return self.defs{i} ;/ @@ -1212,7 +1308,7 @@ ;/ /; if (string_equate(self.name, "")) - ;return {{}, "", 0, 0, 0} + ;return {"", NO_TYPE, 0, 0} ;/ ;~Module m = self.parent @@ -1464,10 +1560,10 @@ ;out.members = parse_param_list(tok, cur, current) /; loop (int i = 0; i < len (out.members)) [i++] - ;tnsl.io.print(string_join({"[", out.members{i}.name, ":", out.members{i}.data_type.name, "]"}, "")) + ;log_debug(string_join({"[", out.members{i}.name, ":", out.members{i}.data_type.name, "]"}, "")) ;/ - ;tnsl.io.print(string_add("Generated type ", string_add(out.name, string_add(":", out.mod_name)))) + ;log_debug(string_add("Generated type ", string_add(out.name, string_add(":", out.mod_name)))) ;current`.types.append(out) ;/ @@ -1650,7 +1746,7 @@ ;; else if (d.cmp("/;")) ;return ";/" ;/ - ;tnsl.io.println(string_add("Error, unrecognized delim: ", d.data)) + ;log_err(string_add("Error, unrecognized delim: ", d.data)) ;/ # Finds closing bracket @@ -1770,34 +1866,54 @@ /; _eval_dot (~{}Token tok, int start, max, ~CompData out, ~Module current, ~Scope scope, Type t, bool alt) [Variable] ;Variable wk ;{}{}uint8 art = {} + /; loop (tok`{start}.type_is(TOKEN.DEFWORD) && start < max) [start++] ;art.append(tok`{start}.data) ;wk = scope`.find_var(art, current) /; if (!string_equate(wk.name, "")) + ;start++ ;break ;/ /; if (tok`{start + 1}.cmp(".")) ;start++ ;; else + ;start++ ;break ;/ ;/ - + + /; if (string_equate(wk.name, "") || start !< max) + ;return wk + ;/ + ;Variable refer = {"#tmp", wk.data_type, 1, LOCATION.REGISTER} /; if (alt) ;refer.location = 2 ;/ - ;refer.set(wk, out) + + ;log_debug(wk.sprint()) + + ;refer.data_type.ptr_chain.append(PTYPE.REFERENCE) + /; if (tok`{start}.cmp(".")) + ;log_debug("Pre loop ref") + ;refer.ref(wk, out) + ;; else + ;log_debug("Pre loop deref") + ;refer = wk.deref(out) + ;/ + ;start++ ;tnsl.io.println(refer.name) - ;tnsl.io.println(refer.data_type.name) + ;tnsl.io.println(refer.data_type) /; loop (start < max) [start++] /; if (tok`{start}.cmp("`")) - ;refer.deref(refer, out) + ;log_debug("Loop deref") + ;refer = refer.deref(out) ;; else if (tok`{start}.cmp(".") && tok`{start + 1}.type_is(TOKEN.DEFWORD)) + ;log_debug("Loop member") ;refer.member(refer, out, tok`{start + 1}.data) ;start++ ;/ @@ -1891,20 +2007,20 @@ ;t = s1.data_type ;/ ;s2 = _eval_value(tok, first + 1, max, out, current, scope, t, !alt) - ;tnsl.io.print("Calculated s2 as ") - ;tnsl.io.println(s2.name) + ;log_debug(string_add("Calculated s2 as ", s2.name)) ;/ - ;tnsl.io.print("Calculated s1 as ") - ;tnsl.io.println(s1.name) + ;log_debug(string_add("Calculated s2 as ", s1.name)) /; if (tok`{first}.cmp("=")) ;s1.set(s2, out) ;return s1 ;/ - ;tnsl.io.println(t.name) - ;tnsl.io.println(t.s) + ;log_debug(string_join( { + "_eval_value called with following type info:", t.name, int_to_string(t.s) + }, " ")) + ;Variable wk = {"#wk", t, 1, LOCATION.REGISTER} /; if (alt) ;wk.location = 2 @@ -1941,9 +2057,10 @@ ;; else if (tok`{first}.cmp("%")) ;wk.set(s1, out) ;wk.mod(s2, out) - ;; else if (tok`{first}.cmp("`")) - ;wk.deref(s1, out) ;; else if (tok`{first}.cmp("~")) + /; if (!(s1.is_ref()) && s1.loc_type == LOCATION.REGISTER) + ;s1 = scope`.move_to_stack(s1.location, out) + ;/ ;wk.ref(s1, out) ;; else if (tok`{first}.cmp("!")) ;wk.not(s1, out) @@ -2639,6 +2756,7 @@ ## /; main ({}{}uint8 args) [int] + ;log_debug("TNSLC version 0.0.1, built with debugging enabled") /; if (len args < 1) ;tnsl.io.println("Give me something to compile!") ;return 1 -- cgit v1.2.3