From 09df1bb48823631228af3df647111af1eebc854b Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Thu, 16 Feb 2023 05:14:31 -0500 Subject: Collapse tnslc into a single file --- tnslc/compile/compile.tnsl | 768 --------------------------------------------- tnslc/compile/isa_x86.tnsl | 182 ----------- tnslc/compile/value.tnsl | 362 --------------------- 3 files changed, 1312 deletions(-) delete mode 100644 tnslc/compile/compile.tnsl delete mode 100644 tnslc/compile/isa_x86.tnsl delete mode 100644 tnslc/compile/value.tnsl (limited to 'tnslc/compile') diff --git a/tnslc/compile/compile.tnsl b/tnslc/compile/compile.tnsl deleted file mode 100644 index 034304c..0000000 --- a/tnslc/compile/compile.tnsl +++ /dev/null @@ -1,768 +0,0 @@ -/## - Copyright 2021-2022 Kyle Gunger - - This file is licensed under the CDDL 1.0 (the License) - and may only be used in accordance with the License. - You should have received a copy of the License with this - software/source code. If you did not, a copy can be found - at the following URL: - - https://opensource.org/licenses/CDDL-1.0 - - THIS SOFTWARE/SOURCE CODE IS PROVIDED "AS IS" WITH NO - WARRANTY, GUARANTEE, OR CLAIM OF FITNESS FOR ANY PURPOSE - EXPRESS OR IMPLIED -#/ - - -;{}{}uint8 COMMON_ASM = { - "\tret\n" -} - -# Represents a type -;struct VType { - uint - _size, - int - ptr, - - {}uint8 name, - - {}VType sub_types, - {}{}uint8 sub_names -} - -/; method VType - /; get_sub_type({}uint8 name) [VType] - /; loop (int i = 0; i < len (self.sub_types)) [i++] - /; if (string_equate(~name, ~(self.sub_names{i}))) - ;return self.sub_types{i} - ;/ - ;/ - ;return NT - ;/ - - /; get_offset({}uint8 name) [int] - ;int out = 0 - /; loop (int i = 0; i < len (self.on_stack)) [i++] - /; if (string_equate(~name, ~(self.sub_types{i*2 + 1}))) - ;return out - ;; else if (self.on_stack{i}) - ;VType tmp = vtype_by_name(self.sub_types{i*2}) - ;out = out + tmp.size - ;/ - ;/ - ;return -1 - ;/ - - /; print - ;tnsl.io.print("Size: ") - ;tnsl.io.print(self._size) - ;tnsl.io.print(" | Ptr: ") - ;tnsl.io.print(self.ptr) - ;tnsl.io.print(" | Name: ") - ;tnsl.io.println(self.name) - ;/ -;/ - -# Tracks defined variables in a block -;struct VTrack { - {}{}uint8 - sym_names, - - {}Value - sym_vals -} - -/; method VTrack - - /; next_loc(VType vt) [int] - /; if (is_struct(vt) && vt.ptr == 0) - ;return -1 - ;/ - - ;int count = 0 - /; loop (int i = 0; i < len (self.sym_vals)) [i++] - /; if (!(self.sym_vals{i}.on_stack)) - ;count++ - ;/ - - /; if (count > 7) - ;return -1 - ;/ - ;/ - - ;return count + 6 - ;/ - - # returns with init commands - /; add_track({}uint8 name, VType _type) [{}uint8] - ;Value v = track_val(_type, to_stack, self.next_loc(_type)) - - /; if (v.loc < 0) - ;v.loc = 0 - ;/ - - ;self.sym_names.append(name) - ;self.sym_vals.append(v) - ;return v.init_val() - ;/ - - # Returns true if the variable is being tracked - /; in_vtrack({}uint8 name) [bool] - /; loop (int i = 0; i < len (self.sym_names)) [i++] - /; if (string_equate(name, self.sym_names{i})) - ;return true - ;/ - ;/ - ;return false - ;/ - - # Returns the total allocated memory on the stack for this tracker - /; stack_total [int] - ;int out = 0 - /; loop (int i = 0; i < len (self.on_stack)) [i++] - /; if (self.on_stack{i}) - ;out = out + (self.sym_vals{i}._type._size) - ;/ - ;/ - ;return out - ;/ - - # returns the type of the named variable - /; get_val ({}uint8 name) [Value] - /; loop (int i = 0; i < len (self.sym_names)) [i++] - /; if (string_equate(name, self.sym_names{i})) - ;return (self.sym_vals{i}) - ;/ - ;/ - ;/ - - # push stack updates loc for every value on the stack - /; push_stack (VType vt) [{}uint8] - ;int tsz = vt._size - /; if (vt.ptr !== 0) - ;tsz = 8 - ;/ - - /; loop (int i = 0; i < len (self.sym_vals)) [i++] - /; if (self.sym_vals{i}.on_stack) - ;self.sym_vals{i}.loc = self.sym_vals{i}.loc + tsz - ;/ - ;/ - - ;{}uint8 out = "\tsub $" - ;{}uint8 tmp = string_from_int(tsz) - ;add_strings(~out, ~tmp) - ;out.append(',') - ;out.append(' ') - ;tmp = "%rsp" - ;add_strings(~out, ~tmp) - ;return out - ;/ -;/ - -# Sizes of items -;{}VType type_table = { - {1, 0, "int8", {}, {}}, - {2, 0, "int16", {}, {}}, - {4, 0, "int32", {}, {}}, - {8, 0, "int64", {}, {}}, - {8, 0, "int", {}, {}}, - {1, 0, "uint8", {}, {}}, - {2, 0, "uint16", {}, {}}, - {4, 0, "uint32", {}, {}}, - {8, 0, "uint64", {}, {}}, - {8, 0, "uint", {}, {}}, - {4, 0, "float32", {}, {}}, - {8, 0, "float64", {}, {}}, - {8, 0, "float", {}, {}}, - {1, 0, "bool", {}, {}}, - {8, 0, "void", {}, {}} -} - -# Null type -;VType NT = {0, 0, "null", {}, {}} - -# Returns an index in the vtrack for a given variable name -/; name_to_index ({}uint8 name, ~VTrack tab) [int] - /; loop (int i = 0; i < len (tab`.sym_names)) [i++] - /; if (string_equate(tab`.sym_names{i}, name)) - ;return i - ;/ - ;/ - - ;tnsl.io.print("Failed to find vairable ") - ;tnsl.io.println(name) - - ;return -1 -;/ - -# Bool to j -/; cmp_to_jxt ({}uint8 c) [{}uint8] - /; if (string_equate(c, "<")) - ;return "l" - ;; else if (string_equate(c, ">")) - ;return "g" - ;; else if (string_equate(c, "!<") || string_equate(c, ">==")) - ;return "nl" - ;; else if (string_equate(c, "!>") || string_equate(c, "<==")) - ;return "ng" - ;; else if (string_equate(c, "==")) - ;return "e" - ;; else if (string_equate(c, "!==")) - ;return "ne" - ;/ - ;return "nz" -;/ - -# Is struct returns true if the type name given is a struct -/; is_struct (VType t) [bool] - ;VType tmp = NT - /; loop (int i = 0; i < 15) [i++] - ;tmp = tnslc.type_table{i} - /; if (string_equate(tmp.name, t.name)) - ;return false - ;/ - ;/ - - ;return true -;/ - -# Using the given offset (in bytes), return an asm value of form ".quad " -/; construct_value (int size, int offset) [{}uint8] - ;{}uint8 out = ".byte " - /; if (size == 2) - ;out = ".word " - ;; if (size == 4) - ;out = ".long" - ;; if (size == 8) - ;out = ".quad " - ;/ - ;{}uint8 tmp = string_from_int(offset) - ;add_strings(~out, ~tmp) - ;return out -;/ - -/; construct_text_value ({}uint8 t) [{}uint8] - ;{}uint8 tmp = "\n\t.ascii " - ;add_strings(~tmp, ~t) - ;return tmp -;/ - -/; construct_mov_literal({}uint8 value, reg) [{}uint8] - ;{}uint8 tmp = "$" - ;add_strings(~tmp, ~value) - ;return mov_asm(tmp, reg) -;/ - -# Parse a struct and add it to the table -/; def_struct (~int cur, ~{}Token data, ~{}uint8 dsec) [VType] - ;VType out = {0, 0, "", {}, {}} - ;cur`++ - - ;out.name = data`{cur`}.data` - - ;cur`++ - ;cur`++ - # Should be indexed at first type in the type list - - /; if (token_is(cur, data, "}")) - ;return NT - ;/ - - ;VType ctype = get_vtype(cur, data) - ;cur`++ - - /; loop (cur` < len data`) [cur`++] - /; if (token_is(cur, data, "}")) - ;break - ;; else if (token_is(cur, data, ",")) - ;cur`++ - ;/ - - ;cur`++ - /; if (token_is(cur, data, ",") || token_is(cur, data, "}")) - # Use ctype - ;cur`-- - - /; if (ctype.ptr > 0) - ;out._size = out._size + 8 - ;; else - ;out._size = out._size + ctype._size - ;/ - ;out.sub_types.append(ctype) - ;out.sub_names.append(data`{cur`}.data`) - - ;; else - # Get type - ;cur`-- - ;ctype = get_vtype(cur, data) - ;/ - ;/ - ;out.print() - ;type_table.append(out) - - ;return out -;/ - -# Checks if the current token's data member is equal to a given string -/; token_is(~int cur, ~{}Token data, {}uint8 str) [bool] - ;return string_equate(data`{cur`}.data`, str) -;/ - -# Skips in a definition or list until it finds a name -/; skip_to_name (~int cur, ~{}Token data) - ;int tmp = 0 - /; loop (cur` < len data`) [cur`++] - ;tmp = cur` + 1 - /; if (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD && - ( token_is(~tmp, data, ",") || token_is(~tmp, data, ")") || token_is(~tmp, data, "}") || token_is(~tmp, data, ";") )) - ;break - ;/ - ;/ -;/ - -# Searches the type table for a type -/; vtype_by_name ({}uint8 name) [VType] - /; loop (int i = 0; i < len type_table) [i++] - ;VType tmp = tnslc.type_table{i} - /; if (string_equate(name, tmp.name)) - ;return tmp - ;/ - ;/ - ;return NT -;/ - -# Parses a type in a definition or list -/; get_vtype (~int cur, ~{}Token data) [VType] - ;uint ptr = 0 - ;VType out = NT - - /; loop (cur` < len data`) [cur`++] - ;int i = data`{cur`}.token_type - /; if (token_is(cur, data, "~") || token_is(cur, data, "{")) - ;ptr++ - ;; else if (i == TOKEN_TYPE.DEFWORD || i == TOKEN_TYPE.KEYTYPE) - ;out = vtype_by_name(data`{cur`}.data`) - ;break - ;; else if (!token_is(cur, data, "}")) - ;break - ;/ - ;/ - - ;out.ptr = ptr - - ;return out -;/ - -# Assumes cur points to the beginning of the arguments list -# Sets up the VTrack struct that is pointed to. -/; setup_vtrack (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 csec) - ;cur`++ - - ;VType last = NT - ;Value tmp = {false, false, 0, 0, last} - - /; loop (cur` < len data`) [cur`++] - ;int pre_skip = cur` - /; if (token_is(cur, data, ")")) - - ;break - ;; else if (!token_is(cur, data, ",")) - - ;skip_to_name(cur, data) - - /; if (pre_skip !== cur`) - ;last = get_vtype(~pre_skip, data) - ;tmp._type = last - ;/ - - ;tab`.sym_names.append(data`{cur`}.data`) - ;int nloc = tab`.next_loc(last) - - ;Value store = {false, false, nloc, 0, last} - /; if (store.loc !< 0 && tmp.loc !> 5) - ;{}uint8 tstr = store.set_value(tmp) - ;add_strings(csec, ~tstr) - ;tmp.loc = tmp.loc + 1 - ;; else - ;store.loc = 0 - ;store.on_stack = true - ;tab`.push_stack(last) - ;/ - - ;tab`.sym_vals.append(store) - ;/ - ;/ -;/ - -# Mostly deals with structs and enums -/; compile_global (~int cur, ~{}Token data, ~{}uint8 hsec, csec, dsec) - ;cur`++ - /; if (token_is(cur, data, "struct")) - ;def_struct(cur, data, dsec) - ;/ -;/ - -# Evaluate a value -/; eval_value (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec, int val_layer) [Value] - /; if (token_is(cur, data, ";/")) - ;return NV - ;/ - - ;Value tmp = {false, false, val_layer % 5, 0, NT} - - /; if (val_layer > 5) - ;tmp.on_stack = true - ;/ - - /; loop (cur` < len data`) - ;tnsl.io.println("looping") - /; if (data`{cur`}.token_type == TOKEN_TYPE.LITERAL) - /; if (data`{cur`}.data`{0} == '"') - # String literal - ;tmp._type = type_table{5} - ;tmp._type.ptr = 1 - ;; else if (data`{cur`}.data`{0} == '\'') - # Char literal - ;int val = unquote_char(data`{cur`}.data`) - ;Value lit = {false, true, 0, val, type_table{5}} - ;{}uint8 tmp = out.set_value(lit) - ;add_strings(csec, ~tmp) - ;; else - # int literal - ;tnsl.io.print("int literal ") - ;tnsl.io.println(data`{cur`}.data`) - ;tmp.val = int_from_string(data`{cur`}.data`) - ;tmp.literal = true - ;tmp._type = tnslc.type_table{4} - ;cur`++ - ;tnsl.io.print("next tok ") - ;tnsl.io.println(data`{cur`}.data`) - ;/ - ;; else if (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD) - - /; if (is_call(cur, data)) - ;; else if (tab`.in_vtrack(data`{cur`}.data`)) - ;tmp = tab`.get_val(data`{cur`}.data`) - ;cur`++ - /; loop (token_is(cur, data, ".")) - ;cur`++ - ;tmp = tmp.get_member_value(data`{cur`}.data`) - ;cur`++ - ;/ - ;/ - - ;; else if (token_is(cur, data, "~")) - ;; else if (data`{cur`}.token_type == TOKEN_TYPE.AUGMENT) - - ;int acr = cur` - ;cur`++ - ;Value nxt = eval_value(cur, data, tab, hsec, csec, dsec, val_layer + 1) - ;{}uint8 code = "" - /; if (token_is(~acr, data, "=")) - ;code = tmp.set_value(nxt) - ;; if (token_is(~acr, data, "+")) - ;code = tmp.add_value(nxt) - ;; if (token_is(~acr, data, "-")) - ;tnsl.io.println("here") - ;code = tmp.sub_value(nxt) - ;; if (token_is(~acr, data, "*")) - ;code = tmp.mul_value(nxt) - ;; if (token_is(~acr, data, "/")) - ;code = tmp.div_value(nxt) - ;/ - ;add_strings(csec, ~code) - ;break - ;; else - ;break - ;/ - ;/ - ;return tmp -;/ - -/; get_function_label(~int cur, ~{}Token data) [{}uint8] - /; if (string_equate(data`{cur` + 1}.data`, "(")) - ;return data`{cur`}.data` - ;/ - - ;{}{}uint8 func_path = {} - - /; loop (cur` < len data`) [cur`++] - /; if (token_is(cur, data, "(")) - ;break - ;; else if (!token_is(cur, data, ".")) - ;func_path.append(data`{cur`}.data`) - ;/ - ;/ - ;{}uint8 out = "_." - ;{}uint8 jn_tmp = join(func_path, '.') - ;add_strings(~out, ~jn_tmp) - ;return out -;/ - -# Sets up a call and reports back where the return value is stored -/; eval_call (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec) [{}uint8] - - # Store the name of the function we are calling - ;{}uint8 to_call = get_function_label(cur, data) - ;tnsl.io.println(to_call) - # Set read head to first parameter - ;cur`++ - /; loop (!token_is(cur, data, ")")) - /; if (token_is(cur, data, ",")) - ;cur`++ - ;; else - /; if (reg < 7) - ;eval_value(cur, data, tab, hsec, csec, dsec) - ;reg++ - ;; else - ;eval_value(cur, data, tab, hsec, csec, dsec) - ;push_asm(get_reg(8, "bp")) - ;/ - ;/ - ;/ - ;cur`++ - - ;{}uint8 call_ist = call_asm(to_call) - - ;add_strings(csec, ~call_ist) - ;return "ax" -;/ - -/; is_call (~int cur, ~{}Token data) [bool] - ;bool look_def = true - /; loop (int i = cur`; i < len data`) [i++] - /; if (look_def && data`{i}.token_type == TOKEN_TYPE.DEFWORD) - ;look_def = false - ;; else if (!look_def && token_is(~i, data, ".")) - ;look_def = true - ;; else if (!look_def && token_is(~i, data, "(")) - ;return true - ;; else - ;break - ;/ - ;/ - ;return false -;/ - -# Compile a statement in a function -/; compile_statement (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec) [bool] - ;cur`++ - ;bool r = false - /; if (cur` !< len data`) - ;return false - ;/ - - /; if (token_is(cur, data, "asm")) - ;cur`++ - ;{}uint8 raw_asm = unquote_string(data`{cur`}.data`) - ;raw_asm.append('\n') - ;csec`.append('\t') - ;add_strings(csec, ~raw_asm) - ;cur`++ - ;; else if (token_is(cur, data, "raw")) - ;cur`++ - ;r = true - ;; else if (token_is(cur, data, "return")) - ;cur`++ - ;Value out = eval_value(cur, data, tab, hsec, csec, dsec, 0) - ;{}uint8 mv = out.mov_to_reg(0) - ;add_strings(csec, ~mv) - ;tail_guard(csec) - ;add_strings(csec, ~(tnslc.COMMON_ASM{0})) - ;return true - ;; else if (is_call(cur, data)) - # Function call - ;eval_call(cur, data, tab, hsec, csec, dsec) - ;; else if (tab.in_vtrack(data`{cur`}.data`)) - # set value - ;int i = name_to_index(data`{cur`}.data`, tab) - ;{}uint8 tmp = index_to_loc(i) - ;eval_value(cur, data, tab, hsec, csec, dsec) - ;tmp = mov_asm(get_reg(tab`.sym_types{i}._size, "ax"), tmp) - ;add_strings(csec, ~tmp) - ;; else - #Definition - ;VType def_t = get_vtype(cur, data) - ;cur`++ - - /; loop (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD) - ;{}uint8 init = tab`.add_track(data`{cur`}.data`, def_t) - ;add_strings(~out, ~init) - ;cur`++ - /; if (token_is(cur, data, ",")) - ;cur`++ - ;; else if (token_is(cur, data, "=")) - ;{}uint8 set = index_to_loc(len tab`.sym_names - 1, tab) - ;eval_value(cur, data, tab, hsec, csec, dsec, loc) - /; if (token_is(cur, data, ",")) - ;cur`++ - ;/ - ;; else - ;break - ;/ - ;/ - /; if (string_equate(data`{cur`+1}.data`, "=")) - ;/ - ;; if (token_is(cur, data, "return")) - ;add_strings(csec, ~(tnslc.COMMON_ASM{0})) - ;return true - ;/ - - ;return false -;/ - - - -/; compile_block (~int cur, ~{}Token data, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path, Path rel) - ;VTrack tab = { {}, {} } - ;VType out_type = tnslc.type_table{14} - ;{}uint8 name = "" - ;bool r = false - - /; loop (cur`++; cur` < len data`) [cur`++] - /; if (token_is(cur, data, "module")) - ;mod_path.append(data`{cur` + 1}.data`) - ;cur` = cur` + 2 - ;break - ;/ - /; if (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD && len name == 0) - ;name = data`{cur`}.data` - /; if (len mod_path > 0) - ;{}uint8 frs = "_." - ;{}uint8 jn = join(mod_path, '.') - ;add_strings(~frs, ~jn) - ;add_strings(csec, ~frs) - ;csec`.append('.') - ;/ - ;add_strings(csec, ~name) - ;csec`.append(':') - ;csec`.append('\n') - /; if (!r) - ;header_guard(csec) - ;/ - ;; else if (token_is(cur, data, "(")) - ;setup_vtrack(cur, data, ~tab, csec) - ;; else if (token_is(cur, data, "[")) - ;cur`++ - ;out_type = get_vtype(cur, data) - ;cur`++ - ;; else if (token_is(cur, data, "raw")) - ;r = true - ;; else - ;break - ;/ - ;/ - - ;tnsl.io.println(out_type.name) - - ;bool ret = false - /; loop (cur` < len data` && !ret) - /; if (token_is(cur, data, ";/")) - /; if (!r) - ;tail_guard(csec) - ;/ - ;add_strings(csec, ~(tnslc.COMMON_ASM{0})) - ;break - ;; else if (token_is(cur, data, "/;")) - ;bool ch = true - /; loop (ch) - ;compile_block(cur, data, hsec, csec, dsec, mod_path) - /; if (cur` !< len data`) - ;break - ;/ - ;ch = token_is(cur, data, ";;") - ;/ - ;; else if (string_equate(data`{cur`}.data`, ":")) - ;cur` = cur` + 2 - ;Path inc = rel.rel_file(unquote_string(data`{cur`}.data`)) - ;compile_include(inc, hsec, csec, dsec, mod_path) - ;cur`++ - ;; else if (string_equate(data`{cur`}.data`, ";")) - ;ret = compile_statement(cur, data, ~tab, hsec, csec, dsec) - ;; else - ;tnsl.io.print("Failed to compile token [compile_block]: ") - ;data`{cur`}.print() - ;tnsl.io.println("") - ;break - ;/ - ;/ - - ;csec`.append('\n') -;/ - -/; compile_include (Path file_path, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path) - # Autocomplete in the case of module syntax - ;bool d = file_path.extension_is("tnsl") - /; if (!d) - ;file_path.dirs.append(file_path.file) - ;{}uint8 ftmp = file_path.file - ;{}uint8 tmp = ".tnsl" - ;add_strings(~ftmp, ~tmp) - ;file_path.file = ftmp - ;/ - - ;tnsl.io.print("[TNSLC:INCLUDE] ") - ;tnsl.io.println(file_path.full_path()) - - ;tnsl.io.File inc = file_path.open_r() - ;~{}Token data = parse.tokenize(inc) - ;inc.close() - - ;tnsl.io.print(len data`) - ;tnsl.io.println(" tokens parsed.") - - ;compile_file(file_path, data, hsec, csec, dsec, mod_path) -;/ - -/; compile_file (Path rel, ~{}Token data, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path) - - ;int j = len data` - - /; loop (int i = 0; i < j) [i++] - /; if (string_equate(data`{i}.data`, "/;")) - ;compile_block(~i, data, hsec, csec, dsec, mod_path, rel) - ;; else if (string_equate(data`{i}.data`, ";")) - ;compile_global(~i, data, hsec, csec, dsec) - ;; else if (string_equate(data`{i}.data`, ":")) - ;i = i + 2 - ;Path inc = rel.rel_file(unquote_string(data`{i}.data`)) - ;compile_include(inc, hsec, csec, dsec, mod_path) - ;; else - ;break - ;/ - ;/ - -;/ - -/; do_compile ({}uint8 file_out, Path rel) - ;{}uint8 hsec = ".global main\n" - ;{}uint8 csec = ".text\n" - ;{}uint8 dsec = ".data\n" - - ;tnslc.compile_include(rel, ~hsec, ~csec, ~dsec, {}) - - ;tnsl.io.File out = tnsl.io.writeFile(file_out) - - /; loop (int i = 0; i < len hsec) [i++] - ;out.write(hsec{i}) - ;/ - - ;out.write('\n') - - /; loop (int i = 0; i < len dsec) [i++] - ;out.write(dsec{i}) - ;/ - - ;out.write('\n') - - /; loop (int i = 0; i < len csec) [i++] - ;out.write(csec{i}) - ;/ - - ;out.write('\n') - ;out.close() -;/ - diff --git a/tnslc/compile/isa_x86.tnsl b/tnslc/compile/isa_x86.tnsl deleted file mode 100644 index 1cb09ab..0000000 --- a/tnslc/compile/isa_x86.tnsl +++ /dev/null @@ -1,182 +0,0 @@ -/## - Copyright 2021-2022 Kyle Gunger - - This file is licensed under the CDDL 1.0 (the License) - and may only be used in accordance with the License. - You should have received a copy of the License with this - software/source code. If you did not, a copy can be found - at the following URL: - - https://opensource.org/licenses/CDDL-1.0 - - THIS SOFTWARE/SOURCE CODE IS PROVIDED "AS IS" WITH NO - WARRANTY, GUARANTEE, OR CLAIM OF FITNESS FOR ANY PURPOSE - EXPRESS OR IMPLIED -#/ - -/; construct_statement({}uint8 base, {}{}uint8 args) [{}uint8] - /; loop (int i = 0; i < len args) [i++] - ;add_strings(~base, ~(args{i})) - /; if (i < len args - 1) - ;base.append(',') - ;base.append(' ') - ;/ - ;/ - ;base.append('\n') - ;return base -;/ - -/; literal_num ({}uint8 num) [{}uint8] - ;{}uint8 out = "$" - ;add_strings(~out, ~num) - ;return out -;/ - -/; add_asm ({}uint8 from, to) [{}uint8] - ;return construct_statement("\tadd ", {from, to}) -;/ - -/; sub_asm({}uint8 from, to) [{}uint8] - ;return construct_statement("\tsub ", {from, to}) -;/ - -/; push_asm ({}uint8 reg) [{}uint8] - ;return construct_statement("\tpush ", {reg}) -;/ - -/; pop_asm ({}uint8 reg) [{}uint8] - ;return construct_statement("\tpop ", {reg}) -;/ - -/; cmp_asm ({}uint8 a, b) [{}uint8] - ;return construct_statement("\tcmp ", {a, b}) -;/ - -/; mov_asm ({}uint8 a, b) [{}uint8] - ;return construct_statement("\tmov ", {a, b}) -;/ - -/; jmp_asm ({}uint8 pos) [{}uint8] - ;return construct_statement("\tjmp ", {pos}) -;/ - -/; call_asm ({}uint8 pos) [{}uint8] - ;return construct_statement("\tcall ", {pos}) -;/ - -/; cjmp_asm ({}uint8 suffix, pos) [{}uint8] - ;{}uint8 p = "\tj" - ;add_strings(~p, ~suffix) - ;p.append(' ') - ;return construct_statement(p, {pos}) -;/ - -/; mem_offset ({}uint8 pos, offset, scale) [{}uint8] - ;{}uint8 tmp = construct_statement("(", {pos, offset, scale}) - ;tmp{len tmp - 1} = ')' - ;return tmp -;/ - -/; header_guard (~{}uint8 csec) [{}uint8] - ;{}uint8 out = "", tmp = "" - ;tmp = push_asm("%r8") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r9") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r10") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r11") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r12") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r13") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r14") - ;add_strings(~out, ~tmp) - ;tmp = push_asm("%r15") - ;add_strings(~out, ~tmp) - ;add_strings(csec, ~out) -;/ - -/; tail_guard (~{}uint8 csec) [{}uint8] - ;{}uint8 out = "", tmp = "" - ;tmp = pop_asm("%r15") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r14") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r13") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r12") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r11") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r10") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r9") - ;add_strings(~out, ~tmp) - ;tmp = pop_asm("%r8") - ;add_strings(~out, ~tmp) - ;add_strings(csec, ~out) -;/ - -/; is_common_reg ({}uint8 n) [bool] - ;return string_equate(n, "ax") || string_equate(n, "bx") || string_equate(n, "cx") || string_equate(n, "dx") - || string_equate(n, "sp") || string_equate(n, "bp") || string_equate(n, "si") || string_equate(n, "di") - || string_equate(n, "8") || string_equate(n, "9") || string_equate(n, "10") || string_equate(n, "11") - || string_equate(n, "12") || string_equate(n, "13") || string_equate(n, "14") || string_equate(n, "15") -;/ - -/# Accepted common names: -# - ax -# - bx -# - cx -# - dx -# - si -# - di -# - bp -# - sp -# - 8-15 -#/ -/; get_reg (uint size, {}uint8 common) [{}uint8] - ;{}uint8 out = "%" - - /; if (common{0} !< 'a') - - /; if (size == 1) - /; if(common{1} == 'x') - ;common{1} = 'l' - ;; else - ;common.append('l') - ;/ - ;; else if (size == 4) - ;out.append('e') - ;; else if (size == 8) - ;out.append('r') - ;/ - - ;add_strings(~out, ~common) - - ;; else - - ;out.append('r') - ;add_strings(~out, ~common) - /; if (size == 1) - ;out.append('b') - ;; else if (size == 2) - ;out.append('w') - ;; else if (size == 4) - ;out.append('d') - ;/ - ;return out - ;/ - - ;return out -;/ - -/; make_label ({}uint8 func_name, func_place, ~{}uint8 csec) - ;func_name.append("_") - ;add_strings(~func_name, ~func_place) - ;func_name.append(':') - ;func_name.append('\n') - ;add_strings(csec, ~func_name) -;/ diff --git a/tnslc/compile/value.tnsl b/tnslc/compile/value.tnsl deleted file mode 100644 index da76ac8..0000000 --- a/tnslc/compile/value.tnsl +++ /dev/null @@ -1,362 +0,0 @@ -;struct Value { - bool - on_stack, - literal, - - int - loc, - val, - - VType - _type -} - -;Value NV = {false, false, 0, 0, 0, {0, 0, "null", {}, {}}} - -/; val_from_address (int offset, {}uint8 reg) [{}uint8] - ;{}uint8 out = string_from_int(offset) - ;out.append('(') - ;add_strings(~out, ~reg) - ;out.append(')') - ;return out -;/ - - -# The temp registers in order -/; reg_by_num(int r) [{}uint8] - /; if (r == 0) - ;return "ax" - ;; if (r == 1) - ;return "bx" - ;; if (r == 2) - ;return "cx" - ;; if (r == 3) - ;return "dx" - ;; if (r == 4) - ;return "si" - ;; if (r == 5) - ;return "di" - ;; if (r == -1) - ;return "sp" - ;/ - ;return string_from_int(r + 2) -;/ - -/; ext_by_size(int s) [uint8] - /; if (r == 1) - ;return 'b' - ;; if (r == 2) - ;return 'w' - ;; if (r == 4) - ;return 'l' - ;/ - ;return 'q' -;/ - - -/; method Value - - /; get_norm_sz [int] - /; if (self._type.ptr !== 0) - ;return 8 - ;/ - ;returnself._type._size - ;/ - - /; get_norm_loc [{}uint8] - /; if (self.on_stack) - ;return val_from_address(self.loc, "%rsp") - ;; if (!(self.on_stack) && self._type.ptr == 0 && is_struct(self._type)) - ;{}uint8 out = "(" - ;{}uint8 tmp = get_reg(8, reg_by_num(self.loc)) - ;add_strings(~out, ~tmp) - ;out.append(')') - ;return out - ;/ - - /; if (self.literal) - ;{}uint8 out = "$" - ;{}uint8 num = string_from_int(self.val) - ;add_strings(~out, ~num) - ;return out - ;/ - - ;int sz = self._type._size - /; if (self._type.ptr !== 0) - ;sz = 8 - ;/ - - ;return get_reg(sz, reg_by_num(self.loc)) - ;/ - - /; init_val [{}uint8] - /; if (self.literal || !self.on_stack) - ;return "" - ;/ - - ;{}uint8 out = "\tsub $" - ;{}uint8 tmp = string_from_int(self._type._size) - ;add_strings(~out, ~tmp) - ;tmp = ", %rsp\n" - ;add_strings(~out, ~tmp) - ;return out - ;/ - - /; standard_op(Value other, {}uint8 op) [{}uint8] - ;tnsl.io.print("Std op ") - ;tnsl.io.println(op) - ;int tsz = other._type._size - ;other._type._size = self._type._size - ;{}uint8 tmp = other.get_norm_loc() - ;other._type._size = tsz - ;{}uint8 out = "\t" - ;add_strings(~out, ~op) - ;out.append(' ') - ;add_strings(~out, ~tmp) - ;out.append(',') - ;out.append(' ') - ;tmp = self.get_norm_loc() - ;add_strings(~out, ~tmp) - ;out.append('\n') - ;return out - ;/ - - /; add_value (Value v) [{}uint8] - /; if (self.literal) - ;self.val = self.val + v.val - ;return "" - ;; else if (!(self.on_stack)) - ;return self.standard_op(v, "add") - ;/ - ;/ - - /; sub_value (Value v) [{}uint8] - /; if (self.literal) - ;self.val = self.val - v.val - ;return "" - ;; else if (!(self.on_stack)) - ;return self.standard_op(v, "sub") - ;/ - ;/ - - /; ax_compute(Value v, {}uint8 op, bool save_dx) - ;{}uint8 out = "\tpush %rax\n\tpush %rdx\n" - - /; if (v.on_stack) - ;v.loc = v.loc + 16 - ;; if (self.on_stack) - ;self.loc = self.loc + 16 - ;/ - - ;{}uint8 tmp = "\tmov " - ;{}uint8 t2 = v.get_norm_loc() - ;add_strings(~tmp, ~t2) - ;t2 = ", %rax\n" - ;add_strings(~tmp, ~t2) - ;add_strings(~out, ~tmp) - - ;tmp = "\txor %rdx, %rdx\n" - ;add_strings(~out, ~tmp) - - ;tmp = "\t" - ;add_strings(~tmp, ~op) - ;tmp.append(' ') - ;{}uint8 t2 = self.get_norm_loc() - ;add_strings(~tmp, ~t2) - ;tmp.append('\n') - ;add_strings(~out, ~tmp) - - /; if (save_dx) - ;tmp = "\tmov %rdx, " - ;; else - ;tmp = "\tmov %rax, " - ;/ - ;add_strings(~tmp, ~t2) - ;tmp.append('\n') - ;add_strings(~out, ~tmp) - - /; if (v.on_stack) - ;v.loc = v.loc - 16 - ;; if (self.on_stack) - ;self.loc = self.loc - 16 - ;/ - - ;tmp = "\tpop %rdx\n\tpop %rax" - ;add_strings(~out, ~tmp) - ;return out - ;/ - - /; mul_value (Value v) [{}uint8] - /; if (self.literal) - ;self.val = self.val * v.val - ;return "" - ;; else if (!(self.on_stack)) - /; if (self._type.name{0} !== 'u') - ;return self.standard_op(v, "imul") - ;/ - - ;return self.ax_compute(v, "mul", false) - ;/ - ;/ - - /; div_value (Value v) [{}uint8] - /; if (self.literal) - ;self.val = self.val + v.val - ;return "" - ;; else if (!(self.on_stack)) - /; if (self._type.name{0} !== 'u') - ;return self.ax_compute(v, "idiv", false) - ;/ - - ;return self.ax_compute(v, "div", false) - ;/ - ;/ - - /; mod_value (Value v) [{}uint8] - /; if (self.literal) - ;self.val = self.val / v.val - ;return "" - ;; else if (!self.on_stack) - /; if (self._type.name{0} !== 'u') - ;return self.ax_compute(v, "idiv", true) - ;/ - - ;return self.ax_compute(v, "div", true) - ;/ - ;/ - - /; ref_value (Value to_ref) [{}uint8] - /; if (!to_ref.on_stack) - ;return "" - ;/ - - ;return self.standard_op(to_ref, "lea") - ;/ - - /; deref_value [{}uint8] - /; if (self._type.ptr == 0) - ;return "" - ;/ - - ;Value new = self - ;new._type.ptr = new._type.ptr - 1 - ;{}uint8 out = "\tmov (" - ;{}uint8 tmp = self.get_norm_loc() - ;add_strings(~out, ~tmp) - ;out.append(')') - ;out.append(',') - ;out.append(' ') - ;tmp = new.get_norm_loc() - ;add_strings(~out, ~tmp) - - ;self = new - ;return out - ;/ - - /; get_index (Value index) [Value] - /; if (self._type.ptr == 0) - ;return NV - ;/ - ;/ - - /; set_value (Value v) [{}uint8] - /; if (self.literal) - ;self.val = v.val - ;return "" - ;; else if (!(self.on_stack)) - /; if (!is_struct(self._type)) - ;return self.standard_op(v, "mov") - ;/ - # This is the case where we are storing an address to - # a struct in a register. - ;{}charp out = "\tpush %rcx\n\tmov " - ;{}charp tmp = self.get_norm_loc() - ;add_strings(~out, ~tmp) - ;tmp = ", %rcx\n" - ;add_strings(~out, ~tmp) - ;tmp = self.standard_op(v, "movsb") - ;add_strings(~out, ~tmp) - ;tmp = "\tpop %rcx" - ;add_strings(~out, ~tmp) - ;return out - ;/ - - /; if (self._type._size !> 8) - /; if (!v.on_stack) - ;return self.standard_op(v, "mov") - ;/ - ;{}charp out = "\tpush %rax\n\tmov " - ;{}charp tmp = v.get_norm_loc() - ;add_strings(~out, ~tmp) - ;tmp = ", %rax\n" - ;add_strings(~out, ~tmp) - ;tmp = self.standard_op(v, "mov") - ;add_strings(~out, ~tmp) - ;return out - ;/ - - ;/ - - /; load_label_address ({}uint8 lab) [{}uint8] - ;{}uint8 out = "\tlea " - ;{}uint8 tmp = "(%rip), " - ;add_strings(~out, ~lab) - ;add_strings(~out, ~tmp) - ;tmp = self.get_norm_loc() - ;add_strings(~out, tmp) - ;out.append('\n') - ;return out - ;/ - - /; get_member_value ({}uint8 name) [Value] - ;Value out = self - /; if (self.on_stack) - ;out.loc = out.loc + self._type.get_offset(name) - ;; else - ;out.val = out.val + self._type.get_offset(name) - ;/ - ;out._type = self._type.get_sub_type(name) - ;out._type.ptr = -1 - ;return out - ;/ - - /; mov_to_reg (int reg) [{}uint8] - /; if (!(self.on_stack)) - ;return self.update_loc(0) - ;/ - ;/ - - /; update_loc(int loc) [{}uint8] - /; if (self.on_stack) - ;self.loc = self.loc + loc - ;; else if (!(self.literal)) - ;{}uint8 out = "\tmov " - ;int tsz = self._type._size - ;self._type._size = 8 - - ;{}uint8 tmp = self.get_norm_loc() - ;add_strings(~out, ~tmp) - ;out.append(',') - ;out.append(' ') - - ;self.loc = loc - - ;tmp = self.get_norm_loc() - ;add_strings(~out, ~tmp) - ;out.append('\n') - - ;self._type._size = tsz - ;return out - ;/ - ;return "" - ;/ - -;/ - -/; literal_val (int l, VType t) [Value] - ;return {false, true, 0, l, t} -;/ - -/; track_val(VType ty, bool on_stack, int loc) [Value] - ;return {on_stack, false, loc, 0, ty} -;/ -- cgit v1.2.3