diff options
Diffstat (limited to 'tnslc')
-rw-r--r-- | tnslc/parse/ast.tnsl | 197 |
1 files changed, 194 insertions, 3 deletions
diff --git a/tnslc/parse/ast.tnsl b/tnslc/parse/ast.tnsl index a01a185..5bf84c8 100644 --- a/tnslc/parse/ast.tnsl +++ b/tnslc/parse/ast.tnsl @@ -15,6 +15,7 @@ uint16 NTYPE_ELIST = 12 uint16 NTYPE_LITERAL = 13 uint16 NTYPE_KEY_TYPE = 14 uint16 NTYPE_ENUM = 15 +uint16 NTYPE_DECL = 16 uint16 NTYPE_ASM = 998 struct Node { @@ -74,6 +75,119 @@ struct Node { _printf("\n\0") ;/ + + +# AST values + +/; _ast_value (~utils.File fin, ~Node mod, ~Token first) + +;/ + +/; _ast_type (~utils.File fin, ~Node mod, ~Token first) + +;/ + + + +# AST lists + +/; _ast_list_decl (~utils.File fin, ~Node mod, ~Token first) + Node list + list.init(NTYPE_DLIST) + + uint8 end = _get_closing_delim(first`.data`) + + first` = produce_next_token(fin, first`) + + /; loop (first`._type !== TTYPE_ERR && first`.data` !== end) + # TODO + ;/ + + mod`.sub.push(~list) + + Token next = produce_next_token(fin, first`) + first`.end() + first` = next +;/ + +/; _ast_list_enum (~utils.File fin, ~Node mod, ~Token first) + Node list + list.init(NTYPE_ELIST) + + uint8 end = _get_closing_delim(first`.data`) + + first` = produce_next_token(fin, first`) + + /; loop (first`._type !== TTYPE_ERR && first`.data` !== end) + /; if (first`._type == TTYPE_USRWD || first`._type == TTYPE_KEYTP || first`.eq("~\0") == true || first`.eq("{\0") == true) + Node enum_id + enum_id.init(NTYPE_ID, first`.data) + + first` = produce_next_token(fin, first`) + + /; if (_advance_check(fin, first, "=\0")) + _ast_value(fin, ~enum_id, first) + ;/ + + list.sub.push(~enum_id) + + /; if (_advance_check(fin, first, ",\0") == false && first`._type !== TTYPE_DELIM) + _ast_print_err(first, "Expected ',' to continue the enum list or a closing delimiter\0") + mod`.sub.push(~list) + return + ;/ + ;; else + _ast_print_err(first, "Expected identifier in body of enum declaration\0") + mod`.sub.push(~list) + return + ;/ + ;/ + + mod`.sub.push(~list) + + Token next = produce_next_token(fin, first`) + first`.end() + first` = next +;/ + +/; _ast_list_type (~utils.File fin, ~Node mod, ~Token first) + Node list + list.init(NTYPE_TLIST) + + uint8 end = _get_closing_delim(first`.data`) + + first` = produce_next_token(fin, first`) + + /; loop (first`._type !== TTYPE_ERR && first`.data` !== end) + + /; if (first`._type == TTYPE_USRWD || first`._type == TTYPE_KEYTP || first`.eq("~\0") == true || first`.eq("{\0") == true) + _ast_type(fin, ~list, first) + + /; if (_advance_check(fin, first, ",\0") == false && first`._type !== TTYPE_DELIM) + _ast_print_err(first, "Expected ',' to continue the type list or a closing delimiter\0") + mod`.sub.push(~list) + return + ;/ + ;; else + _ast_print_err(first, "Expected type in type list\0") + mod`.sub.push(~list) + return + ;/ + ;/ + + mod`.sub.push(~list) + + Token next = produce_next_token(fin, first`) + first`.end() + first` = next +;/ + + + +# Method and function blocks + + + # Top level directives /; _ast_import (~utils.File fin, ~Node mod, ~Token first) @@ -158,7 +272,7 @@ struct Node { ;/ # Parse deflist and push root node into module - _ast_list_def(fin, mod, first) + _ast_list_decl(fin, ~sct, first) mod`.sub.push(~sct) Token tmp = produce_next_token(fin, first`) @@ -166,11 +280,88 @@ struct Node { first` = tmp ;/ -/; _ast_decl (~utils.File fin, ~Node mod, ~Token first) +/; _ast_enum (~utils.File fin, ~Node mod, ~Token first) + # Identifier check + /; if (first`._type !== TTYPE_USRWD) + _ast_print_err(first, "Expected new identifier for def after 'enum'\0") + + Token tmp = produce_next_token(fin, first`) + first`.end() + first` = tmp + + return + ;/ + + # Root struct node + Node sct + sct.init(NTYPE_ENUM, first`.data) + first` = produce_next_token(fin, first`) + + # Check for enum type + /; if (first`.data` == '[') + _ast_list_type(fin, ~sct, first) + + Token tmp = produce_next_token(fin, first`) + first`.end() + first` = tmp + ;/ + + # Check for def list + /; if (first`._type !== TTYPE_DELIM || first`.data` !== '{') + _ast_print_err(first, "Expected new identifier for typedef after 'struct'\0") + mod`.sub.push(~sct) + + Token tmp = produce_next_token(fin, first`) + first`.end() + first` = tmp + + return + ;/ + + # Parse deflist and push root node into module + _ast_list_enum(fin, ~sct, first) + mod`.sub.push(~sct) + Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp +;/ + +/; _ast_decl (~utils.File fin, ~Node mod, ~Token first) + Node decl + decl.init(NTYPE_DECL, utils.strcpy("\0")) + + _ast_type(fin, ~decl, first) + + /; loop (bool run = true; run == true) + /; if (first`._type == TTYPE_USRWD) + Node var + var.init(NTYPE_ID, first`.data) + + first` = produce_next_token(fin, first`) + /; if (first`.eq("=\0")) + Token tmp = produce_next_token(fin, first`) + first`.end() + first` = tmp + _ast_value(fin, ~var, first) + ;/ + + decl.sub.push(~var) + + /; if (first`.eq(",\0") == false) + run = false + ;; else + Token tmp = produce_next_token(fin, first`) + first`.end() + first` = tmp + ;/ + ;; else + _ast_print_err("Expected variable name in declaration\0") + run = false + ;/ + ;/ + mod`.sub.push(~decl) ;/ /; _ast_top_block(~utils.File fin, ~Node mod, ~Token first) @@ -200,7 +391,7 @@ struct Node { _ast_asm(fin, mod, ~first) ;; else if (first.eq("/;\0") == true) _ast_top_block(fin, mod, ~first) - ;; else if (first._type == TTYPE_KEYTP || first._type == TTYPE_USRWD || first.eq("~\0") == true) + ;; else if (first._type == TTYPE_KEYTP || first._type == TTYPE_USRWD || first.eq("~\0") == true || first.eq("{\0") == true) _ast_decl(fin, mod, ~first) ;; else _printf("Expected 'import', 'struct', 'asm', block, or declaration in top level:\n\0") |