Starting to refactor the linked-list nature
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 8 Jul 2020 18:54:21 +0000 (13:54 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 8 Jul 2020 18:54:21 +0000 (13:54 -0500)
docs/new_symbol_resolution [new file with mode: 0644]
docs/optimizations [new file with mode: 0644]
include/onyxparser.h
onyx
src/onyx.c
src/onyxparser.c

diff --git a/docs/new_symbol_resolution b/docs/new_symbol_resolution
new file mode 100644 (file)
index 0000000..71c909c
--- /dev/null
@@ -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 (file)
index 0000000..abbe5aa
--- /dev/null
@@ -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
+
index 76886e14dcb448ffc406a1a3605ac2862508951f..3774300992a76bc410fed0311b28e6d3de514545 100644 (file)
@@ -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 5b8ecd947fd64cc24d11ac298b2521f261bdeaa2..e0cd5c77f1552d18e67b77a739aeb7e08a87196d 100755 (executable)
Binary files a/onyx and b/onyx differ
index 4fbe8464cdca1a25b7dc91234e2e11cda1bfc864..d843c498b10882ee993e18d534fd26543ab6acd7 100644 (file)
@@ -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) {
index f0590eb26ea7d7afc7048e7542917edf06943dd8..83f2b627b801469e3986ac4469e3edfb104da4e3 100644 (file)
@@ -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;
 }