summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2024-12-13 16:10:14 -0500
committerKyle Gunger <kgunger12@gmail.com>2024-12-13 16:10:14 -0500
commit61e1e5ce377719c8e9e437e5ba79ba06fc1de4ba (patch)
tree10ad1cbb37ab6fc2cbfc6971f9d00c8610b77f70
parent8bcb71c01fffa6cb576ad77f90ff3efe5c4c8fca (diff)
Type generation for compile modulesorigin
-rw-r--r--tnslc/README.md4
-rwxr-xr-xtnslc/build.sh2
-rw-r--r--tnslc/compile/compile.tnsl1
-rw-r--r--tnslc/compile/generate.tnsl16
-rw-r--r--tnslc/compile/outbuf.tnsl31
-rw-r--r--tnslc/compile/type.tnsl250
-rw-r--r--tnslc/parse/ast.tnsl6
-rw-r--r--tnslc/utils/algo.tnsl7
-rw-r--r--tnslc/utils/vector.tnsl35
9 files changed, 335 insertions, 17 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/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/compile.tnsl b/tnslc/compile/compile.tnsl
index 3560f48..b980b62 100644
--- a/tnslc/compile/compile.tnsl
+++ b/tnslc/compile/compile.tnsl
@@ -1,4 +1,5 @@
/; module compile
:import "type.tnsl"
+ :import "outbuf.tnsl"
:import "generate.tnsl"
;/
diff --git a/tnslc/compile/generate.tnsl b/tnslc/compile/generate.tnsl
index ef6a76c..c05a304 100644
--- a/tnslc/compile/generate.tnsl
+++ b/tnslc/compile/generate.tnsl
@@ -1,6 +1,22 @@
+/; generate_module (~OutBuf buf, ~Module mod)
+;/
+
/; generate (~utils.File fin, fout)
parse.Node n = parse.generate_ast(fin)
n.update_children()
parse.print_ast(~n)
+
+ OutBuf buf
+ buf.init()
+
+ Module mod = transform_tree(~n, ~buf)
+ mod.print(0)
+
+
+ generate_module(~buf, ~mod)
+ buf.write_to_file(fout)
+
+ mod.end()
+ buf.end()
n.end()
;/
diff --git a/tnslc/compile/outbuf.tnsl b/tnslc/compile/outbuf.tnsl
new file mode 100644
index 0000000..7394feb
--- /dev/null
+++ b/tnslc/compile/outbuf.tnsl
@@ -0,0 +1,31 @@
+struct OutBuf {
+ utils.Vector
+ hsec,
+ dsec,
+ csec
+}
+
+/; method OutBuf
+ /; init
+ self.hsec.init(1)
+ self.dsec.init(1)
+ self.csec.init(1)
+ ;/
+
+ /; write_to_file (~utils.File fout)
+ fout`.open()
+ fout`.write_cstr("bits 64\n\0")
+ fout`.write_cstr(self.hsec.as_cstr())
+ fout`.write_cstr("\nsection .data\n\0")
+ fout`.write_cstr(self.dsec.as_cstr())
+ fout`.write_cstr("\nsection .text\n\0")
+ fout`.write_cstr(self.csec.as_cstr())
+ fout`.close()
+ ;/
+
+ /; end
+ self.hsec.end()
+ self.dsec.end()
+ self.csec.end()
+ ;/
+;/
diff --git a/tnslc/compile/type.tnsl b/tnslc/compile/type.tnsl
index 474f705..28813ce 100644
--- a/tnslc/compile/type.tnsl
+++ b/tnslc/compile/type.tnsl
@@ -1,3 +1,9 @@
+/; _indent (int indent)
+ /; loop (int i = 0; i < indent) [i++]
+ _printf(" \0")
+ ;/
+;/
+
struct Variable {
~uint8 name,
~Type _type,
@@ -36,6 +42,27 @@ struct Variable {
_delete(self.name)
self.ptr.end()
;/
+
+ /; _prnt(int indent)
+ _printf(self.name)
+
+ # todo: types and such
+
+ _indent(indent)
+ _printf("}\n\0")
+ ;/
+
+ /; print (int indent)
+ _indent(indent)
+ _printf("{ Variable: \0")
+ _prnt(indent)
+ ;/
+
+ /; print_mem (int indent)
+ _indent(indent)
+ _printf("{ Member: \0")
+ _prnt(indent)
+ ;/
;/
struct Type {
@@ -64,6 +91,21 @@ struct Type {
;/
self.vars.end()
;/
+
+ /; print (int indent)
+ _indent(indent)
+ _printf("{ Type: \0")
+ _printf(self.name)
+ _print_num(" { size: %d }\n\0", self.size)
+
+ /; loop (int i = 0; i < self.vars.count) [i++]
+ ~Variable v = self.vars.get(i)
+ v`.print_mem(indent + 1)
+ ;/
+
+ _indent(indent)
+ _printf("}\n\0")
+ ;/
;/
struct Function {
@@ -127,12 +169,27 @@ struct Enum {
;/
self.vals.end()
;/
+
+ /; print (int indent)
+ _indent(indent)
+ _printf("{ Enum: \0")
+ _printf(self.name)
+ _printf("\n\0")
+
+ /; loop (int i = 0; i < self.vals.count) [i++]
+ ~Variable v = self.vals.get(i)
+ v`.print(indent + 1)
+ ;/
+
+ _indent(indent)
+ _printf("}\n\0")
+ ;/
;/
struct Module {
~uint8 name,
~Module parent,
- bool exp,
+ bool exp, mth,
utils.Vector
sub,
vars,
@@ -176,7 +233,9 @@ uint8 MOD_FIND_ENM = 4
~Module s = self.sub.get(i)
s`.update_children()
;/
- return self.sub.get(self.sub.count - 1)
+ ~Module out = self.sub.get(self.sub.count - 1)
+ out`.parent = ~self
+ return out
;/
/; add_var (~Variable v)
@@ -201,7 +260,7 @@ uint8 MOD_FIND_ENM = 4
;; 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)
+ /; if (utils.strcmp(pth.get(sub), m`.name) == true && m`.mth == false)
return _find_rec(pth, typ, sub + 1)
;/
;/
@@ -209,7 +268,7 @@ uint8 MOD_FIND_ENM = 4
/; 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)
+ /; if (utils.strcmp(pth.get(sub), m`.name) == true && m`.mth == false)
return self.sub.get(i)
;/
;/
@@ -288,6 +347,36 @@ uint8 MOD_FIND_ENM = 4
;/
self.enums.end()
;/
+
+ /; print (int indent)
+ _indent(indent)
+ /; if (self.mth == true)
+ _printf("{ Method: \0")
+ ;; else
+ _printf("{ Module: \0")
+ ;/
+ _printf(self.name)
+ _printf("\n\0")
+
+
+ /; loop (int i = 0; i < self.sub.count) [i++]
+ ~Module s = self.sub.get(i)
+ s`.print(indent + 1)
+ ;/
+
+ /; loop (int i = 0; i < self.types.count) [i++]
+ ~Type s = self.types.get(i)
+ s`.print(indent + 1)
+ ;/
+
+ /; loop (int i = 0; i < self.enums.count) [i++]
+ ~Enum s = self.enums.get(i)
+ s`.print(indent + 1)
+ ;/
+
+ _indent(indent)
+ _printf("}\n\0")
+ ;/
;/
{}~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" }
@@ -298,21 +387,26 @@ uint8 MOD_FIND_ENM = 4
return NULL
;/
-/; transform_struct(~parse.Node n, ~Module parent)
+/; transform_struct(~parse.Node n, ~Module m)
;/
-/; _tfn_mod_loop (~parse.Node n, ~Module m)
+/; transform_enum(~parse.Node n, ~OutBuf b, ~Module m)
+;/
+
+/; _tfn_mod_loop (~parse.Node n, ~OutBuf b, ~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)
+ transform_module(s, b, m)
;; else if (s`._type == parse.NTYPE_STRUCT)
transform_struct(s, m)
+ ;; else if (s`._type == parse.NTYPE_ENUM)
+ transform_enum(s, b, m)
;/
;/
;/
-/; transform_module (~parse.Node n, ~Module parent)
+/; transform_module (~parse.Node n, ~OutBuf b, ~Module parent)
~Module s = NULL
/; loop (int i = 0; i < parent`.sub.count) [i++]
@@ -336,25 +430,159 @@ uint8 MOD_FIND_ENM = 4
s = parent`.add_sub(~out)
;/
- _tfn_mod_loop(n, s)
+ _tfn_mod_loop(n, b, s)
;/
+#
+# GEN DEFAULT TYPES
+#
+
/; _tfn_gen_default_types (~Module m)
+ Module d
+ d.init(utils.strcpy("#\0"))
+ ~Module dp = m`.add_sub(~d)
/; 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}
+ t.methods = dp
m`.add_type(~t)
;/
;/
-/; transform_tree (~parse.Node n) [Module]
+#
+# GEN TYPES & ENUMS FIRST PASS
+#
+
+/; _tfn_gen_types_mod(~parse.Node n, ~Module m)
+ ~Module s = NULL
+
+ /; loop (int i = 0; i < m`.sub.count) [i++]
+ ~Module tmp = m`.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 = m`.add_sub(~out)
+ ;/
+
+ _tfn_gen_types(n, s)
+;/
+
+/; _tfn_gen_types (~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)
+ _tfn_gen_types_mod(s, m)
+ ;; else if (s`._type == parse.NTYPE_STRUCT)
+ Module mth
+ mth.init(utils.stradd("_#\0", s`.data))
+ ~Module mp = m`.add_sub(~mth)
+
+ Type t
+ t.size = 0
+ t.init(utils.strcpy(s`.data))
+ t.methods = mp
+ m`.add_type(~t)
+ ;; else if (s`._type == parse.NTYPE_ENUM)
+ Enum e
+ e.init(utils.strcpy(s`.data))
+ m`.add_enum(~e)
+ ;/
+ ;/
+;/
+
+# Main transform functions
+
+/; _td_rec(~parse.Node n, ~utils.Artifact a)
+ /; if (n`.eq(".\0") == true && n`.sub.count > 1)
+ ~parse.Node tmp = n`.sub.get(0)
+ _td_rec(tmp, a)
+ tmp = n`.sub.get(1)
+ _td_rec(tmp, a)
+ ;; else if (n`._type == parse.NTYPE_ID)
+ a`.push(utils.strcpy(n`.data))
+ ;/
+;/
+
+/; transform_dot(~parse.Node n) [utils.Artifact]
+ utils.Artifact out
+ out.init()
+
+ _td_rec(n, ~out)
+
+ return out
+;/
+
+/; art_from_type(~parse.Node n) [utils.Artifact]
+ utils.Artifact out
+ out.init()
+
+ /; if (n`._type !== parse.NTYPE_TYPE)
+ return out
+ ;/
+
+ /; loop (int i = 0; i < n`.sub.count) [i++]
+ ~parse.Node s = n`.sub.get(i)
+ /; if (s`._type == parse.NTYPE_ID)
+ out.push(utils.strcpy(s`.data))
+ ;/
+ ;/
+
+ return out
+;/
+
+/; vec_from_type(~parse.Node n) [utils.Vector]
+ utils.Vector out
+ out.init(8)
+
+ /; if (n`._type !== parse.NTYPE_TYPE)
+ return out
+ ;/
+
+ int nm
+ /; loop (int i = 0; i < n`.sub.count) [i++]
+ ~parse.Node s = n`.sub.get(i)
+ /; if (s`._type == parse.NTYPE_PRE_OP)
+ /; if (s`.eq("~\0") == true)
+ nm = 0 - 1
+ ;; else if (s`.eq("{\0") == true)
+ # TODO: WHATEVER
+ nm = 0 - 2
+ ;/
+ out.push(~nm)
+ ;; else if (s`._type == parse.NTYPE_POST_OP)
+ /; if (s`.eq("`\0") == true)
+ nm = 0
+ out.push(~nm)
+ ;/
+ ;/
+ ;/
+
+ return out
+;/
+
+/; transform_tree (~parse.Node n, ~OutBuf buf) [Module]
Module out
out.init(utils.strcpy(n`.data))
out.exp = true
_tfn_gen_default_types(~out)
- _tfn_mod_loop(n, ~out)
+ _tfn_gen_types(n, ~out)
+ out.update_children()
+ _tfn_mod_loop(n, buf, ~out)
return out
;/
diff --git a/tnslc/parse/ast.tnsl b/tnslc/parse/ast.tnsl
index 420f3d3..588f3fd 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)
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
+ ;/
;/