summaryrefslogtreecommitdiff
path: root/tnslc
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc')
-rw-r--r--tnslc/README.md4
-rw-r--r--tnslc/breakdown.pngbin0 -> 168313 bytes
-rwxr-xr-xtnslc/build.sh2
-rw-r--r--tnslc/compile/codegen.tnsl8
-rw-r--r--tnslc/compile/compbuf.tnsl45
-rw-r--r--tnslc/compile/compile.tnsl9
-rw-r--r--tnslc/compile/function.tnsl36
-rw-r--r--tnslc/compile/generate.tnsl6
-rw-r--r--tnslc/compile/module.tnsl71
-rw-r--r--tnslc/compile/scope.tnsl123
-rw-r--r--tnslc/compile/struct.tnsl46
-rw-r--r--tnslc/compile/type.tnsl360
-rw-r--r--tnslc/compile/var.tnsl254
-rw-r--r--tnslc/layout_generator.pngbin0 -> 338881 bytes
-rw-r--r--tnslc/parse/ast.tnsl8
-rw-r--r--tnslc/test.tnsl3
-rw-r--r--tnslc/utils/algo.tnsl7
-rw-r--r--tnslc/utils/vector.tnsl35
-rw-r--r--tnslc/vec_test.tnsl47
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
new file mode 100644
index 0000000..dc5ce77
--- /dev/null
+++ b/tnslc/breakdown.png
Binary files differ
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
new file mode 100644
index 0000000..4e1c05c
--- /dev/null
+++ b/tnslc/layout_generator.png
Binary files differ
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
+;/
+
+