diff options
-rw-r--r-- | tnslc/README.md | 4 | ||||
-rw-r--r-- | tnslc/breakdown.png | bin | 0 -> 168313 bytes | |||
-rwxr-xr-x | tnslc/build.sh | 2 | ||||
-rw-r--r-- | tnslc/compile/codegen.tnsl | 8 | ||||
-rw-r--r-- | tnslc/compile/compbuf.tnsl | 45 | ||||
-rw-r--r-- | tnslc/compile/compile.tnsl | 9 | ||||
-rw-r--r-- | tnslc/compile/function.tnsl | 36 | ||||
-rw-r--r-- | tnslc/compile/generate.tnsl | 6 | ||||
-rw-r--r-- | tnslc/compile/module.tnsl | 71 | ||||
-rw-r--r-- | tnslc/compile/scope.tnsl | 123 | ||||
-rw-r--r-- | tnslc/compile/struct.tnsl | 46 | ||||
-rw-r--r-- | tnslc/compile/type.tnsl | 360 | ||||
-rw-r--r-- | tnslc/compile/var.tnsl | 254 | ||||
-rw-r--r-- | tnslc/layout_generator.png | bin | 0 -> 338881 bytes | |||
-rw-r--r-- | tnslc/parse/ast.tnsl | 8 | ||||
-rw-r--r-- | tnslc/test.tnsl | 3 | ||||
-rw-r--r-- | tnslc/utils/algo.tnsl | 7 | ||||
-rw-r--r-- | tnslc/utils/vector.tnsl | 35 | ||||
-rw-r--r-- | tnslc/vec_test.tnsl | 47 |
19 files changed, 689 insertions, 375 deletions
diff --git a/tnslc/README.md b/tnslc/README.md index 9a69f6b..88607eb 100644 --- a/tnslc/README.md +++ b/tnslc/README.md @@ -4,12 +4,12 @@ The reference compiler for the TNSL programming language. The compiler is writt ## Usage: -Place the [bootstrap compiler](https://git.cshift.net/CircleShift/ctc) `ctc` in this folder and execute `build.sh` +Place the [bootstrap compiler](https://git.cshift.net/CircleShift/ctc) `ctc` in this folder and execute `build.sh tnslc` The compiler outputs x86 NASM compatible assembly. Examples: - `./ctc dummy.tnsl dummy.asm` - Run the bootstrap compiler on the dummy file, output to dummy.asm -- `./build.sh` - Build the compiler +- `./build.sh tnslc` - Build the compiler ## License diff --git a/tnslc/breakdown.png b/tnslc/breakdown.png Binary files differnew file mode 100644 index 0000000..dc5ce77 --- /dev/null +++ b/tnslc/breakdown.png diff --git a/tnslc/build.sh b/tnslc/build.sh index 6bee3fc..537c7cc 100755 --- a/tnslc/build.sh +++ b/tnslc/build.sh @@ -5,7 +5,7 @@ ARTIFACT_DIR=$BUILD_DIR/artifacts mkdir -p $BUILD_DIR mkdir -p $ARTIFACT_DIR -filename=tnslc.tnsl +filename=$1 filename="${filename%.*}" ./ctc $filename.tnsl $ARTIFACT_DIR/$filename.asm nasm -g -f elf64 -o $ARTIFACT_DIR/$filename.o $ARTIFACT_DIR/$filename.asm diff --git a/tnslc/compile/codegen.tnsl b/tnslc/compile/codegen.tnsl new file mode 100644 index 0000000..caaafb7 --- /dev/null +++ b/tnslc/compile/codegen.tnsl @@ -0,0 +1,8 @@ + +/; generate (~utils.File fin, fout) + parse.Node ast = parse.generate_ast(fin) + ast.update_children() + parse.print_ast(~ast) + ast.end() +;/ + diff --git a/tnslc/compile/compbuf.tnsl b/tnslc/compile/compbuf.tnsl new file mode 100644 index 0000000..b4ce261 --- /dev/null +++ b/tnslc/compile/compbuf.tnsl @@ -0,0 +1,45 @@ + +struct CompBuf { + utils.Vector + sec_head, + sec_data, + sec_code +} + +/; method CompBuf + /; init + self.sec_head.init(1) + self.sec_data.init(1) + self.sec_code.init(1) + ;/ + + /; add_h(~uint8 text) + self.sec_head.push_cstr(text) + ;/ + + /; add_d(~uint8 text) + self.sec_data.push_cstr(text) + ;/ + + /; add_c(~uint8 text) + self.sec_code.push_cstr(text) + ;/ + + /; write_to(~utils.File fout) + fout`.write_cstr("BITS 64\0\n") + fout`.write_cstr(self.sec_head.as_cstr()) + + fout`.write_cstr("\nsection .data\0\n\n") + fout`.write_cstr(self.sec_data.as_cstr()) + + fout`.write_cstr("\nsection .text\0\n\n") + fout`.write_cstr(self.sec_code.as_cstr()) + ;/ + + /; end + self.sec_head.end() + self.sec_data.end() + self.sec_code.end() + ;/ +;/ + diff --git a/tnslc/compile/compile.tnsl b/tnslc/compile/compile.tnsl index 3560f48..338e28d 100644 --- a/tnslc/compile/compile.tnsl +++ b/tnslc/compile/compile.tnsl @@ -1,4 +1,9 @@ /; module compile - :import "type.tnsl" - :import "generate.tnsl" + :import "compbuf.tnsl" + :import "struct.tnsl" + :import "var.tnsl" + :import "function.tnsl" + :import "module.tnsl" + :import "codegen.tnsl" ;/ + diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl new file mode 100644 index 0000000..cf42db1 --- /dev/null +++ b/tnslc/compile/function.tnsl @@ -0,0 +1,36 @@ + +struct Function { + ~uint8 name, + utils.Vector + inputs, + outputs, + ~parse.Node body +} + +/; method Function + /; init (~uint8 name) + self.name = name + Var v + self.inputs.init(len v) + self.outputs.init(len v) + ;/ + + /; end + _delete(self.name) + self.body`.end() + + ~Var v + /; loop (int i = 0; i < self.inputs.count) [i++] + v = self.inputs.get(i) + v`.end() + ;/ + self.inputs.end() + + /; loop (int i = 0; i < self.outputs.count) [i++] + v = self.outputs.get(i) + v`.end() + ;/ + self.outputs.end() + ;/ +;/ + diff --git a/tnslc/compile/generate.tnsl b/tnslc/compile/generate.tnsl deleted file mode 100644 index ef6a76c..0000000 --- a/tnslc/compile/generate.tnsl +++ /dev/null @@ -1,6 +0,0 @@ -/; generate (~utils.File fin, fout) - parse.Node n = parse.generate_ast(fin) - n.update_children() - parse.print_ast(~n) - n.end() -;/ diff --git a/tnslc/compile/module.tnsl b/tnslc/compile/module.tnsl new file mode 100644 index 0000000..6d1d24a --- /dev/null +++ b/tnslc/compile/module.tnsl @@ -0,0 +1,71 @@ + +struct Module { + # Text name of module + ~uint8 name, + + # Various contained elements + utils.Vector + vars, + structs, + funcs, + subs, + + # Whether we export or not + bool e +} + +/; method Module + + /; init (~uint8 name, bool exp) + Var v + Struct s + Function f + Module m + + self.vars.init(len v) + self.structs.init(len s) + self.funcs.init(len f) + self.subs.init(len m) + + self.name = name + self.e = exp + ;/ + + /; from_tree (~parse.Node root) + ;/ + + /; end + _delete(self.name) + + ~Var v + /; loop (int i = 0; i < self.vars.count) [i++] + v = self.vars.get(i) + v`.end() + ;/ + self.vars.end() + + ~Struct s + /; loop (int i = 0; i < self.structs.count) [i++] + s = self.structs.get(i) + s`.end() + ;/ + self.structs.end() + + ~Function f + /; loop (int i = 0; i < self.funcs.count) [i++] + f = self.funcs.get(i) + f`.end() + ;/ + self.funcs.end() + + ~Module m + /; loop (int i = 0; i < self.subs.count) [i++] + m = self.subs.get(i) + m`.end() + ;/ + self.subs.end() + + ;/ + +;/ + diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl new file mode 100644 index 0000000..7822125 --- /dev/null +++ b/tnslc/compile/scope.tnsl @@ -0,0 +1,123 @@ +struct Scope { + ~uint8 name, + + utils.Vector + stack_vars, + reg_vars, + + ~Scope parent, + + int + next_const, + next_bool +} + +/; method Scope + /; init (~uint8 name) + self.name = name + + Variable v + self.stack_vars.init(len v) + self.reg_vars.init(len v) + + self.next_const = 0 + self.next_bool = 0 + ;/ + + /; end + _delete(self.name) + + ~Variable v + /; loop (int i = 0; i < self.stack_vars.count) [i++] + v = self.stack_vars.get(i) + v`.end() + ;/ + + /; loop (int i = 0; i < self.reg_vars.count) [i++] + v = self.reg_vars.get(i) + v`.end() + ;/ + ;/ + + /; _name_rec (~utils.Vector out) + /; if (self.parent !== NULL) + self.parent`._name_rec(out) + out`.push_cstr("#") + ;/ + + out`.push_cstr(self.name) + ;/ + + /; _base_label [utils.Vector] + utils.Vector out + out.init(1) + + ~uint8 mod_str = self.current.label_prefix() + out.push_cstr(mod_str) + _delete(mod_str) + + self._name_rec(~out) + + return out + ;/ + + /; label_start [~uint8] + utils.Vector base = self._base_label() + base.push_cstr("#start\0") + return base.as_cstr() + ;/ + + /; label_rep [~uint8] + utils.Vector base = self._base_label() + base.push_cstr("#rep\0") + return base.as_cstr() + ;/ + + /; label_end [~uint8] + utils.Vector base = self._base_label() + base.push_cstr("#end\0") + return base.as_cstr() + ;/ + + /; label_next_const [~uint8] + utils.Vector base = self._base_label() + base.push_cstr("#const\0") + + ~uint8 str = utils.int_to_str(self.next_const) + base.push_cstr(str) + self.next_const++ + _delete(str) + + return base.as_cstr() + ;/ + + /; label_bool [~uint8] + utils.Vector base = self._base_label() + base.push_cstr("#bool\0") + + ~uint8 str = utils.int_to_str(self.next_bool) + base.push_cstr(str) + self.next_bool++ + _delete(str) + + return base.as_cstr() + ;/ + + /; label_bool_adv + self.next_bool++ + ;/ + + /; subscope (~uint8 name) [Scope] + Scope out + + utils.Vector str + str.from_cstr(name) + _delete(name) + + out.init(str.as_cstr(), self.current) + out.parent = ~self + + return out + ;/ +;/ + diff --git a/tnslc/compile/struct.tnsl b/tnslc/compile/struct.tnsl new file mode 100644 index 0000000..d175aef --- /dev/null +++ b/tnslc/compile/struct.tnsl @@ -0,0 +1,46 @@ + +struct Struct { + ~uint8 name, + ~Module methods, + utils.Vector members, + int size +} + +/; method Struct + + /; init (~uint8 name) + self.name = name + Var v + self.members.init(len v) + ;/ + + /; add_member(~Var v) + self.members.push(v) + ;/ + + /; get_member(~uint8 name) [~Var] + ~Var out = NULL + + ~Var v + /; loop (int i = 0; i < self.members.count) [i++] + v = self.members.get(i) + /; if (utils.strcmp(v`.name, name) == true) + return v + ;/ + ;/ + + return out + ;/ + + /; end + _delete(self.name) + ~Var v + /; loop (int i = 0; i < self.members.count) [i++] + v = self.members.get(i) + v`.end() + ;/ + self.members.end() + ;/ + +;/ + diff --git a/tnslc/compile/type.tnsl b/tnslc/compile/type.tnsl deleted file mode 100644 index 474f705..0000000 --- a/tnslc/compile/type.tnsl +++ /dev/null @@ -1,360 +0,0 @@ -struct Variable { - ~uint8 name, - ~Type _type, - utils.Vector ptr -} - -/; method Variable - /; init (~uint8 name) - self.name = name - self.ptr.init(8) - ;/ - - /; add_ptr(uint ptp) - self.ptr.push(~ptp) - ;/ - - /; get_ptr [uint] - /; if (self.ptr.count == 0) - return 0 - ;/ - ~uint p = self.ptr.get(self.ptr.count - 1) - return p` - ;/ - - /; pop_ptr [uint] - /; if (self.ptr.count == 0) - return 0 - ;/ - ~uint p = self.ptr.get(self.ptr.count - 1) - uint out = p` - self.ptr.pop() - return out - ;/ - - /; end - _delete(self.name) - self.ptr.end() - ;/ -;/ - -struct Type { - ~uint8 name, - uint size, - utils.Vector vars, - ~Module methods, -} - -/; method Type - /; init(~uint8 name) - self.name = name - Variable tmp - self.vars.init(len tmp) - ;/ - - /; add_var (~Variable v) - self.vars.push(v) - ;/ - - /; end - _delete(self.name) - /; loop (int i = 0; i < self.vars.count) [i++] - ~Variable v = self.vars.get(i) - v`.end() - ;/ - self.vars.end() - ;/ -;/ - -struct Function { - ~uint8 - name, - ~parse.Node - body, - utils.Vector - inputs, - outputs -} - -/; method Function - /; init (~uint8 name) - self.name = name - Variable vtmp - ~uint i - self.inputs.init(len vtmp) - self.outputs.init(len i) - ;/ - - /; add_input (~Variable v) - self.inputs.push(v) - ;/ - - /; add_output (~Type t) - self.outputs.push(~t) - ;/ - - /; end - _delete(self.name) - - /; loop (int i = 0; i < self.inputs.count) [i++] - ~Variable v = self.inputs.get(i) - v`.end() - ;/ - self.inputs.end() - - self.outputs.end() - ;/ -;/ - -struct Enum { - ~uint8 name, - ~Type _type, - utils.Vector vals -} - -/; method Enum - /; init (~uint8 name) - self.name = name - Variable vtmp - self.vals.init(len vtmp) - ;/ - - /; end - _delete(self.name) - /; loop (int i = 0; i < self.vals.count) [i++] - ~Variable v = self.vals.get(i) - v`.end() - ;/ - self.vals.end() - ;/ -;/ - -struct Module { - ~uint8 name, - ~Module parent, - bool exp, - utils.Vector - sub, - vars, - types, - funcs, - enums - -} - -uint8 MOD_FIND_SUB = 0 -uint8 MOD_FIND_VAR = 1 -uint8 MOD_FIND_TYP = 2 -uint8 MOD_FIND_FUN = 3 -uint8 MOD_FIND_ENM = 4 - -/; method Module - /; init (~uint8 name) - self.name = name - Module mtmp - Variable vtmp - Type ttmp - Function ftmp - Enum etmp - self.sub.init(len mtmp) - self.vars.init(len vtmp) - self.types.init(len ttmp) - self.funcs.init(len ftmp) - self.enums.init(len etmp) - ;/ - - /; update_children - /; loop (int i = 0; i < self.sub.count) [i++] - ~Module s = self.sub.get(i) - s`.parent = ~self - ;/ - ;/ - - /; add_sub(~Module m) [~Module] - self.sub.push(m) - /; loop (int i = 0; i < self.sub.count) [i++] - ~Module s = self.sub.get(i) - s`.update_children() - ;/ - return self.sub.get(self.sub.count - 1) - ;/ - - /; add_var (~Variable v) - self.vars.push(v) - ;/ - - /; add_type (~Type t) - self.types.push(t) - ;/ - - /; add_funcs (~Function f) - self.funcs.push(f) - ;/ - - /; add_enum (~Enum e) - self.enums.push(e) - ;/ - - /; _find_rec (utils.Artifact pth, uint8 typ, int sub) [~void] - /; if (sub !< pth.count) - return NULL - ;; else if ((sub + 1) < pth.count) - /; loop (int i = 0; i < self.sub.count) [i++] - ~Module m = self.sub.get(i) - /; if (utils.strcmp(pth.get(sub), m`.name) == true) - return _find_rec(pth, typ, sub + 1) - ;/ - ;/ - ;; else - /; if (typ == MOD_FIND_SUB) - /; loop (int i = 0; i < self.sub.count) [i++] - ~Module m = self.sub.get(i) - /; if (utils.strcmp(pth.get(sub), m`.name) == true) - return self.sub.get(i) - ;/ - ;/ - ;; else if (typ == MOD_FIND_VAR) - /; loop (int i = 0; i < self.vars.count) [i++] - ~Variable v = self.vars.get(i) - /; if (utils.strcmp(pth.get(sub), v`.name) == true) - return self.vars.get(i) - ;/ - ;/ - ;; else if (typ == MOD_FIND_TYP) - /; loop (int i = 0; i < self.types.count) [i++] - ~Type t = self.types.get(i) - /; if (utils.strcmp(pth.get(sub), t`.name) == true) - return self.types.get(i) - ;/ - ;/ - ;; else if (typ == MOD_FIND_FUN) - /; loop (int i = 0; i < self.funcs.count) [i++] - ~Function f = self.funcs.get(i) - /; if (utils.strcmp(pth.get(sub), f`.name) == true) - return self.funcs.get(i) - ;/ - ;/ - ;; else if (typ == MOD_FIND_ENM) - /; loop (int i = 0; i < self.enums.count) [i++] - ~Enum e = self.enums.get(i) - /; if (utils.strcmp(pth.get(sub), e`.name) == true) - return self.enums.get(i) - ;/ - ;/ - ;/ - ;/ - - /; if (self.parent == NULL || sub !== 0) - return NULL - ;/ - - return self.parent._find_rec(pth, typ, 0) - ;/ - - /; find (utils.Artifact pth, uint8 typ) [~void] - return _find_rec(pth, typ, 0) - ;/ - - /; end - _delete(self.name) - - /; loop (int i = 0; i < self.sub.count) [i++] - ~Module m = self.sub.get(i) - m`.end() - ;/ - self.sub.end() - - /; loop (int i = 0; i < self.vars.count) [i++] - ~Variable v = self.vars.get(i) - v`.end() - ;/ - self.vars.end() - - /; loop (int i = 0; i < self.types.count) [i++] - ~Type t = self.types.get(i) - t`.end() - ;/ - self.types.end() - - /; loop (int i = 0; i < self.funcs.count) [i++] - ~Function f = self.funcs.get(i) - f`.end() - ;/ - self.funcs.end() - - /; loop (int i = 0; i < self.enums.count) [i++] - ~Enum e = self.enums.get(i) - e`.end() - ;/ - self.enums.end() - ;/ -;/ - -{}~uint8 GEN_VAR_NAMES = { "int\0", "int8\0", "int16\0", "int32\0", "int64\0", "uint\0", "uint8\0", "uint16\0", "uint32\0", "uint64\0", "float\0", "float32\0", "float64\0", "vect\0", "bool\0", "void\0" } - -{}uint GEN_VAR_SIZES = { 8, 1, 2, 4, 8, 8, 1, 2, 4, 8, 8, 4, 8, 0, 1, 8} - -/; find_type(utils.Artifact a, ~parse.Node n) [~parse.Node] - return NULL -;/ - -/; transform_struct(~parse.Node n, ~Module parent) -;/ - -/; _tfn_mod_loop (~parse.Node n, ~Module m) - /; loop (int i = 0; i < n`.sub.count) [i++] - ~parse.Node s = n`.sub.get(i) - /; if (s`._type == parse.NTYPE_MODULE || s`._type == parse.NTYPE_EXPORT) - transform_module(s, m) - ;; else if (s`._type == parse.NTYPE_STRUCT) - transform_struct(s, m) - ;/ - ;/ -;/ - -/; transform_module (~parse.Node n, ~Module parent) - ~Module s = NULL - - /; loop (int i = 0; i < parent`.sub.count) [i++] - ~Module tmp = parent`.sub.get(i) - /; if (utils.strcmp(n`.data, tmp`.name) == true) - s = tmp - ;/ - ;/ - - ~int cmp = s - /; if (cmp == NULL) - Module out - out.init(utils.strcpy(n`.data)) - - /; if (n`._type == parse.NTYPE_EXPORT) - out.exp = true - ;; else - out.exp = false - ;/ - - s = parent`.add_sub(~out) - ;/ - - _tfn_mod_loop(n, s) -;/ - -/; _tfn_gen_default_types (~Module m) - /; loop (int i = 0; i < len GEN_VAR_NAMES) [i++] - Type t - t.init(utils.strcpy(GEN_VAR_NAMES{i})) - t.size = GEN_VAR_SIZES{i} - m`.add_type(~t) - ;/ -;/ - -/; transform_tree (~parse.Node n) [Module] - Module out - out.init(utils.strcpy(n`.data)) - out.exp = true - - _tfn_gen_default_types(~out) - _tfn_mod_loop(n, ~out) - - return out -;/ diff --git a/tnslc/compile/var.tnsl b/tnslc/compile/var.tnsl new file mode 100644 index 0000000..23da42b --- /dev/null +++ b/tnslc/compile/var.tnsl @@ -0,0 +1,254 @@ + +# Location enum +int VLOC_STCK = 2 +int VLOC_LITL = 1 +int VLOC_DATA = 0 + +int PTYPE_NONE = 2 +int PTYPE_PTR = 1 +int PTYPE_REF = 0 +int PTYPE_ARR = 1 + +int PRIM_NON = 0 +int PRIM_BOO = 1 +int PRIM_INT = 2 +int PRIM_FLT = 3 + +~uint8 PRIM_CSV_BOO = "bool\0" +~uint8 PRIM_CSV_INT = "int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64\0" +~uint8 PRIM_CSV_FLT = "float,float32,float64\0" + +# Should dispose of this constructed string +# 1-8 are ax, bx, cx, dx, si, di, sp, bp +# 9-16 are r8, r9, r10, r11, r12, r13, r14, r15 +# 17-32 are xmm0, xmm1, xmm2, ..., xmm15 +/; reg_string (int r, int size) [~uint8] + utils.Vector out + out.init(1) + uint8 add + + /; if (r < 9) + /; if (size == 4) + add = 'e' + out.push(~add) + ;; else if (size == 8) + add = 'r' + out.push(~add) + ;/ + + add = 'a' + /; if (r < 5) + add = add + r - 1 + ;; else if (r == 5 || r == 7) + add = 's' + ;; else if (r == 6) + add = 'd' + ;; else if (r == 8) + add = 'b' + ;/ + out.push(~add) + + /; if (r == 5 || r == 6) + add = 'i' + out.push(~add) + ;; else if (r == 7 || r == 8) + add = 'p' + out.push(~add) + ;; else if (size !== 1) + add = 'x' + out.push(~add) + ;/ + + /; if (size == 1) + add = 'l' + out.push(~add) + ;/ + ;; else if (r < 17) + add = 'r' + out.push(~add) + + ~uint8 num = utils.int_to_str(r - 1) + out.push_cstr(num) + _delete(num) + /; if (size == 1) + add = 'b' + out.push(~add) + ;; else if (size == 2) + add = 'w' + out.push(~add) + ;; else if (size == 4) + add = 'd' + out.push(~add) + ;/ + ;; else if (r < 33) + out.push_cstr("xmm\0") + ~uint8 num = utils.int_to_str(r - 17) + out.push_cstr(num) + _delete(num) + ;/ + + return out.as_cstr() +;/ + +struct Var { + ~uint8 name, + ~Struct _type, + utils.Vector ptrc, + int loc +} + +/; method Var + /; init (~uint8 name) + self.name = name + self.ptrc.init(4) + ;/ + + /; ptr [int32] + ~int32 i + i = self.ptrc.get(self.ptrc.count - 1) + return i` + ;/ + + /; ptr_push (int32 p) + self.ptrc.push(~p) + ;/ + + /; ptr_pop + self.ptrc.pop() + ;/ + + /; is_primitive [int] + ~uint8 tn = self`._type`.name + + /; if (parse._in_csv(PRIM_CSV_BOO, tn) == true) + return PRIM_BOO + ;; else if (parse._in_csv(PRIM_CSV_INT, tn) == true) + return PRIM_INT + ;; else if (parse._in_csv(PRIM_CSV_FLT, tn) == true) + return PRIM_FLT + ;/ + + return PRIM_NON + ;/ + + /; end + _delete(self.name) + self.ptrc.end() + ;/ + + ################################### + # Variable manipulation functions # + ################################### + + # Generate a string which represents where the variable is in memory, + # this string may be used to set the value of the variable with operations like "mov" + # if "maybe_mem" is true, this might be an address like "[rsi]" + /; gen_to (bool maybe_mem) [~uint8] + utils.Vector out + out.init(1) + return out.as_cstr() + ;/ + + # Generate a string which represents where the variable is in memory, + # this string may be used to read the value of the variable with operations like "mov" + # if "maybe_mem" is true, this might be an address like "[rsi]" + /; gen_from (bool maybe_mem) [~uint8] + utils.Vector out + out.init(1) + return out.as_cstr() + ;/ + + # Returns true if the variable is stored in memory + /; in_mem [bool] + /; if (self.loc !> 0) + return true + ;/ + return false + ;/ + + # Set this variable to the value of a literal + /; set_literal (~CompBuf buf, ~Var other) + ;/ + + # Set this Variable to the value of other + /; set (~CompBuf buf, ~Var other) + ;/ + + /; standard_op (~CompBuf buf, ~Var other, ~uint8 op_str) + ~uint8 from_str + ~uint8 to_str = self.gen_to(true) + + /; if (self.in_mem()) + from_str = other`.gen_from(false) + ;; else + from_str = other`.gen_from(true) + ;/ + + buf`.add_c(op_str) + buf`.add_c(" \0") + buf`.add_c(to_str) + buf`.add_c(", \0") + buf`.add_c(from_str) + buf`.add_c("\n\0") + + _delete(from_str) + _delete(to_str) + ;/ + + /; product_op (~CompBuf buf, ~Var other, ~uint8 op_str, int read_reg) + + ;/ + + /; add (~CompBuf buf, ~Var other) + /; if (self.loc = VLOC_LITL) + ;/ + self.standard_op("add") + ;/ + + /; sub (~CompBuf buf, ~Var other) + self.standard_op("sub") + ;/ + + /; mul (~CompBuf buf, ~Var other) + self.product_op(buf, other, "imul", 1) + ;/ + + /; div (~CompBuf buf, ~Var other) + /; if ("signed") + self.product_op(buf, other, "idiv", 1) + ;; else + self.product_op(buf, other, "div", 1) + ;/ + ;/ + + /; mod (~CompBuf buf, ~Var other) + /; if ("signed") + self.product_op(buf, other, "idiv", 4) + ;; else + self.product_op(buf, other, "div", 4) + ;/ + ;/ + + /; and (~CompBuf buf, ~Var other) + self.standard_op("and") + ;/ + + /; or (~CompBuf buf, ~Var other) + self.standard_op("or") + ;/ + + /; xor (~CompBuf buf, ~Var other) + self.standard_op("xor") + ;/ + + /; not (~CompBuf buf, ~Var other) + self.standard_op("xor") + ;/ + + /; member (~CompBuf buf, ~uint8 name) [Var] + Var out + return out + ;/ +;/ + + diff --git a/tnslc/layout_generator.png b/tnslc/layout_generator.png Binary files differnew file mode 100644 index 0000000..4e1c05c --- /dev/null +++ b/tnslc/layout_generator.png diff --git a/tnslc/parse/ast.tnsl b/tnslc/parse/ast.tnsl index 420f3d3..b12e75e 100644 --- a/tnslc/parse/ast.tnsl +++ b/tnslc/parse/ast.tnsl @@ -912,7 +912,7 @@ int errors_shown = 0 _ast_decl(fin, ~list, first) ;; else if (first`._type == TTYPE_USRWD || first`.eq("~\0") == true) _maybe_helper_fun(fin, ~list, first, true) - ;; else if (first`._type == TTYPE_LITRL || _op_prefix(first)) + ;; else if (first`._type == TTYPE_LITRL || first`.eq("(\0") == true || _op_prefix(first)) _ast_value(fin, ~list, first, true) ;; else if (first`._type == TTYPE_KEYWD) _ast_keyword_expr(fin, ~list, first) @@ -1054,7 +1054,7 @@ int errors_shown = 0 _ast_decl(fin, ~out, first) ;; else if (first`._type == TTYPE_USRWD || first`.eq("~\0") == true) _maybe_helper_fun(fin, ~out, first, false) - ;; else if (first`._type == TTYPE_LITRL || _op_prefix(first)) + ;; else if (first`._type == TTYPE_LITRL || first`.eq("(\0") == true || _op_prefix(first)) _ast_value(fin, ~out, first, false) ;; else if (first`._type == TTYPE_KEYWD) _ast_keyword_expr(fin, ~out, first) @@ -1815,7 +1815,7 @@ int errors_shown = 0 _ast_decl(fin, ~fn, first) ;; else if (first`._type == TTYPE_USRWD || first`.eq("~\0") == true) _maybe_helper_fun(fin, ~fn, first, false) - ;; else if (first`._type == TTYPE_LITRL || _op_prefix(first)) + ;; else if (first`._type == TTYPE_LITRL || first`.eq("(\0") == true || _op_prefix(first)) _ast_value(fin, ~fn, first, false) ;; else if (first`._type == TTYPE_KEYWD) _ast_keyword_expr(fin, ~fn, first) @@ -2187,7 +2187,7 @@ int errors_shown = 0 ;/ /; print_node_head (~Node n) - _printf("{ NODE_TYPE: \0") + _printf("{ \0") print_node_type(n) _printf(", DATA: \0") _printf(n`.data) diff --git a/tnslc/test.tnsl b/tnslc/test.tnsl index 6b55408..72836c3 100644 --- a/tnslc/test.tnsl +++ b/tnslc/test.tnsl @@ -1,9 +1,12 @@ int i = 1 + 2 * 4 - 3 + 4 +int j = -3 ~uint8 a = b{0} /; main ({}{}uint8 args) [int] + + tnsl.print("Hello, World!") ~uint8 as = 12 as` = 3 + 4 diff --git a/tnslc/utils/algo.tnsl b/tnslc/utils/algo.tnsl index 73cfb7f..35ac35c 100644 --- a/tnslc/utils/algo.tnsl +++ b/tnslc/utils/algo.tnsl @@ -200,6 +200,13 @@ return out.as_cstr() ;/ +/; stradd(~uint8 a, ~uint8 b) [~uint8] + Vector out + out.from_cstr(a) + out.push_cstr(b) + return out.as_cstr() +;/ + /; unquote_cha(~uint8 cha) [uint8] /; if (cha` !== '\\') return cha` diff --git a/tnslc/utils/vector.tnsl b/tnslc/utils/vector.tnsl index d00d698..38c45fc 100644 --- a/tnslc/utils/vector.tnsl +++ b/tnslc/utils/vector.tnsl @@ -67,6 +67,22 @@ uint VECTOR_MAX_GROW = 256 ;/ /; pop + self.remove(self.count - 1) + ;/ + + /; remove (int index) + /; if (index < 0 || index !< self.count) + return + ;/ + + /; if (self.count > 1) + /; loop (int i = index * self._elsz; i < (self.count - 1) * self._elsz) [i++] + ~uint8 to = self.data + i + ~uint8 from = self.data + i + self._elsz + to` = from` + ;/ + ;/ + self.count-- /; if (self.count < self.size / 2) @@ -96,6 +112,25 @@ uint VECTOR_MAX_GROW = 256 self._elsz = 0 _delete(self.data) ;/ + + /; copy [Vector] + Vector out + + out.init(self._elsz) + /; loop (int i = 0; i < self.count) [i++] + ~int tmp = self.get(i) + out.push(tmp) + ;/ + + return out + ;/ + + /; back [~void] + /; if (self.count > 0) + return self.get(self.count - 1) + ;/ + return NULL + ;/ ;/ diff --git a/tnslc/vec_test.tnsl b/tnslc/vec_test.tnsl new file mode 100644 index 0000000..95544e3 --- /dev/null +++ b/tnslc/vec_test.tnsl @@ -0,0 +1,47 @@ +:import "utils/utils.tnsl" + +/; print_vec(~utils.Vector v) + _printf("vec: [ \0") + /; if (v`.count > 0) + ~int n = v`.get(0) + _print_num("%d\0", n`) + /; loop (int i = 1; i < v`.count) [i++] + ~int n = v`.get(i) + _print_num(", %d\0", n`) + ;/ + ;/ + _printf(" ]\n\0") +;/ + +/; main [int] + utils.Vector vec + vec.init(8) + int a = 1295 + vec.push(~a) + a = 1984 + vec.push(~a) + a = 3498 + vec.push(~a) + a = 8972 + vec.push(~a) + + print_vec(~vec) + _printf("pop_front\n\0") + vec.remove(0) + print_vec(~vec) + _printf("pop_mid\n\0") + vec.remove(1) + print_vec(~vec) + _printf("pop_end\n\0") + vec.pop() + print_vec(~vec) + _printf("pop_final\n\0") + vec.pop() + print_vec(~vec) + + vec.end() + + return 0 +;/ + + |