From 9066d5215225a32865cb628dad1c69997efffe62 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Thu, 23 Mar 2023 01:03:28 -0400 Subject: Simple if and loop statements --- tnslc/simple.tnsl | 13 ++- tnslc/tnslc.tnsl | 307 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 224 insertions(+), 96 deletions(-) diff --git a/tnslc/simple.tnsl b/tnslc/simple.tnsl index 4b34340..1d9bd30 100644 --- a/tnslc/simple.tnsl +++ b/tnslc/simple.tnsl @@ -20,10 +20,13 @@ mod.test sv = { } /; main [int] - ~int j = ~sv.i - int i = mod.arr_i{j` - 1} - /; if (1 == 1) - return i + ~uint8 i = ~mod.str{0} + bool b = i` > i` + /; loop (i` < 81) + i` = i` + 2 + /; if (i` == 80) + i` = i` + 5 + ;/ ;/ - return 0 + return i` ;/ diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl index 12abbec..1054d7b 100644 --- a/tnslc/tnslc.tnsl +++ b/tnslc/tnslc.tnsl @@ -304,16 +304,6 @@ ;return string_add(out, self.name) ;/ - /; extension [{}uint8] - ;{}{}uint8 split_name = string_split(self.name, '.') - - /; if (len split_name > 1) - ;return split_name{len split_name - 1} - ;/ - - ;return "" - ;/ - /; open_read [tnsl.io.File] ;return tnsl.io.readFile(self.full_path()) ;/ @@ -568,8 +558,42 @@ ;return out ;/ +/; to_jmp({}uint8 cmp) [{}uint8] + /; if (string_equate(cmp, "==")) + ;return "\tje " + ;; else if (string_equate(cmp, "!==")) + ;return "\tjne " + ;; else if (string_equate(cmp, "!<") || string_equate(cmp, ">==")) + ;return "\tjge " + ;; else if (string_equate(cmp, "!>") || string_equate(cmp, "<==")) + ;return "\tjle " + ;; else if (string_equate(cmp, ">")) + ;return "\tjg " + ;; else if (string_equate(cmp, "<")) + ;return "\tjl " + ;/ + ;return "\tjnz " +;/ + +/; not_jmp({}uint8 cmp) [{}uint8] + /; if (string_equate(cmp, "==")) + ;return "\tjne " + ;; else if (string_equate(cmp, "!==")) + ;return "\tje " + ;; else if (string_equate(cmp, "!<") || string_equate(cmp, ">==")) + ;return "\tjl " + ;; else if (string_equate(cmp, "!>") || string_equate(cmp, "<==")) + ;return "\tjg " + ;; else if (string_equate(cmp, ">")) + ;return "\tjle " + ;; else if (string_equate(cmp, "<")) + ;return "\tjge " + ;/ + ;return "\tjz " +;/ + # Methods on variables assume that the rax, rdx, rsi, and rdi registers are fair game. -# +# ONLY USES RDI ON SOME ASSIGNMENTS. SAFE FOR BOOLEAN STORAGE /; method Variable /; sprint [{}uint8] @@ -611,8 +635,30 @@ /; match_types (Variable to_match, ~CompData data) [Variable] /; if (to_match.loc_type == LOCATION.LITERAL) ;return to_match + ;; if (!(to_match.is_prim()) || (len(to_match.data_type.ptr_chain) > 0 && !(to_match.is_ref()))) + ;return to_match + ;/ + + ;Variable out = {"#match", self.data_type, 4, LOCATION.REGISTER} + ;{}uint8 mov = "mov" + + /; if (self.data_type.name{0} == 'i' && out.norm_size() > to_match.norm_size()) + ;mov = string_add(mov, "sx") + /; if (out.norm_size() == 8 && to_match.norm_size() == 4) + ;mov.append('d') + ;/ + ;; else if (self.data_type.name{0} == 'u' && out.norm_size() > to_match.norm_size() && out.norm_size() !== 8) + ;mov = string_add(mov, "zx") + ;; else + ;return to_match ;/ - ;return to_match + + ;data`.csec = string_join( { + data`.csec, + "\t", mov, " ", out.norm_loc(out.norm_size()), ", ", to_match.norm_loc(to_match.norm_size()), "\n" + }, "") + + ;return out ;/ /; norm_op ({}uint8 op, int sz, Variable v, ~CompData data) @@ -728,7 +774,7 @@ ;self.location = !v.location ;; else if (string_equate(v.data_type.name, "bool") && len (v.data_type.ptr_chain) == 0) - ;self.xor({"#literal", get_primitive(is_primitive("bool")), 1, LOCATION.LITERAL}, data) + ;self.xor(literal_variable("true", "", data), data) ;; else ;v = self.match_types(v, data) ;self.set(v, data) @@ -746,8 +792,8 @@ ;; else ;self.location = 0 ;/ - ;; else - ;self.norm_op("add", self.norm_size(), v, data) + ;; else if (v.is_prim() && self.is_prim()) + ;self.norm_op("cmp", self.norm_size(), v, data) ;/ ;/ @@ -871,8 +917,25 @@ ;/ ;/ + # Only to be called from a boolean variable + /; bool_from (Variable v, ~CompData data, {}uint8 landing_pad) + ;int sz = v.norm_size() + ;data`.csec = string_join( { + data`.csec, + "\tmov ", get_reg(4, sz), ", ", v.norm_loc(sz), "\n", + "\ttest ", get_reg(4, sz), ", ", get_reg(4, sz), "\n", + "\tmov ", self.norm_loc(1), ", 1\n", + "\tjnz ", skip_pad, "\n", + "\tmov ", self.norm_loc(1), ", 0\n", + landing_pad, ":\n" + }, "") + ;/ + /; move_register (int new_reg, ~CompData data) ;int sz = self.norm_size() + /; if (self.is_ref()) + ;sz = 8 + ;/ ;data`.csec = string_join( { data`.csec, "\tmov ", get_reg(new_reg, sz), ", ", get_reg(self.location, sz), "\n" @@ -945,12 +1008,12 @@ }, "") ;/ - ;Variable t = {"#tmp", get_primitive(is_primitive("uint")), 5, LOCATION.REGISTER} + ;Variable t = {"#tmp", get_primitive(is_primitive("uint")), 0, LOCATION.REGISTER} ;t.set({"#literal", t.data_type, sz, LOCATION.LITERAL}, data) ;t.mul(i, data) ;data`.csec = string_join( { data`.csec, - "\tadd rsi, rdi\n" + "\tadd rsi, rax\n" }, "") /; if (out.is_ref()) @@ -1257,10 +1320,7 @@ ;/ /; next_const [{}uint8] - /; if (self.is_cf()) - ;return self.parent`.next_const() - ;/ - ;{}uint8 out = string_add(self.name, string_add("#const_", int_to_string(self.c))) + ;{}uint8 out = string_add(self.full_label(), string_add("#const_", int_to_string(self.c))) ;self.c++ ;return out ;/ @@ -1870,8 +1930,9 @@ # 3 - mul/div/mod # 4 - add/sub # 5 - bitwise -# 6 - boolean -# 7 - assignment +# 6 - boolean cmp +# 7 - boolean logic +# 8 - assignment /; priority (Token tok) [int] /; if (!(tok.type_is(TOKEN.AUGMENT))) ;return -1 @@ -1893,16 +1954,18 @@ ;; else if (tok.cmp("<") || tok.cmp(">")) ;return 6 ;; else if (tok.cmp("=")) - ;return 7 + ;return 8 ;/ ;; else if (len (tok.data) == 2) /; if (tok.data{0} == tok.data{1}) /; if (tok.data{0} == '<' || tok.data{0} == '>') ;return 5 + ;; else if (tok.data{0} == '=') + ;return 6 ;/ - ;return 6 - ;; else if (tok.data{1} == '=') ;return 7 + ;; else if (tok.data{1} == '=') + ;return 8 ;; else if (tok.data{1} == '<' || tok.data{1} == '>') ;return 6 ;/ @@ -2121,19 +2184,6 @@ ;/ ;/ - # TODO: Boolean logic - /; if (pr == 6) - # create a boolean scope - /; if (!scope.is_cf() || !scope.cf_type("bool")) - ;Scope bsc = scope`.new_sub_cf("bool") - ;scope = ~bsc - # do some kinda boolean magic - # create an end clause as a landing pad for the result - ;; else - # boolean magic but without the end clause - ;/ - ;/ - # This is all kinda garbage, to fix. /; if (is_call(tok, start)) ;log_debug("Attempt to invoke a call") @@ -2173,6 +2223,28 @@ ;wk.location = 2 ;/ + # TODO: Boolean logic + /; if (pr == 6) + ;wk.set(s1, out) + ;wk.cmp(s2, out) + ;wk.data_type = {1, "bool", "_bool", {}, {}} + + ;wk.set(literal_variable("true", "", out), out) + ;{}uint8 l = scope`.next_const() + # ;log_debug(l) + ;out`.csec = string_join( { + out`.csec, + to_jmp(tok`{first}.data), l, "\n" + }, "") + ;wk.set(literal_variable("false", "", out), out) + ;out`.csec = string_join( { + out`.csec, + l, ":\n" + }, "") + + ;return wk + ;/ + /; if (tok`{first}.cmp("+")) ;wk.set(s1, out) ;wk.add(s2, out) @@ -2226,14 +2298,13 @@ ;end = find_closing(tok, ~end) ;/ ;/ - ;Variable val = _eval_value(tok, cur`, end, out, mov, current, scope, t, false) + ;cur` = end /; if (save) ;Variable set = {"#tmp", t, 0, LOCATION.REGISTER} ;set.set(val, out) ;return val ;/ - ;cur` = end ;return { "", NO_TYPE, 0, 0 } ;/ @@ -2255,7 +2326,7 @@ ;int i = start /; loop (i < max) [i++] /; if (tok`{i}.type_is(TOKEN.AUGMENT)) - /; if (priority(tok`{i}) == 6) + /; if (priority(tok`{i}) == 6 || priority(tok`{i}) == 7) ;return true ;/ ;; else if (tok`{i}.type_is(TOKEN.LITERAL)) @@ -2282,47 +2353,53 @@ ;/ -/; statement_list(~{}Token tok, int start, end, ~Module current, ~CompData out, mov, ~Scope parent) [CompData] +/; statement_list(~{}Token tok, int start, end, ~Module current, ~CompData out, mov, ~Scope parent) [{}uint8] ;log_debug("Statement list!") - ;bool b = false + ;int b = -1 ;CompData carry = {"", "", ""} - /; loop (start = next_non_nl(tok, start + 1); start < end) [start = next_non_nl(tok, start + 1)] + ;int s = next_non_nl(tok, start + 1) + /; loop (s < end) [s = next_non_nl(tok, s + 1)] ;out`.add(carry) ;carry = {"", "", ""} - ;b = false - /; if (is_definition(tok, ~start, current)) + ;b = -1 + /; if (is_definition(tok, ~s, current)) + ;log_debug("Block def") - ;eval_def(tok, ~start, out, mov, current, parent) + ;eval_def(tok, ~s, out, mov, current, parent) ;; else ;log_debug("Block val") - ;b = is_bool_statement(tok, start, end, current, parent) + /; if (is_bool_statement(tok, s, end, current, parent)) + ;b = s + ;/ ;Type t = NO_TYPE - /; if (b) + /; if (b !< 0) ;t = {1, "bool", "_bool", {}, {}} + ;log_debug("Boolish") ;/ - ;eval_value(tok, ~start, carry, mov, current, parent, t, b) + ;eval_value(tok, ~s, out, mov, current, parent, t, b) ;/ ;/ - ;out`.add(carry) - /; if (!b) - ;carry = {"", "", ""} + + ;{}uint str = "" + + /; if (b > 0) + ;str = int_to_string(b) ;/ - ;return carry + ;return str ;/ # 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, mov, ~Scope parent) +/; _compile_block (~{}Token tok, ~int cur, ~Module current, ~CompData out, mov, ~Scope parent, Type ret) ;int max = find_closing(tok, cur) ;Scope cf = parent`.new_sub_cf("wrap") - ;CompData prelude = {"", "", ""} - ;out`.csec = string_join( { - out`.csec, - cf.scope_start_label(), ":\n" - }, "") + + ;CompData outro = {"", "", ""} + ;{}uint8 condition = "" + /; loop (cur`++; cur` < max) [cur`++] /; if (tok`{cur`}.type_is(TOKEN.KEYWORD)) /; if (tok`{cur` + 1}.cmp("if")) @@ -2334,34 +2411,48 @@ ;; else if (tok`{cur`}.cmp("(") || tok`{cur`}.cmp("[")) ;int psl = find_closing(tok, cur) /; if (tok`{cur`}.cmp("[")) - ;out`.csec = string_join( { - out`.csec, - cf.scope_end_label(), ":\n" - }, "") - ;CompData tmp = statement_list(tok, cur`, psl, current, out, mov, ~cf) - /; if (len (tmp.csec) == 0 && cf.cf_type("loop")) - ;out`.csec = string_add(out`.csec, prelude.csec) + ;outro.csec = string_add(cf.scope_rep_label(), ":\n") + ;{}uint8 tmp = statement_list(tok, cur`, psl, current, ~outro, mov, ~cf) + + /; if (cf.cf_type("loop")) + /; if (len (tmp) == 0 && len (condition) > 0) + /; if (len (condition) > 0) + ;int tmps = string_to_int(condition) + ;eval_value(tok, ~tmps, ~outro, mov, current, ~cf, {1, "bool", "", {}, {}}, true) + ;; else + ;outro.csec = string_join( { + outro.csec, + "\tjmp ", cf.scope_start_label(), "\n" + }, "") + ;/ + ;/ + + /; if (len (tmp) > 0 || len(condition) > 0) + ;outro.csec = string_join( { + outro.csec, + "\ttest al, al\n", + "\tjnz ", cf.scope_start_label(), "\n", + "\tjmp ", cf.scope_end_label(), "\n" + }, "") + ;/ ;/ - /; if (cf.is_cf()) + ;; else + ;condition = statement_list(tok, cur`, psl, current, out, mov, ~cf) + /; if (len (condition) == 0) ;out`.csec = string_join( { out`.csec, - "\tjmp ", cf.parent`.scope_end_label(), "\n" + "\tjmp ", cf.scope_start_label(), "\n" }, "") - ;/ - ;; else - ;out`.csec = string_join( { - out`.csec, - cf.scope_start_label(), ":\n" - }, "") - ;prelude = statement_list(tok, cur`, psl, current, out, mov, ~cf) - /; if (len (prelude.csec) == 0) - ;prelude.csec = string_join( { - "\tjmp ", cf.scope_rep_label(), "\n" + ;; else + ;out`.csec = string_join( { + out`.csec, + "\ttest al, al\n", + "\tjnz ", cf.scope_start_label(), "\n", + "\tjmp ", cf.scope_end_label(), "\n" }, "") - ;out`.csec = string_add(out`.csec, prelude.csec) ;/ ;/ - ;cur` = ps1 + ;cur` = psl ;; else ;break ;/ @@ -2369,7 +2460,7 @@ ;out`.csec = string_join( { out`.csec, - cf.scope_rep_label(), ":\n" + cf.scope_start_label(), ":\n" }, "") /; if (tok`{cur`}.cmp("\n")) @@ -2380,7 +2471,7 @@ /; loop (cur` < max && !returned) [cur` = next_non_nl(tok, cur` + 1)] /; if (tok`{cur`}.cmp("/;") || tok`{cur`}.cmp(";;")) ;log_debug("Block in block") - ;_compile_block(tok, cur, current, out, mov, ~cf) + ;_compile_block(tok, cur, current, out, mov, ~cf, ret) /; if (tok`{cur`}.cmp(";;")) ;cur` = cur` - 1 @@ -2388,7 +2479,7 @@ ;; else if (tok`{cur`}.type_is(TOKEN.KEYWORD)) /; if (tok`{cur`}.cmp("return")) ;cur`++ - ;eval_value(tok, cur, out, ~mov, current, ~cf, ret, true) + ;eval_value(tok, cur, out, mov, current, ~cf, ret, true) ;cf.end_scope(out) ;out`.csec = string_add(out`.csec, "\tret\n") ;returned = true @@ -2397,7 +2488,7 @@ ;log_err("Unable to perform a raw return from a non-raw block.") ;/ ;cur` = cur` + 2 - ;eval_value(tok, cur, out, ~mov, current, ~root, ret, true) + ;eval_value(tok, cur, out, mov, current, ~cf, ret, true) ;out`.csec = string_add(out`.csec, "\tret\n") ;returned = true ;; else if (tok`{cur`}.cmp("asm")) @@ -2410,12 +2501,45 @@ ;/ ;; else if (is_definition(tok, cur, current)) ;log_debug("Block def") - ;eval_def(tok, cur, out, mov, current, ~root) + ;eval_def(tok, cur, out, mov, current, ~cf) ;; else ;log_debug("Block val") - ;eval_value(tok, cur, out, mov, current, ~root, NO_TYPE, false) + ;eval_value(tok, cur, out, mov, current, ~cf, NO_TYPE, false) ;/ ;/ + ;log_debug("Passing gauntlet 2") + + /; if (len (outro.csec) > 0) + ;out`.add(outro) + ;; else + ;out`.csec = string_join( { + out`.csec, + cf.scope_rep_label(), ":\n" + }, "") + + /; if (cf.cf_type("loop")) + /; if (len (condition) > 0) + ;int tmps = string_to_int(condition) + ;eval_value(tok, ~tmps, out, mov, current, ~cf, {1, "bool", "", {}, {}}, true) + ;out`.csec = string_join( { + out`.csec, + "\ttest al, al\n", + "\tjnz ", cf.scope_start_label(), "\n", + "\tjmp ", cf.scope_end_label(), "\n" + }, "") + ;; else + ;out`.csec = string_join( { + out`.csec, + "\tjmp ", cf.scope_start_label(), "\n" + }, "") + ;/ + ;/ + ;/ + + ;out`.csec = string_join( { + out`.csec, + cf.scope_end_label(), ":\n" + }, "") /; if (cf.is_cf()) ;out`.csec = string_join( { @@ -2481,10 +2605,11 @@ ;; else ;CompData mov = {"", "", ""}, tmp = {"", "", ""} ;log_debug("PRE COMPUTATION OF BLOCK\n") - ;_compile_block(tok, cur, current, ~tmp, ~mov, ~root) + ;int tcr = cur` + ;_compile_block(tok, ~tcr, current, ~tmp, ~mov, ~root, ret) ;out`.add(mov) ;log_debug("POST COMPUTATION OF BLOCK") - ;_compile_block(tok, cur, current, out, ~tmp, ~root) + ;_compile_block(tok, cur, current, out, ~tmp, ~root, ret) ;/ /; if (tok`{cur`}.cmp(";;")) @@ -2765,7 +2890,7 @@ ;{}uint8 PARENS = "()[]{}" ;{}uint8 SEPS = "\n;:," ;{}uint8 RESERVED = "`~!%^&*()-+=[]{}|;:/?<>.,\"" -;{}uint8 AUGMENTS = "=~!<>&|^+-*/`." +;{}uint8 AUGMENTS = "=~!<>&|^+-*/%`." ;{}{}uint8 MULTI_AUGMENTS = { "~=", "`=", "%=", "^=", "&=", "*=", -- cgit v1.2.3