summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtnslc/build.sh2
-rw-r--r--tnslc/parse/ast.tnsl140
-rw-r--r--tnslc/parse/tokenizer.tnsl2
-rw-r--r--tnslc/test.tnsl14
4 files changed, 136 insertions, 22 deletions
diff --git a/tnslc/build.sh b/tnslc/build.sh
index 1f85a60..6bee3fc 100755
--- a/tnslc/build.sh
+++ b/tnslc/build.sh
@@ -7,7 +7,7 @@ mkdir -p $BUILD_DIR
mkdir -p $ARTIFACT_DIR
filename=tnslc.tnsl
filename="${filename%.*}"
-valgrind ./ctc $filename.tnsl $ARTIFACT_DIR/$filename.asm
+./ctc $filename.tnsl $ARTIFACT_DIR/$filename.asm
nasm -g -f elf64 -o $ARTIFACT_DIR/$filename.o $ARTIFACT_DIR/$filename.asm
gcc -ggdb -o $BUILD_DIR/$filename $ARTIFACT_DIR/$filename.o
diff --git a/tnslc/parse/ast.tnsl b/tnslc/parse/ast.tnsl
index 15cb276..ba8408b 100644
--- a/tnslc/parse/ast.tnsl
+++ b/tnslc/parse/ast.tnsl
@@ -59,6 +59,18 @@ struct Node {
return 0
;/
+/; _is_closing(~Token tok) [bool]
+ /; if (tok`._type !== TTYPE_DELIM)
+ return false
+ ;/
+
+ uint8 ch = tok`.data`
+ /; if (ch == ';' || ch == '}' || ch == ']' || ch == ')')
+ return true
+ ;/
+ return false
+;/
+
/; _advance_check(~utils.File fin, ~Token tok, ~uint8 eq) [bool]
/; if (tok`._type !== TTYPE_ERR && tok`.eq(eq) == true)
Token tmp = produce_next_token(fin, tok`)
@@ -161,6 +173,12 @@ struct Node {
;/
;/
+/; _ast_keyword_expr (~utils.File fin, ~Node mod, ~Token first)
+ Token tmp = produce_next_token(fin, first`)
+ first`.end()
+ first` = tmp
+;/
+
# AST types
@@ -326,7 +344,7 @@ struct Node {
/; _maybe_helper_decl (~utils.File fin, ~Node mod, ~Token first)
# either a continuation of prev type or a new type then an id
Token next = produce_next_token(fin, first`)
- /; if (next._type !== TTYPE_ERR && next.eq(",\0"))
+ /; if (next._type !== TTYPE_ERR && next.eq(",\0") || _is_closing(~next) == true)
# Another id
Node id
id.init(NTYPE_ID, first`.data)
@@ -433,7 +451,7 @@ struct Node {
return
;/
- /; if (_advance_check(fin, first, ",\0") == false && first`._type !== TTYPE_DELIM)
+ /; if (_advance_check(fin, first, ",\0") == false && _is_closing(first) == false)
_ast_print_err(first, "Expected ',' to continue the declaration list or a closing delimiter\0")
mod`.sub.push(~list)
return
@@ -441,7 +459,7 @@ struct Node {
;/
mod`.sub.push(~list)
-
+
Token next = produce_next_token(fin, first`)
first`.end()
first` = next
@@ -474,7 +492,7 @@ struct Node {
return
;/
- /; if (_advance_check(fin, first, ",\0") == false && first`._type !== TTYPE_DELIM)
+ /; if (_advance_check(fin, first, ",\0") == false && _is_closing(first) == false)
_ast_print_err(first, "Expected ',' to continue the type list or a closing delimiter\0")
mod`.sub.push(~list)
return
@@ -506,7 +524,7 @@ struct Node {
return
;/
- /; if (_advance_check(fin, first, ",\0") == false && (first`._type !== TTYPE_DELIM || first`.data` !== end))
+ /; if (_advance_check(fin, first, ",\0") == false && _is_closing(first) == false)
_ast_print_err(first, "Expected ',' to continue the type list or a closing delimiter\0")
mod`.sub.push(~list)
return
@@ -522,16 +540,114 @@ struct Node {
-# Method and function blocks
+# Method blocks
/; _ast_method (~utils.File fin, ~Node mod, ~Token first)
+
+;/
+
+
+
+# function blocks
+
+/; _ast_if (~utils.File fin, ~Node mod, ~Token first)
+;/
+
+/; _ast_loop (~utils.File fin, ~Node mod, ~Token first)
+;/
+
+/; _ast_fun_block (~utils.File fin, ~Node mod, ~Token first)
+ Token blf = first`
+ first` = produce_next_token(fin, first`)
+
+ /; loop (bool run = true; run == true && first`._type !== TTYPE_ERR)
+ /; if (_advance_check(fin, first, "if\0") == true)
+ _ast_if(fin, mod, first)
+ ;; else if (_advance_check(fin, first, "loop\0") == true)
+ _ast_loop(fin, mod, first)
+ # ;; else if (first`._type == TTYPE_USRWD)
+ # _ast_function(fin, mod, first)
+ ;; else
+ _ast_print_err(first, "Expected 'if' or 'loop' for function level block\0")
+ ;/
+
+ run = _advance_check(fin, first, ";;\0")
+ /; if (run == false && first`.eq(";/\0") == false)
+ _ast_print_err(first, "Block being skipped. Parsing will pick up after the end\0")
+ ;/
+ ;/
+
+ /; loop (int deep = 1; deep > 0 && first`._type !== TTYPE_ERR)
+ /; if (first`.eq(";/\0"))
+ deep = deep - 1
+ ;; else if (first`.eq("/;\0"))
+ deep = deep + 1
+ ;/
+
+ /; if (deep > 0)
+ Token tmp = produce_next_token(fin, first`)
+ first`.end()
+ first` = tmp
+ ;/
+ ;/
+
+ /; if (_advance_check(fin, first`, ";/\0") == false)
+ _ast_print_err(~blf, "Could not find closing ;/ for top block\0")
+ ;/
+ blf.end()
+;/
+
+/; _maybe_helper_fun (~utils.File fin, ~Node mod, ~Token first)
+ Token next = produce_next_token(fin, first`)
+ first`.end()
+ first` = next
;/
/; _ast_function (~utils.File fin, ~Node mod, ~Token first)
+ /; if (first`._type !== TTYPE_USRWD)
+ _ast_print_err(first, "[FATAL] [CMPERR] Expected function name\0")
+ return
+ ;/
+ Node fn
+ fn.init(NTYPE_FUNCTION, first`.data)
+ first` = produce_next_token(fin, first`)
+ /; if (first`.eq("(\0"))
+ _ast_list_decl(fin, ~fn, first)
+ ;/
+
+ /; if (first`.eq("[\0"))
+ _ast_list_type(fin, ~fn, first)
+ ;/
+
+ /; loop (bool run = true; run == true && first`._type !== TTYPE_ERR)
+ /; if (_advance_check(fin, first, "asm\0") == true)
+ _ast_asm(fin, mod, first)
+ ;; else if (first`.eq("/;\0") == true)
+ _ast_fun_block(fin, mod, first)
+ ;; else if (first`._type == TTYPE_KEYTP || first`.eq("{\0") == true)
+ _ast_decl(fin, mod, first)
+ ;; else if (first`._type == TTYPE_USRWD || first`.eq("~\0") == true)
+ _maybe_helper_fun(fin, mod, first)
+ ;; else if (first`._type == TTYPE_KEYWD)
+ _ast_keyword_expr(fin, mod, first)
+ ;; else if (first`._type == TTYPE_DELIM && first`.data` == ';')
+ run = false
+ ;; else
+ _ast_print_err(first, "Expected definition, expression, or sub block in function\0")
+
+ Token tmp = produce_next_token(fin, first`)
+ first`.end()
+ first` = tmp
+ ;/
+ ;/
+
+ mod`.sub.push(~fn)
;/
+
+
# Top level directives
/; _ast_import (~utils.File fin, ~Node mod, ~Token first)
@@ -618,10 +734,6 @@ struct Node {
# Parse deflist and push root node into module
_ast_list_decl(fin, ~sct, first)
mod`.sub.push(~sct)
-
- Token tmp = produce_next_token(fin, first`)
- first`.end()
- first` = tmp
;/
/; _ast_enum (~utils.File fin, ~Node mod, ~Token first)
@@ -702,9 +814,6 @@ struct Node {
;; else
_ast_print_err(first, "Expected variable name in declaration\0")
run = false
- Token tmp = produce_next_token(fin, first`)
- first`.end()
- first` = tmp
;/
;/
@@ -749,7 +858,6 @@ struct Node {
/; if (_advance_check(fin, first`, ";/\0") == false)
_ast_print_err(~blf, "Could not find closing ;/ for top block\0")
- _ast_print_err(first, "^^^ Last token before previous error\0")
;/
blf.end()
;/
@@ -790,7 +898,7 @@ struct Node {
_ast_top_block(fin, ~nmod, first)
;; else if (first`._type == TTYPE_KEYTP || first`._type == TTYPE_USRWD || first`.eq("~\0") == true || first`.eq("{\0") == true)
_ast_decl(fin, ~nmod, first)
- ;; else if (first`.eq(";/\0") == true)
+ ;; else if (first`._type == TTYPE_DELIM && first`.data` == ';')
run = false
;; else
_ast_print_err(first, "Expected 'import', 'struct', 'asm', block, or declaration in top level\0")
@@ -830,6 +938,8 @@ struct Node {
;/
;/
+ first.end()
+
fin`.close()
;/
diff --git a/tnslc/parse/tokenizer.tnsl b/tnslc/parse/tokenizer.tnsl
index e44e648..f17ea34 100644
--- a/tnslc/parse/tokenizer.tnsl
+++ b/tnslc/parse/tokenizer.tnsl
@@ -350,6 +350,7 @@ uint MAX_MULTI = 3
out.line = prev.line
out.col = prev.col
out._type = TTYPE_ERR
+ out.data = utils.strcpy("\0")
return out
;/
@@ -379,6 +380,7 @@ uint MAX_MULTI = 3
com.end()
;/
;/
+ tmp.end()
fin`.close()
return out
diff --git a/tnslc/test.tnsl b/tnslc/test.tnsl
index a6f1673..44bfaff 100644
--- a/tnslc/test.tnsl
+++ b/tnslc/test.tnsl
@@ -2,20 +2,22 @@
~uint lmao
-user.tp a
-
-user.tp(asd, asd) b
~{2}user c
struct user {
~int abcd,
- Geko efg,
~Geko hij
}
-/; whatev (~uint8 a) [uint8]
- return a{0}
+struct Geko {
+ int i
+}
+
+/; module mod
+ /; whatev (~uint8 a) [uint8]
+ return a{0}
+ ;/
;/
/; main [int]