From: Brendan Hansen Date: Wed, 8 Jul 2020 18:54:21 +0000 (-0500) Subject: Starting to refactor the linked-list nature X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=4e9c1e7ccebfa6784746d6e8f59f0e3d9283d4a5;p=onyx.git Starting to refactor the linked-list nature --- diff --git a/docs/new_symbol_resolution b/docs/new_symbol_resolution new file mode 100644 index 00000000..71c909ca --- /dev/null +++ b/docs/new_symbol_resolution @@ -0,0 +1,19 @@ +The current way I do symbol resolution is: + - Join all top level symbols at parse time into a single struct + - Add all top level symbols to a string table that maps from + their name to their AST node + - Then step through every function linearly and resolve each symbol using the table + * Function locals are added when they are declared and then removed at the end + of their scope as would be expected + +This method works, but it is not great and feels like a hack. + - References to other things are just pointers to the AST node + - This produces a heavy reliance on the AST instead of other, more efficient data structures + + + + +PROPOSED NEW METHOD: + Every top level declaration will add a declinfo entry that will contain the following information: + - Identifier + - Pointer to AST node diff --git a/docs/optimizations b/docs/optimizations new file mode 100644 index 00000000..abbe5aaf --- /dev/null +++ b/docs/optimizations @@ -0,0 +1,11 @@ +Some optimizations to make to the output WASM: + [ ] local.set followed by local.get turns into local.tee + [ ] Dead code elimination + - Function level: If a function is not explicitly called or exported, it may be removed + - Local level: If a local is not read, it may be removed + [ ] Add compile-time evaluation for simple operations + [ ] If statement compile-time condition evaluation + - If the condition of an if statement is compile time known, only generate the case that + is used + [ ] Inline-ing functions that have been explicitly marked + diff --git a/include/onyxparser.h b/include/onyxparser.h index 76886e14..37743009 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -24,6 +24,6 @@ const char* onyx_ast_node_kind_string(AstNodeKind kind); void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstNodeKind kind); OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs); void onyx_parser_free(OnyxParser* parser); -AstNode* onyx_parse(OnyxParser *parser); +bh_arr(AstNode *) onyx_parse(OnyxParser *parser); #endif // #ifndef ONYXPARSER_H diff --git a/onyx b/onyx index 5b8ecd94..e0cd5c77 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyx.c b/src/onyx.c index 4fbe8464..d843c498 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -106,7 +106,7 @@ static void compile_opts_free(OnyxCompileOptions* opts) { bh_arr_free(opts->files); } -static AstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { +static bh_arr(AstNode *) parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) { // NOTE: Maybe don't want to recreate the tokenizer and parser for every file if (compiler_state->options->verbose_output) bh_printf("[Lexing] %s\n", file_contents->filename); @@ -142,42 +142,30 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc); fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename); - AstNode* root_node = parse_source_file(compiler_state, &fc); + bh_arr(AstNode *) top_nodes = parse_source_file(compiler_state, &fc); - if (compiler_state->options->print_ast) { - onyx_ast_print(root_node, 0); - bh_printf("\n"); - } - - AstNode* walker = root_node; - while (walker) { - switch (walker->kind) { + bh_arr_each(AstNode *, node, top_nodes) { + switch ((*node)->kind) { case AST_NODE_KIND_USE: - bh_arr_push(compiler_state->program.uses, (AstNodeUse *) walker); + bh_arr_push(compiler_state->program.uses, (AstNodeUse *) (*node)); break; case AST_NODE_KIND_GLOBAL: - bh_arr_push(compiler_state->program.globals, (AstNodeGlobal *) walker); + bh_arr_push(compiler_state->program.globals, (AstNodeGlobal *) (*node)); break; case AST_NODE_KIND_FOREIGN: - bh_arr_push(compiler_state->program.foreigns, (AstNodeForeign *) walker); + bh_arr_push(compiler_state->program.foreigns, (AstNodeForeign *) (*node)); break; case AST_NODE_KIND_FUNCTION: - bh_arr_push(compiler_state->program.functions, (AstNodeFunction *) walker); - break; - - case AST_NODE_KIND_PROGRAM: - // Dummy initial node + bh_arr_push(compiler_state->program.functions, (AstNodeFunction *) (*node)); break; default: assert(("Invalid top level node", 0)); break; } - - walker = walker->next; } bh_arr_each(AstNodeUse *, use_node, compiler_state->program.uses) { diff --git a/src/onyxparser.c b/src/onyxparser.c index f0590eb2..83f2b627 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -32,10 +32,6 @@ static void parser_next_token(OnyxParser* parser); static void parser_prev_token(OnyxParser* parser); static b32 is_terminating_token(TokenType token_type); static OnyxToken* expect(OnyxParser* parser, TokenType token_type); -static AstNodeScope* enter_scope(OnyxParser* parser); -static AstNodeScope* leave_scope(OnyxParser* parser); -static void insert_identifier(OnyxParser* parser, AstNode* ident, b32 is_local); -static void remove_identifier(OnyxParser* parser, AstNode* ident); static AstNodeNumLit* parse_numeric_literal(OnyxParser* parser); static AstNodeTyped* parse_factor(OnyxParser* parser); static AstNodeTyped* parse_expression(OnyxParser* parser); @@ -901,22 +897,21 @@ void onyx_parser_free(OnyxParser* parser) { bh_table_free(parser->identifiers); } -AstNode* onyx_parse(OnyxParser *parser) { - AstNode* program = make_node(AstNode, AST_NODE_KIND_PROGRAM); +bh_arr(AstNode *) onyx_parse(OnyxParser *parser) { + bh_arr(AstNode *) top_level_nodes = NULL; + bh_arr_new(global_heap_allocator, top_level_nodes, 4); - AstNode** prev_stmt = &program->next; - AstNode* curr_stmt = NULL; while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) { - curr_stmt = parse_top_level_statement(parser); + AstNode* curr_stmt = parse_top_level_statement(parser); // Building a linked list of statements down the "next" chain if (curr_stmt != NULL && curr_stmt != &error_node) { - *prev_stmt = curr_stmt; - - while (curr_stmt->next != NULL) curr_stmt = curr_stmt->next; - prev_stmt = &curr_stmt->next; + while (curr_stmt != NULL) { + bh_arr_push(top_level_nodes, curr_stmt); + curr_stmt = curr_stmt->next; + } } } - return program; + return top_level_nodes; }