From 0d8ed3e169dba42fc43a4544a9c28fc63cf3053f Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sun, 4 Aug 2024 03:06:08 -0400 Subject: [tnslc] Function ast barebones --- tnslc/build.sh | 2 +- tnslc/parse/ast.tnsl | 140 ++++++++++++++++++++++++++++++++++++++++----- tnslc/parse/tokenizer.tnsl | 2 + tnslc/test.tnsl | 14 +++-- 4 files changed, 136 insertions(+), 22 deletions(-) (limited to 'tnslc') 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] -- cgit v1.2.3