From c94edbe007910755087e71cbb1a6a349d75e9b85 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Tue, 3 Jan 2023 02:03:54 -0500 Subject: Basic addition and subtraction --- tnslc/compile/compile.tnsl | 181 +++++++++++++++++++++------------------------ tnslc/compile/value.tnsl | 134 ++++++++++++++++++++++++++------- 2 files changed, 189 insertions(+), 126 deletions(-) (limited to 'tnslc/compile') diff --git a/tnslc/compile/compile.tnsl b/tnslc/compile/compile.tnsl index cdb651f..034304c 100644 --- a/tnslc/compile/compile.tnsl +++ b/tnslc/compile/compile.tnsl @@ -77,7 +77,7 @@ /; method VTrack /; next_loc(VType vt) [int] - /; if (is_struct(vt)) + /; if (is_struct(vt) && vt.ptr == 0) ;return -1 ;/ @@ -110,8 +110,8 @@ # Returns true if the variable is being tracked /; in_vtrack({}uint8 name) [bool] - /; loop (int i = 0; i < len (self.on_stack)) [i++] - /; if (string_equate(~name, ~(self.sym_names{i}))) + /; loop (int i = 0; i < len (self.sym_names)) [i++] + /; if (string_equate(name, self.sym_names{i})) ;return true ;/ ;/ @@ -131,7 +131,7 @@ # returns the type of the named variable /; get_val ({}uint8 name) [Value] - /; loop (int i = 0; i < len (self.on_stack)) [i++] + /; loop (int i = 0; i < len (self.sym_names)) [i++] /; if (string_equate(name, self.sym_names{i})) ;return (self.sym_vals{i}) ;/ @@ -146,7 +146,9 @@ ;/ /; loop (int i = 0; i < len (self.sym_vals)) [i++] - ;self.sym_vals{i}.loc = self.sym_vals{i}.loc + tsz + /; if (self.sym_vals{i}.on_stack) + ;self.sym_vals{i}.loc = self.sym_vals{i}.loc + tsz + ;/ ;/ ;{}uint8 out = "\tsub $" @@ -196,31 +198,6 @@ ;return -1 ;/ -# Given an index in the vtrack, returns a string representation of the -# register or memory where that variable is -/; index_to_loc (int index, ~VTrack tab) [{}uint8] - ;{}uint8 out = "" - ;int stack_bytes = 0 - ;int reg = 0 - ;int i = 0 - - /; loop (i < index) [i++] - /; if (tab`.sym_types{i}._size !> 8 && reg < 7) - ;reg++ - ;; else - ;stack_bytes = stack_bytes + tab`.sym_types{i}._size - ;/ - ;/ - - /; if (is_struct(tab`.sym_types{index})) - ;out = "(todo: structs)" - ;; else - ;out = reg_by_num(reg) - ;/ - - ;return out -;/ - # Bool to j /; cmp_to_jxt ({}uint8 c) [{}uint8] /; if (string_equate(c, "<")) @@ -235,17 +212,12 @@ ;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] - /; if (t.ptr !== 0) - ;return false - ;/ - ;VType tmp = NT /; loop (int i = 0; i < 15) [i++] ;tmp = tnslc.type_table{i} @@ -254,8 +226,6 @@ ;/ ;/ - - ;return true ;/ @@ -428,42 +398,88 @@ ;/ # Mostly deals with structs and enums -/; compile_global (~int cur, ~{}Token data, ~VTrack gsc, ~{}uint8 hsec, csec, dsec) +/; 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 and return it to the register pointed at by reg -/; eval_value (~int cur, ~{}Token data, ~VTrack tab, gsc, ~{}uint8 hsec, csec, dsec) [Value] +# 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 ;/ - ;int val_layer = 0 + ;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 - ;{}uint8 tmp = construct_mov_literal(data`{cur`}.data`, get_reg(8, reg_by_num(val_layer))) - ;add_strings(csec, ~tmp) - ;val_layer++ + ;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] @@ -487,7 +503,7 @@ ;/ # Sets up a call and reports back where the return value is stored -/; eval_call (~int cur, ~{}Token data, ~VTrack tab, gsc, ~{}uint8 hsec, csec, dsec) [{}uint8] +/; 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) @@ -499,10 +515,10 @@ ;cur`++ ;; else /; if (reg < 7) - ;eval_value(cur, data, tab, gsc, hsec, csec, dsec) + ;eval_value(cur, data, tab, hsec, csec, dsec) ;reg++ ;; else - ;eval_value(cur, data, tab, gsc, hsec, csec, dsec) + ;eval_value(cur, data, tab, hsec, csec, dsec) ;push_asm(get_reg(8, "bp")) ;/ ;/ @@ -515,37 +531,6 @@ ;return "ax" ;/ -/; set_struct_value (~{}uint8 csec) - -;/ - -/; copy_struct ({}uint8 from, to, VType t) [{}uint8] - ;{}uint8 out = "" - ;{}uint8 init = "" -;/ - -/; set_value ({}uint8 from, to, int size, ~{}uint8 csec) - /; if (is_common_reg(from)) - ;from = get_reg(size, from) - ;; if (is_common_reg(to)) - ;to = get_reg(size, to) - ;/ - - ;{}uint8 tmp = "\tmov" - /; if (size == 1) - ;mov.append('b') - ;; else if (size == 2) - ;mov.append('d') - ;; else if (size == 4) - ;mov.append('w') - ;; else if (size == 8) - ;mov.append('q') - ;/ - - ;tmp = construct_statement(tmp, {from, to}) - ;add_strings(csec, ~tmp) -;/ - /; is_call (~int cur, ~{}Token data) [bool] ;bool look_def = true /; loop (int i = cur`; i < len data`) [i++] @@ -563,7 +548,7 @@ ;/ # Compile a statement in a function -/; compile_statement (~int cur, ~{}Token data, ~VTrack tab, gsc, ~{}uint8 hsec, csec, dsec) [bool] +/; compile_statement (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec) [bool] ;cur`++ ;bool r = false /; if (cur` !< len data`) @@ -582,18 +567,20 @@ ;r = true ;; else if (token_is(cur, data, "return")) ;cur`++ - ;eval_value(cur, data, tab, gsc, hsec, csec, dsec, 0) + ;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, gsc, hsec, csec, dsec) - ;; else if (name_to_index(data`{cur`}.data`, tab) !< 0) + ;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, gsc, hsec, csec, dsec) + ;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 @@ -609,7 +596,7 @@ ;cur`++ ;; else if (token_is(cur, data, "=")) ;{}uint8 set = index_to_loc(len tab`.sym_names - 1, tab) - ;eval_value(cur, data, tab, gsc, hsec, csec, dsec, loc) + ;eval_value(cur, data, tab, hsec, csec, dsec, loc) /; if (token_is(cur, data, ",")) ;cur`++ ;/ @@ -629,7 +616,7 @@ -/; compile_block (~int cur, ~{}Token data, ~VTrack gsc, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path, Path rel) +/; 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 = "" @@ -682,7 +669,7 @@ ;; else if (token_is(cur, data, "/;")) ;bool ch = true /; loop (ch) - ;compile_block(cur, data, gsc, hsec, csec, dsec, mod_path) + ;compile_block(cur, data, hsec, csec, dsec, mod_path) /; if (cur` !< len data`) ;break ;/ @@ -691,10 +678,10 @@ ;; else if (string_equate(data`{cur`}.data`, ":")) ;cur` = cur` + 2 ;Path inc = rel.rel_file(unquote_string(data`{cur`}.data`)) - ;compile_include(inc, gsc, hsec, csec, dsec, mod_path) + ;compile_include(inc, hsec, csec, dsec, mod_path) ;cur`++ ;; else if (string_equate(data`{cur`}.data`, ";")) - ;ret = compile_statement(cur, data, ~tab, gsc, hsec, csec, dsec) + ;ret = compile_statement(cur, data, ~tab, hsec, csec, dsec) ;; else ;tnsl.io.print("Failed to compile token [compile_block]: ") ;data`{cur`}.print() @@ -706,7 +693,7 @@ ;csec`.append('\n') ;/ -/; compile_include (Path file_path, ~VTrack global, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path) +/; 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) @@ -727,22 +714,22 @@ ;tnsl.io.print(len data`) ;tnsl.io.println(" tokens parsed.") - ;compile_file(file_path, data, global, hsec, csec, dsec, mod_path) + ;compile_file(file_path, data, hsec, csec, dsec, mod_path) ;/ -/; compile_file (Path rel, ~{}Token data, ~VTrack global, ~{}uint8 hsec, csec, dsec, {}{}uint8 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, global, hsec, csec, dsec, mod_path, rel) + ;compile_block(~i, data, hsec, csec, dsec, mod_path, rel) ;; else if (string_equate(data`{i}.data`, ";")) - ;compile_global(~i, data, global, hsec, csec, dsec) + ;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, global, hsec, csec, dsec, mod_path) + ;compile_include(inc, hsec, csec, dsec, mod_path) ;; else ;break ;/ @@ -754,10 +741,8 @@ ;{}uint8 hsec = ".global main\n" ;{}uint8 csec = ".text\n" ;{}uint8 dsec = ".data\n" - - ;VTrack global_scope = {{}, {}} - ;tnslc.compile_include(rel, ~global_scope, ~hsec, ~csec, ~dsec, {}) + ;tnslc.compile_include(rel, ~hsec, ~csec, ~dsec, {}) ;tnsl.io.File out = tnsl.io.writeFile(file_out) diff --git a/tnslc/compile/value.tnsl b/tnslc/compile/value.tnsl index 747c172..da76ac8 100644 --- a/tnslc/compile/value.tnsl +++ b/tnslc/compile/value.tnsl @@ -36,10 +36,23 @@ ;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 @@ -53,6 +66,12 @@ /; 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) @@ -71,25 +90,21 @@ ;/ /; init_val [{}uint8] - /; if (!self.on_stack) - ;{}uint8 out = "\tmov $0, " - ;{}uint8 reg = get_reg(8, reg_by_num(self.loc)) - ;add_strings(~out, ~reg) - ;return out - ;; else if (!self.literal) - ;{}uint8 out = "\tsub $" - ;{}uint8 tmp = string_from_int(self._type._size) - ;add_strings(~out, ~tmp) - ;out.append(',') - ;out.append(' ') - ;tmp = "%rsp\n" - ;add_strings(~out, ~tmp) - ;return out + /; if (self.literal || !self.on_stack) + ;return "" ;/ - ;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() @@ -110,22 +125,28 @@ /; if (self.literal) ;self.val = self.val + v.val ;return "" - ;; else if (!self.on_stack) + ;; 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 + ;self.val = self.val - v.val ;return "" - ;; else if (!self.on_stack) + ;; 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() @@ -154,6 +175,12 @@ ;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 @@ -161,9 +188,9 @@ /; mul_value (Value v) [{}uint8] /; if (self.literal) - ;self.val = self.val + v.val + ;self.val = self.val * v.val ;return "" - ;; else if (!self.on_stack) + ;; else if (!(self.on_stack)) /; if (self._type.name{0} !== 'u') ;return self.standard_op(v, "imul") ;/ @@ -176,7 +203,7 @@ /; if (self.literal) ;self.val = self.val + v.val ;return "" - ;; else if (!self.on_stack) + ;; else if (!(self.on_stack)) /; if (self._type.name{0} !== 'u') ;return self.ax_compute(v, "idiv", false) ;/ @@ -187,7 +214,7 @@ /; mod_value (Value v) [{}uint8] /; if (self.literal) - ;self.val = self.val + v.val + ;self.val = self.val / v.val ;return "" ;; else if (!self.on_stack) /; if (self._type.name{0} !== 'u') @@ -226,9 +253,9 @@ ;return out ;/ - /; arr_value (Value index, Value store) + /; get_index (Value index) [Value] /; if (self._type.ptr == 0) - ;return + ;return NV ;/ ;/ @@ -237,21 +264,72 @@ ;self.val = v.val ;return "" ;; else if (!(self.on_stack)) - ;return self.standard_op(v, "mov") + /; 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 - ;out.loc = out.loc + self._type.get_offset(name) + /; 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) + ;; else if (!(self.literal)) ;{}uint8 out = "\tmov " ;int tsz = self._type._size ;self._type._size = 8 @@ -263,7 +341,7 @@ ;self.loc = loc - ;{}uint8 tmp = self.get_norm_loc() + ;tmp = self.get_norm_loc() ;add_strings(~out, ~tmp) ;out.append('\n') -- cgit v1.2.3