uint16 NTYPE_MODULE = 0 uint16 NTYPE_EXPORT = 1 uint16 NTYPE_STRUCT = 2 uint16 NTYPE_TYPE = 3 uint16 NTYPE_ID = 4 uint16 NTYPE_BIN_OP = 5 uint16 NTYPE_PRE_OP = 6 uint16 NTYPE_POST_OP = 7 uint16 NTYPE_FUNCTION = 8 uint16 NTYPE_METHOD = 9 uint16 NTYPE_TLIST = 10 uint16 NTYPE_DLIST = 11 uint16 NTYPE_ELIST = 12 uint16 NTYPE_LITERAL = 13 uint16 NTYPE_KEY_TYPE = 14 uint16 NTYPE_ENUM = 15 uint16 NTYPE_ASM = 998 struct Node { uint16 _type, ~uint8 data, utils.Vector sub } /; method Node /; init (uint16 _type, ~uint8 data) self.data = data self._type = _type Node n self.sub.init(len n) ;/ /; end _delete(self.data) /; loop (uint i = 0; i < self.sub.count) [i++] ~Node cur = self.sub.get(i) cur`.end() ;/ self.sub.end() ;/ ;/ /; _get_closing_delim(uint8 ch) [uint8] /; if (ch == '/' || ch == ';') return ';' ;; else if (ch == '(') return ')' ;; else if (ch == '{') return '}' ;; else if (ch == '[') return ']' ;/ return 0 ;/ /; _advance_check(~utils.File fin, ~Token tok, ~uint8 eq) [bool] /; if (tok`.eq(eq) == true) Token tmp = produce_next_token(fin, tok`) tok`.end() tok` = tmp return true ;/ return false ;/ /; _ast_print_err (~Token tok, ~uint8 msg) _printf(msg) _printf(":\n\0") _printf(" \0") print_token(tok`) _printf("\n\0") ;/ # Top level directives /; _ast_import (~utils.File fin, ~Node mod, ~Token first) /; if (first`._type !== TTYPE_LITRL || first`.data` !== '"') _ast_print_err(first, "Expected string or import literal after 'import'\0") Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp return ;/ ~uint8 rel = utils.unquote_str(first`.data) utils.File imp = fin`.relative(rel) _delete(rel) rel = imp.path.to_cstr('/') _printf("Importing \0") _printf(rel) _printf("\n\0") _delete(rel) _ast_file(~imp, mod) imp.end() Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp ;/ /; _ast_asm (~utils.File fin, ~Node mod, ~Token first) /; if (first`._type !== TTYPE_LITRL || first`.data` !== '"') _ast_print_err(first, "Expected string literal after 'ast'\0") Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp return ;/ Node an an.init(NTYPE_ASM, utils.unquote_str(first`.data)) mod`.sub.push(~an) Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp ;/ /; _ast_struct (~utils.File fin, ~Node mod, ~Token first) # Identifier check /; if (first`._type !== TTYPE_USRWD) _ast_print_err(first, "Expected new identifier for typedef after 'struct'\0") Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp return ;/ # Root struct node Node sct sct.init(NTYPE_STRUCT, first`.data) first` = produce_next_token(fin, first`) # 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_def(fin, mod, 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) Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp ;/ /; _ast_top_block(~utils.File fin, ~Node mod, ~Token first) Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp ;/ /; _ast_module(~utils.File fin, ~Node mod, ~Token first) Token tmp = produce_next_token(fin, first`) first`.end() first` = tmp ;/ /; _ast_file (~utils.File fin, ~Node mod) fin`.open() Token first = produce_first_token(fin) /; loop (first._type !== TTYPE_ERR) /; if (_advance_check(fin, ~first, "import\0") == true) _ast_import(fin, mod, ~first) ;; else if (_advance_check(fin, ~first, "struct\0") == true) _ast_struct(fin, mod, ~first) ;; else if (_advance_check(fin, ~first, "asm\0") == true) _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) _ast_decl(fin, mod, ~first) ;; else _printf("Expected 'import', 'struct', 'asm', block, or declaration in top level:\n\0") _printf(" \0") print_token(first) _printf("\n\0") Token tmp = produce_next_token(fin, first) first.end() first = tmp ;/ ;/ fin`.close() ;/ /; generate_ast (~utils.File fin) [Node] Node out utils.Vector v v.init(1) out.init(NTYPE_MODULE, v.as_cstr()) _ast_file(fin, ~out) return out ;/ # # Print out the AST from a specific node # /; print_node_type (~Node n) /; if (n`._type == NTYPE_MODULE) _printf("Mod\0") ;; else if (n`._type == NTYPE_EXPORT) _printf("Exported Module\0") ;; else if (n`._type == NTYPE_STRUCT) _printf("Struct\0") ;; else if (n`._type == NTYPE_ID) _printf("ID\0") ;; else if (n`._type == NTYPE_BIN_OP) _printf("Binary OP\0") ;; else if (n`._type == NTYPE_PRE_OP) _printf("Pre OP\0") ;; else if (n`._type == NTYPE_POST_OP) _printf("Post OP\0") ;; else if (n`._type == NTYPE_FUNCTION) _printf("Function\0") ;; else if (n`._type == NTYPE_METHOD) _printf("Method\0") ;; else if (n`._type == NTYPE_ASM) _printf("ASM\0") ;/ ;/ /; print_node_head (~Node n) _printf("{ NODE_TYPE: \0") print_node_type(n) _printf(", DATA: \0") _printf(n`.data) _printf("\n\0") ;/ /; print_ast_rec(~Node n, uint depth) /; loop (int i = 0; i < depth) [i++] _printf(" \0") ;/ print_node_head(n) /; loop (uint i = 0; i < n`.sub.count) [i++] ~Node s = n`.sub.get(i) print_ast_rec(s, depth + 1) ;/ /; loop (int i = 0; i < depth) [i++] _printf(" \0") ;/ _printf("}\n\0") ;/ /; print_ast (~Node n) print_ast_rec(n, 0) ;/