summaryrefslogtreecommitdiff
path: root/tnslc/parse
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc/parse')
-rw-r--r--tnslc/parse/ast.tnsl140
-rw-r--r--tnslc/parse/tokenizer.tnsl2
2 files changed, 127 insertions, 15 deletions
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