From 1309264425fa72fc7703711cbebabd839c3883cb Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Tue, 21 Feb 2023 05:06:49 -0500 Subject: Bugfix for method labels --- tnslc/tnslc.tnsl | 460 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 379 insertions(+), 81 deletions(-) (limited to 'tnslc/tnslc.tnsl') diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl index c4a832d..bfac5d2 100644 --- a/tnslc/tnslc.tnsl +++ b/tnslc/tnslc.tnsl @@ -466,14 +466,7 @@ /; if (off !== 0) ;off = string_add(" + ", int_to_string(offset)) ;/ - ;{}uint8 out = string_join({ - "\tmov ", - mov_by_size(sz), - " [rel ", - l, off, - "]" - }, "") - ;return out + ;return string_join( { "[rel ", l, off, "]" }, "") ;/ # Most methods make use of one or more temporary variables. @@ -482,11 +475,11 @@ /; norm_loc (int sz) [{}uint8] /; if (self.loc_type == LOCATION.LABEL) - ;return "" + ;return label_to_loc(self.name, sz, 0) ;; else if (self.loc_type == LOCATION.REGISTER) ;return get_reg(self.location, sz) ;; else if (self.loc_type == LOCATION.STACK) - ;return string_join( { "[ rsp + ", int_to_string(self.location), " ]" } , "") + ;return string_join( { "[ rbp - ", int_to_string(self.location), " ]" }, "") ;/ ;/ @@ -524,7 +517,7 @@ ;return self.norm_op("add", { self.norm_loc(self.norm_size()), get_reg(tr, self.norm_size()) }) ;/ - /; sub (Variable v) + /; sub (Variable v) [{}uint8] /; if (self.loc_type == LOCATION.LITERAL) /; if (v.loc_type !== LOCATION.LITERAL) ;return v.add(self) @@ -539,7 +532,7 @@ ;return self.norm_op("sub", { self.norm_loc(self.norm_size()), get_reg(tr, self.norm_size()) }) ;/ - /; div (Variable v) + /; div (Variable v) [{}uint8] /; if (self.loc_type == LOCATION.LITERAL) /; if (v.loc_type !== LOCATION.LITERAL) ;return v.div(self) @@ -554,7 +547,7 @@ ;return self.norm_op("div", { self.norm_loc(self.norm_size()), v.norm_loc(self.norm_size) }) ;/ - /; mul (Variable v) + /; mul (Variable v) [{}uint8] /; if (self.loc_type == LOCATION.LITERAL) /; if (v.loc_type !== LOCATION.LITERAL) ;return v.mul(self) @@ -569,7 +562,7 @@ ;return self.norm_op("mul", { self.norm_loc(self.norm_size()), v.norm_loc(self.norm_size) }) ;/ - /; set (Variable v) + /; set (Variable v, ~CompData dat) /; if (self.loc_type == LOCATION.LITERAL) /; if (v.loc_type !== LOCATION.LITERAL) ;return v.set(self) @@ -585,26 +578,26 @@ ;/ # functions that do work on another variable - /; ref (Variable out) + /; ref (~Variable out, ~CompData dat) ;/ - /; deref (Variable out) + /; deref (~Variable out, ~CompData dat) ;/ - /; member (Variable out, {}uint8 name) + /; member (~Variable out, ~CompData dat, {}uint8 name) ;/ - /; index (Variable out, Variable i) - /; + /; index (~Variable out, ~CompData dat, Variable i) - ;/ ;/ - /; call ({}uint8 name) + /; call ({}uint8 name, ~CompData dat) ;/ ;/ ;struct Scope { + {}int level, + int num, ~Scope parent, {}uint8 name, {}Variable vars @@ -616,11 +609,7 @@ /; if (len split == 0) ;return false ;/ - /; if (string_equate(split{0}, "if") || - string_equate(split{0}, "else") || - string_equate(split{0}, "loop") || - string_equate(split{0}, "match") || - string_equate(split{0}, "case")) + /; if (split{0}{0} == '#') /; loop (int i = 1; i < len split; i++) /; if (len split{i} > 0) /; if (split{i}{0} < '0' || split{i}{0} > '9') @@ -635,6 +624,11 @@ ;return false ;/ + /; cf_type ({}uint8 cf) [bool] + ;{}{}uint8 split = string_split(self.name, '_') + ;return string_equate(split{0}, string_add("#", cf)) + ;/ + /; full_label [{}uint8] ;{}uint8 out = "" /; if (self.is_cf()) @@ -655,8 +649,13 @@ /; next_register [int] ;int out = 8 - /; loop (int i = 0; i < len (self.vars)) [i++] - /; if (is_primitive(self.vars{i})) + + /; if (self.is_cf()) + ;out = self.parent`.next_register() + ;/ + + /; 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) ;out++ ;/ ;/ @@ -672,26 +671,36 @@ ;int out = 0 /; loop (int i = 0; i < len (self.vars)) [i++] - /; if (is_primitive(self.vars{i})) - ;continue + /; if (self.vars{i}.loc_type == LOCATION.STACK) + ;out = out + self.vars{i}.s + ;/ + ;/ + + ;return out + ;/ + + /; get_full_stack [int] + ;int out = 0 + /; if (self.is_cf()) + ;out = self.parent`.get_stack() + ;/ + + /; loop (int i = 0; i < len (self.vars)) [i++] + /; if (self.vars{i}.loc_type == LOCATION.STACK) + ;out = out + self.vars{i}.s ;/ - ;out = out + self.vars{i}.s ;/ ;return out ;/ /; next_loc (Type t) [int] - /; if (is_primitive(t)) + /; if (is_primitive(t.name) || len (t.ptr_chain) > 0) ;return self.next_register() ;/ ;return -1 ;/ - /; initialize ({}Variable v) - ;self.vars = v - ;/ - /; begin_scope (~CompData out) ;int reg = 8 @@ -702,8 +711,102 @@ /; end_scope (~CompData out) ;{}uint8 outro = "\tpop r15\n\tpop r14\n\tpop r13\n\tpop r12\n\tpop r11\n\tpop r10\n\tpop r9\n\tpop r8\n" + ;out`.csec = string_add(out`.csec, outro) ;/ + + /; scope_cleanup (~CompData out) + ;uint sz_to_clean = 0 + + /; loop (int i = 0; i < len (self.vars)) + /; if (self.vars{i}.loc_type == LOCATION.STACK) + ;sz_to_clean = sz_to_clean + self.vars{i}.s + ;/ + ;/ + + /; if (sz_to_clean > 0) + ;out`.csec = string_add(out`.csec, string_add("\tadd rsp, ", int_to_string(sz_to_clean))) + ;/ + ;/ + + /; scope_start_label [{}uint8] + ;return string_add(self.full_label(), "_start") + ;/ + + /; scope_rep_label [{}uint8] + ;return string_add(self.full_label(), "_rep") + ;/ + + /; scope_end_label [{}uint8] + ;return string_add(self.full_label(), "_end") + ;/ + + /; new_sub_cf ({}uint8 cf) [Scope] + ;cf = string_add("#", cf) + ;{}int s = self.level + ;s.append(self.num) + ;self.num++ + + /; loop (int i = 0; i < len (s)) [i++] + ;cf.append('_') + ;cf = string_add(cf, int_to_string(s{i})) + ;/ + + ;return {s, 0, ~self, cf, {}} + ;/ + + /; get_continue (uint i) [{}uint8] + ;~Scope top = ~self + /; loop (i > 0 || top`.cf_type("")) + ;top = top`.parent + /; if (!(top`.cf_type(""))) + ;i = i - 1 + ;/ + ;/ + ;/ + + /; get_break (uint i) [{}uint8] + ;~Scope top = ~self + /; loop (i > 0 || top`.cf_type("")) + ;top = top`.parent + /; if (!(top`.cf_type(""))) + ;i = i - 1 + ;/ + ;/ + ;/ + + /; new_var (Type t, {}uint8 name, ~CompData out) + ;Variable new = {name, t, 0, 0} + /; if (self.next_loc(t) !< 0) + ;new.loc_type = LOCATION.REGISTER + ;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') + ;/ + ;self.vars.append(new) + ;/ + + /; find_var ({}{}uint8 artifact, ~Module current) [Variable] + /; if (len artifact > 1) + ;return current`.find_def(artifact) + ;/ + + /; loop (int i = 0; i < len (self.vars)) [i++] + /; if (string_equate(self.vars{i}.name, artifact{0})) + ;return self.vars{i} + ;/ + ;/ + + /; if (!self.is_cf()) + ;return current`.find_def(artifact) + ;/ + ;return self.parent`.find_var(artifact, current) + ;/ ;/ ;struct Function { @@ -835,6 +938,41 @@ ;return _find_function(artifact, 0) ;/ + /; _find_mod ({}{}uint8 artifact, int r) [~Module] + /; if (len artifact !> r) + ;return ~self + ;/ + + /; 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_mod(artifact, r + 1) + ;/ + ;/ + ;; else if (len artifact - 1 == r) + ;{}uint8 v1 = string_add("_#", artifact{r}), v2 = string_add("__#", artifact{r}) + /; loop (int i = 0; i < len (self.defs)) [i++] + /; if (string_equate(self.sub{i}.name, artifact{r}) ||string_equate(self.sub{i}.name, v1) || string_equate(self.sub{i}.name, v2)) + ;return ~(self.sub{i}) + ;/ + ;/ + ;/ + + /; if (string_equate(self.name, "")) + ;return ~self + ;/ + + ;~Module m = self.parent + /; loop (r > 0) [r = r - 1] + ;m = m.parent + ;/ + ;return m`._find_mod(artifact, 0) + ;/ + + /; find_mod({}{}uint8 artifact) [~Module] + ;return self._find_mod(artifact, 0) + ;/ + /; find_sub ({}uint8 s_mod) [~Module] ;{}uint8 v1 = string_add("_#", s_mod) ;{}uint8 v2 = string_add("__#", s_mod) @@ -879,6 +1017,12 @@ ;return out ;/ +/; is_call(~{}Token tok, ~int cur) [bool] + ;int i = cur` + ;get_artifact(tok, cur) + ;return tok`{cur`}.cmp("(") +;/ + /; get_type (~{}Token tok, ~int cur, ~Module current) [Type] ;{}int ptr_chain = {} @@ -917,7 +1061,7 @@ /; is_definition (~{}Token tok, ~int cur, ~Module current) [bool] ;int i = cur` ;Type t = get_type(tok, ~i, current) - ;return tok`{i}.type_is(TOKEN.DEFWORD) + ;return tok`{i}.type_is(TOKEN.DEFWORD) && !string_equate(t.name, "") ;/ /; compile_file_def (~{}Token tok, ~int cur, ~Module current, ~CompData out) @@ -989,9 +1133,15 @@ /; new_type (~{}Token tok, ~int cur, ~Module current) ;cur`++ ;Type out = {0, tok`{cur`}.data, "", {}, {}} - ;out.mod_name = string_add(current`.full_path(), "_#") + + ;out.mod_name = current`.full_path() + /; if (len (out.mod_name) > 0) + ;out.mod_name.append('.') + ;/ + ;out.mod_name = string_add(out.mod_name, "_#") ;out.mod_name = string_add(out.mod_name, out.name) - ;current`.sub.append({current, current`.exp, out.mod_name, {}, {}, {}, {}}) + + ;current`.sub.append({current, current`.exp, string_add("_#", out.name), {}, {}, {}, {}}) /; loop (cur` < len tok`) [cur`++] /; if (tok`{cur`}.cmp("{")) @@ -1237,16 +1387,115 @@ ;/ ;/ -/; _eval_value(~{}Token tok, int start, int max, ~CompData out, ~Module current, ~Scope scope) - ;int first = -1, priority = 9999 +# Priority +# 0 - deref +# 1 - get +# 2 - ref +# 3 - mul/div/mod +# 4 - add/sub +# 5 - bitwise +# 6 - boolean +# 7 - assignment +/; priority (Token tok) [int] + /; if (!(tok.type_is(TOKEN.AUGMENT))) + ;return 999 + ;/ + + /; if (tok.cmp(".")) + ;return 1 + ;; else if (len (tok.data) == 1) + /; if (tok.cmp("`")) + ;return 0 + ;; else if (tok.cmp("~")) + ;return 2 + ;; else if (tok.cmp("*") || tok.cmp("/") || tok.cmp("%")) + ;return 3 + ;; else if (tok.cmp("-") || tok.cmp("+")) + ;return 4 + ;; else if (tok.cmp("&") || tok.cmp("|") || tok.cmp("^") || tok.cmp("!")) + ;return 5 + ;; else if (tok.cmp("<") || tok.cmp(">")) + ;return 6 + ;; else if (tok.cmp("=")) + ;return 7 + ;/ + ;; else if (len (tok.data) == 2) + /; if (tok.data{0} == tok.data{1}) + /; if (tok.data{0} == '<' || tok.data{0} == '>') + ;return 5 + ;/ + ;return 6 + ;; else if (tok.data{1} == '=') + ;return 7 + ;; else if (tok.data{1} == '<' || tok.data{1} == '>') + ;return 6 + ;/ + ;return 5 + ;; else if (len (tok.data) == 3) + ;return 6 + ;/ + + ;return 999 +;/ + +/; _eval_dot (~{}Token tok, int start, ~CompData out, ~Module current, ~Scope scope, Type t, int loc) [Variable] + ;Variable wk = scope.find_var(get_artifact(tok, ~start), current) + ;Variable refer = {"#tmp", wk.data_type, loc, LOCATION.REGISTER} + + /; loop (start < len tok`) [start++] + /; if (tok`{start}.cmp("`")) + ;wk.deref(out) + ;; else if (tok`{start}.cmp(".") && tok`{start + 1}.type_is(TOKEN.DEFWORD)) + ;wk = wk.get() + ;start++ + ;/ + ;/ +;/ + +/; _eval_call (~{}Token tok, int start, max, ~CompData out, ~Module current, ~Scope scope, Type t) [Variable] + +;/ + +# FIXME: +# Need to impliment in place solving +# Need to impliment auto typing +/; _eval_value(~{}Token tok, int start, max, ~CompData out, ~Module current, ~Scope scope, Type t) [Variable] + ;int first = -1, pr = -1, pa = -1 /; loop (int i = start; i < max) [i++] - /; if (tok`{i}.type_is(TOKEN.AUGMENT)) + /; if (tok`{i}.type_is(TOKEN.AUGMENT) && priority(tok`{i}) !< pr) + ;first = i + ;pr = priority(tok`{i}) + ;; else if (tok`{i}.cmp("(")) + ;pa = i + ;i = find_closing(tok, ~i) + ;/ + ;/ + + ;return {"", NO_TYPE, 0, 0} + # This is all kinda garbage, to fix. + /; if (pr == 0 || pr == 1) + /; if (pa > 0 && tok`{max - 1}.cmp(")")) + ;return _eval_call(tok, start, max, out, current, scope, t, loc) ;/ + ;return _eval_dot(tok, start, out, current, scope, t, loc) + ;/ + + ;loc = loc % 8 + + ;Type s1, s2 + /; if (first == start) + ;s1 = _eval_value(tok, first + 1, max, out, current, scope, NO_TYPE, loc) + ;; else if (first == max - 1) + ;s1 = _eval_value(tok, start, first, out, current, scope, NO_TYPE, loc) + ;; else + ;s1 = _eval_value(tok, start, first, out, current, scope, NO_TYPE, loc) + ;s1 = _eval_value(tok, first + 1, max, out, current, scope, NO_TYPE, loc + 1) ;/ ;/ -/; eval_value (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope) +# ALWAYS put the value in rax +/; eval_value (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope, Type t) ;int end = cur` /; loop (end < len tok`) [end++] /; if (tok`{end}.cmp(",") || tok`{end}.cmp("\n") || tok`{end}.cmp(";") || tok`{end}.cmp(";/")) @@ -1255,27 +1504,45 @@ ;end = find_closing(tok, ~end) ;/ ;/ - ;_eval_value(tok, cur`, end, out, current, scope) + ;_eval_value(tok, cur`, end, out, current, scope, t) ;cur` = end ;/ +# FIXME: +# Need to find type of definition, then add all definitions to the current scope, while evaluating the +# Value (if any) to store in them /; eval_def (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope) + ;Type t = get_type(tok, cur, current) + /; loop (tok`{cur`}.type_is(TOKEN.DEFWORD)) + ;scope`.new_var(t, tok`{cur`}.data, out) + ;eval_value(tok, cur, out, current, scope, t) + /; if (tok`{cur`}.cmp(",")) + ;cur` = next_non_nl(tok, cur` + 1) + ;/ + ;/ ;/ -# TODO: -/; compile_function (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope scope) - -;/ - -# TODO: -/; compile_method (~{}Token tok, ~int cur, ~CompData out, ~Module current, ~Scope parent) +/; statement_list(~{}Token tok, int start, end, ~Module current, ~CompData out, ~Scope parent) ;/ +# FIXME: +# Need to impl: +# cf block scoping and contextual keywords such as +# continue, break, and return /; _compile_block (~{}Token tok, ~int cur, ~Module current, ~CompData out, ~Scope parent) ;int max = find_closing(tok, cur) - /; loop () - + ;Scope cf = parent` + /; loop (cur`++; cur` < max) [cur`++] + /; if (tok`{cur`}.type_is(TOKEN.KEYWORD)) + ;cf = parent`.new_sub_cf(tok`{cur`}.data) + ;; else if (tok`{cur`}.cmp("(") || tok`{cur`}.cmp("[")) + ;int psl = find_closing(tok, cur) + ;statement_list(tok, cur`, psl, current, out, ~cf) + ;cur` = psl + ;; else + ;break + ;/ ;/ /; loop (cur`++; cur` < max) [cur`++] @@ -1283,48 +1550,59 @@ ;/ /; compile_block (~{}Token tok, ~int cur, ~Module current, ~CompData out) - ;Scope root = {0, "", {}} + ;Scope root = {{}, 0, 0, "", {}} ;int max = find_closing(tok, cur) - ;bool r = false, m = false + ;bool r = false, m = false, returned = false + ;Type ret = NO_TYPE /; loop (cur`++; cur` < max && !m) [cur`++] /; if (tok`{cur`}.type_is(TOKEN.DEFWORD)) ;root.name = tok`{cur`}.data ;; if (tok`{cur`}.type_is(TOKEN.KEYWORD)) /; if (tok`{cur`}.cmp("raw")) ;r = true - ;; if (tok`{cur`}.cmp("method")) + ;; else if (tok`{cur`}.cmp("method")) ;m = true + ;tnsl.io.println(tok`{cur` + 1}.data) + ;tnsl.io.println(current`.sub{0}.name) ;current = current`.find_sub(tok`{cur` + 1}.data) + ;; else + ;tnsl.io.print("Keyword ") + ;tnsl.io.print(tok`{cur`}.data) + ;tnsl.io.println(" not impl on mod level blocks") + ;tok`{e}.cmp() ;/ ;; if (tok`{cur`}.cmp("(")) - ;{}Variable init = parse_param_list(tok, cur, current) - ;root.initialize(init) + ;root.vars = parse_param_list(tok, cur, current) ;; if (tok`{cur`}.cmp("[")) - ;cur` = find_closing(tok, cur) + ;ret = get_type(tok, cur, current) ;; if (tok`{cur`}.cmp("\n")) ;break ;/ ;/ - ;{}uint8 l = "" - /; if (!string_equate(current`.name, "")) - ;l = string_add(l, current`.full_path()) - ;l.append('.') - ;/ - ;l = string_add(l, root.name) - /; if (current`.exp) - ;out`.hsec = string_add(out`.hsec, "global ") - ;out`.hsec = string_add(out`.hsec, l) - ;out`.hsec.append('\n') - ;/ - ;out`.csec = string_add(out`.csec, l) - ;out`.csec = string_add(out`.csec, ":\n") + /; if (!m) + ;{}uint8 l = "" + /; if (!string_equate(current`.name, "")) + ;l = string_add(l, current`.full_path()) + ;l.append('.') + ;/ + ;l = string_add(l, root.name) + ;root.name = l + + /; if (current`.exp) + ;out`.hsec = string_add(out`.hsec, "global ") + ;out`.hsec = string_add(out`.hsec, l) + ;out`.hsec.append('\n') + ;/ + ;out`.csec = string_add(out`.csec, l) + ;out`.csec = string_add(out`.csec, ":\n") - /; if (!r) - ;root.begin_scope(out) + /; if (!r) + ;root.begin_scope(out) + ;/ ;/ - /; loop (cur` = next_non_nl(tok, cur` + 1); cur` < max) [cur` = next_non_nl(tok, cur` + 1)] + /; loop (cur` = next_non_nl(tok, cur` + 1); cur` < max && !returned) [cur` = next_non_nl(tok, cur` + 1)] /; if (tok`{cur`}.cmp("/;") || tok`{cur`}.cmp(";;")) /; if (m) ;compile_block(tok, cur, current, out) @@ -1336,10 +1614,21 @@ ;cur` = cur` - 1 ;/ ;; else if (tok`{cur`}.type_is(TOKEN.KEYWORD)) - ;tnsl.io.println(tok`{cur`}.data) /; if (tok`{cur`}.cmp("return")) ;cur`++ - ;eval_value(tok, cur, out, current, ~root) + ;eval_value(tok, cur, out, current, ~root, ret) + ;root.end_scope(out) + ;out`.csec = string_add(out`.csec, "\tret\n") + ;returned = true + ;; else if (tok`{cur`}.cmp("raw") && tok`{cur` + 1}.cmp("return")) + /; if (!r) + ;tnsl.io.println("Unable to perform a raw return from a non-raw block.") + ;tok`{e}.cmp() + ;/ + ;cur` = cur` + 2 + ;eval_value(tok, cur, out, current, ~root, ret) + ;out`.csec = string_add(out`.csec, "\tret\n") + ;returned = true ;; else if (tok`{cur`}.cmp("asm")) ;cur`++ ;out`.csec.append('\t') @@ -1352,14 +1641,23 @@ ;; else if (is_definition(tok, cur, current)) ;eval_def(tok, cur, out, current, ~root) ;; else - ;eval_value(tok, cur, out, current, ~root) + ;eval_value(tok, cur, out, current, ~root, NO_TYPE) ;/ ;/ - /; if (!r) - ;root.end_scope(out) + ;cur` = max + + /; if (!returned && !string_equate(ret.name, "")) + ;tnsl.io.println("Block must return a value.") + ;tok`{e}.cmp() + ;/ + + /; if (!m && !returned) + /; if (!r) + ;root.end_scope(out) + ;/ + ;out`.csec = string_add(out`.csec, "\tret\n") ;/ - ;out`.csec = string_add(out`.csec, "\tret\n") ;/ # First pass on a module -- cgit v1.2.3