From 6e5d990783caf5630fe75d847b8f7f5559bf5e94 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sat, 25 Mar 2023 14:43:01 -0400 Subject: Pre-generate function signatures in modules --- tnslc/simple.tnsl | 22 ++++++- tnslc/tnslc.tnsl | 185 +++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 174 insertions(+), 33 deletions(-) diff --git a/tnslc/simple.tnsl b/tnslc/simple.tnsl index d871e92..d996c1b 100644 --- a/tnslc/simple.tnsl +++ b/tnslc/simple.tnsl @@ -2,17 +2,35 @@ {}uint8 str1 = "abcd" {}uint8 str2 = "abcd" +/; method Test + /; wamba + ;/ +;/ + +struct Test { + int i, j, k +} + /; call_me [int] return 4 ;/ /; main (int argc, ~~uint argv) [int] # On windows, the first two arguments are passed in RCX and RDX, so we need to - # update their positions here or else tnsl willhave garbage values in r8 and r9 + # update their positions here or else tnsl will have garbage values in r8 and r9 asm "mov r8, rcx" asm "mov r9, rdx" # If on linux, you would use rdi and rsi instead of rcx and rdx, respectively + Test m + ~int i = ~m.i + i{1} = 3 + + /; if (argc > 8) + argc = 90 + ;/ + + call_me() # return the number of arguments - return argc + return m.j ;/ diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl index 9eee55a..467b061 100644 --- a/tnslc/tnslc.tnsl +++ b/tnslc/tnslc.tnsl @@ -1545,7 +1545,7 @@ ;/ ;{}uint8 moves = string_join( { - "lea rsi, [rbp]\n" + "\tlea rsi, [rbp]\n" }, "") # Move extra variables @@ -1556,31 +1556,31 @@ ;accum = accum + sz ;self.vars{i}.location = accum /; if (len (self.vars{i}.data_type.ptr_chain) > 0) - ;moves.csec = string_join( { - moves.csec, + ;moves = string_join( { + moves, "\tmov rdi, qword [rsi]\n", "\tmov qword [rbp - ", int_to_string(accum), "], rdi\n", "\tadd rsi, 8\n" }, "") ;; else if (self.vars{i}.is_prim()) - ;moves.csec = string_join( { - moves.csec, + ;moves = string_join( { + moves, "\tmov ", get_reg(5, sz), ", ", mov_by_size(sz), "[rsi]\n", "\tmov ", mov_by_size(sz), "[rbp - ", int_to_string(accum), "], ", get_reg(5, sz),"\n", "\tadd rsi, ", int_to_string(sz), "\n" }, "") ;; else - ;moves.csec = string_join( { - moves.csec, + ;moves = string_join( { + moves, "\tlea rdi, [rbp - ", int_to_string(accum), "]\n", - "\tmov rcx", int_to_string(sz), "\n", + "\tmov rcx, ", int_to_string(sz), "\n", "\tmovsb\n", "\tadd rsi, ", int_to_string(sz), "\n" }, "") ;/ ;/ ;/ - + /; if (accum > 80 && !(self.r)) ;out`.csec = string_add(out`.csec, moves) ;/ @@ -1744,7 +1744,8 @@ {}uint8 name, {}Type inputs, - outputs + Type + output } ;struct Module { @@ -1848,15 +1849,15 @@ ;return self._find_def(artifact, 0) ;/ - /; _find_function ({}{}uint8 artifact, int r) [Variable] + /; _find_function ({}{}uint8 artifact, int r) [Function] /; if (len artifact !> r) - ;retirn {{}, "", 0, 0, 0} + ;return {"", {}, {}} ;/ /; 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._find_type(artifact, r + 1) + ;return self._find_function(artifact, r + 1) ;/ ;/ ;/ @@ -1867,7 +1868,7 @@ ;/ ;/ - ;return {{}, "", 0, 0, 0} + ;return {"", {}, {}} ;/ /; find_function ({}{}uint8 artifact) [Variable] @@ -1968,6 +1969,31 @@ ;return false ;/ +/; pre_get_type (~{}Token tok, ~int cur) [Type] + ;{}int ptr_chain = {} + + /; loop (cur` < len tok`) [cur`++] + /; if (tok`{cur`}.cmp("{")) + ;ptr_chain.append(PTYPE.ARRAY) + ;cur`++ + ;; else if (tok`{cur`}.cmp("~")) + ;ptr_chain.append(PTYPE.POINTER) + ;; else + ;break + ;/ + ;/ + + ;{}uint8 a = string_join(get_artifact(tok, cur), ".") + ;Type out = {0, a, "", ptr_chain, {}} + + /; if (tok`{cur`}.cmp("`")) + ;out.ptr_chain.append(PTYPE.REFERENCE) + ;cur`++ + ;/ + + ;return out +;/ + /; get_type (~{}Token tok, ~int cur, ~Module current) [Type] ;{}int ptr_chain = {} @@ -1998,6 +2024,10 @@ ;/ # TODO: References + /; if (tok`{cur`}.cmp("`")) + ;ptr_chain.append(PTYPE.REFERENCE) + ;cur`++ + ;/ ;out.ptr_chain = ptr_chain ;return out @@ -2055,6 +2085,28 @@ ;return c ;/ +/; pre_parse_params (~{}Token tok, ~int cur) [{}Type] + ;{}Type out = {} + + ;int max = find_closing(tok, cur) + + ;Type t = NO_TYPE + /; loop (cur` = next_non_nl(tok, cur` + 1); cur` < max) [cur` = next_non_nl(tok, cur` + 1)] + ;int nnl = next_non_nl(tok, cur` + 1) + /; if (tok`{nnl}.cmp(",") || nnl == max) + ;out.append(t) + /; if (tok`{nnl}.cmp(",")) + ;cur`++ + ;/ + ;; else + ;t = pre_get_type(tok, cur) + ;cur` = cur` - 1 + ;/ + ;/ + + ;return out +;/ + /; parse_param_list (~{}Token tok, ~int cur, ~Module current) [{}Variable] ;{}Variable out = {} @@ -2075,19 +2127,39 @@ ;return out ;/ +/; find_or_create ({}uint sub_name, ~Module current, bool exp) [~Module] + /; if (!(string_equate(current`.find_sub(sub_name)`.name, current`.name))) + ;return current`.find_sub(sub_name) + ;/ + ;Module out = {current, exp, "", {}, {}, {}, {}} + + + ;out.name = current`.full_path() + /; if (len (out.name) > 0) + ;out.name.append('.') + ;/ + ;out.name = string_add(out.name, sub_name) + + + ;current`.sub.append(out) + ;return current`.find_sub(sub_name) +;/ + # Generates new type /; new_type (~{}Token tok, ~int cur, ~Module current) ;cur`++ - ;Type out = {0, tok`{cur`}.data, "", {}, {}} - ;out.mod_name = current`.full_path() - /; if (len (out.mod_name) > 0) - ;out.mod_name.append('.') + /; if (tok`{cur`}.tokenType !== TOKEN.DEFWORD) + ;log_err(string_join( { + "Unexpected token type at ", tok`{cur`}.sprint(), " The struct keyword should be followed by an identifier." + }, "")) ;/ - ;out.mod_name = string_add(out.mod_name, "_#") - ;out.mod_name = string_add(out.mod_name, out.name) - ;current`.sub.append({current, current`.exp, string_add("_#", out.name), {}, {}, {}, {}}) + ;Type out = {0, tok`{cur`}.data, "", {}, {}} + + ;{}uint8 mod_name = string_add("_#", out.name) + ;find_or_create(mod_name, current, current`.exp) + ;out.mod_name = mod_name /; loop (cur` < len tok`) [cur`++] /; if (tok`{cur`}.cmp("{")) @@ -2104,6 +2176,37 @@ ;current`.types.append(out) ;/ +/; new_function (~{}Token tok, ~int cur, ~Module current) + ;{}Type inputs = {} + ;Type output = NO_TYPE + + ;int max = find_closing(tok, cur) + ;cur`++ + + /; if (tok`{cur`}.tokenType !== TOKEN.DEFWORD) + ;log_err(string_join( { + "Unexpected token type at ", tok`{cur`}.sprint(), " The struct keyword should be followed by an identifier." + }, "")) + ;/ + + ;{}uint8 name = tok`{cur`}.data + ;cur`++ + + /; loop (cur` < max) [cur`++] + /; if (tok`{cur`}.cmp("(")) + ;inputs = pre_parse_params(tok, cur) + ;; else if (tok`{cur`}.cmp("[")) + ;cur`++ + ;output = pre_get_type(tok, cur) + ;; else + ;break + ;/ + ;/ + + ;cur` = max + ;current`.functions.append( {name, inputs, output} ) +;/ + /; decompose_empty (Type t) [{}uint8] /; if (len (t.ptr_chain) > 0) ;return "\tdq 0\n" @@ -2433,7 +2536,7 @@ /; if (string_equate(wk.name, "")) ;log_err(string_add("Unable to find variable within artifact ", string_join(art, "."))) ;/ - ;log_info(string_add("Found ", wk.sprint())) + ;log_debug(string_add("Found ", wk.sprint())) ;return wk ;/ @@ -3125,35 +3228,53 @@ # Generates structs, enums, and submodules /; module_pass_one (~{}Token tok, ~int cur, ~Module current, Path f) ;int max = find_closing(tok, cur) - ;Module new = {current, false, "", {}, {}, {}, {}} + ;{}uint8 name = "" + ;bool exp = false /; loop (cur`++; cur` < len tok`) [cur`++] /; if (tok`{cur`}.type_is(TOKEN.DEFWORD)) - ;new.name = tok`{cur`}.data + ;name = tok`{cur`}.data ;; else if (tok`{cur`}.cmp("export")) - ;new.exp = true + ;exp = true + ;; else if (tok`{cur`}.cmp("method")) + ;exp = current`.exp + /; if (len name > 0) + ;name = string_add("_#", name) + ;; else if (tok`{cur` + 1}.type_is(TOKEN.DEFWORD)) + ;cur`++ + ;name = string_add("_#", tok`{cur`}.data) + ;; else + ;log_err(string_add("Tried to find name for method block, but there wasn't one nearby. ", tok`{cur`}.sprint())) + ;/ ;; else if (!(tok`{cur`}.cmp("module"))) ;break ;/ ;/ + /; if (len name == 0) + ;log_err(string_add("Did not find name for module or pethod block. ", tok`{cur`}.sprint())) + ;/ + + ;~Module new = find_or_create(name, current, exp) + /; loop (cur` < max) [cur`++] ;log_vis(".") /; if (tok`{cur`}.cmp(":")) ;log_debug("INCLUDE") /; if (tok`{cur` + 2}.type_is(TOKEN.LITERAL)) - ;compile_file_pass_one(f.relative(unquote_str(tok`{cur` + 2}.data)), ~new) + ;compile_file_pass_one(f.relative(unquote_str(tok`{cur` + 2}.data)), new) ;cur` = cur` + 2 ;/ ;continue ;; else if (tok`{cur`}.cmp("/;") || tok`{cur`}.cmp(";;")) - /; if (tok`{cur` + 1}.cmp("export") || tok`{cur` + 1}.cmp("module")) - ;module_pass_one(tok, cur, ~new, f) + /; if (tok`{cur` + 1}.cmp("export") || tok`{cur` + 1}.cmp("module") || tok`{cur` + 1}.cmp("method")) + ;module_pass_one(tok, cur, new, f) + ;; else + ;new_function(tok, cur, new) ;/ ;; else if (tok`{cur`}.cmp("struct")) - ;new_type(tok, cur, ~new) + ;new_type(tok, cur, new) ;/ ;/ - ;current`.sub.append(new) ;/ # Second pass on a module @@ -3218,8 +3339,10 @@ ;/ ;continue ;; else if (tok{i}.cmp("/;") || tok{i}.cmp(";;")) - /; if (tok{i + 1}.cmp("export") || tok{i + 1}.cmp("module")) + /; if (tok{i + 1}.cmp("export") || tok{i + 1}.cmp("module") || tok{i + 1}.cmp("method")) ;module_pass_one(~tok, ~i, current, f) + ;; else + ;new_function(~tok, ~i, current) ;/ ;; else if (tok{i}.cmp("struct")) ;new_type(~tok, ~i, current) -- cgit v1.2.3