Code cleanup and optimizations
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 2 Jul 2020 21:46:29 +0000 (16:46 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 2 Jul 2020 21:46:29 +0000 (16:46 -0500)
12 files changed:
include/onyxparser.h
include/onyxsempass.h
include/onyxwasm.h
onyx
progs/test.onyx
src/onyx.c
src/onyxparser.c
src/onyxsempass.c
src/onyxsymres.c
src/onyxtypecheck.c
src/onyxutils.c
src/onyxwasm.c

index 137a1987d7f3226503fe29c3c2b5f96161ececb1..1adf82870c7dcedaeb537a54dd73e06719f9d7ca 100644 (file)
@@ -16,12 +16,11 @@ typedef struct OnyxAstNodeBlock OnyxAstNodeBlock;
 typedef struct OnyxAstNodeIf OnyxAstNodeIf;
 typedef struct OnyxAstNodeWhile OnyxAstNodeWhile;
 typedef struct OnyxAstNodeParam OnyxAstNodeParam;
-typedef struct OnyxAstNodeFuncDef OnyxAstNodeFuncDef;
+typedef struct OnyxAstNodeFunction OnyxAstNodeFunction;
 typedef struct OnyxAstNodeForeign OnyxAstNodeForeign;
 typedef struct OnyxAstNodeGlobal OnyxAstNodeGlobal;
 typedef struct OnyxAstNodeCall OnyxAstNodeCall;
 typedef struct OnyxAstNodeUse OnyxAstNodeUse;
-typedef struct OnyxAstNodeFile OnyxAstNodeFile;
 
 typedef struct OnyxParser {
     OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts
@@ -41,7 +40,7 @@ typedef enum OnyxAstNodeKind {
     ONYX_AST_NODE_KIND_PROGRAM,
     ONYX_AST_NODE_KIND_USE,
 
-    ONYX_AST_NODE_KIND_FUNCDEF,
+    ONYX_AST_NODE_KIND_FUNCTION,
     ONYX_AST_NODE_KIND_FOREIGN,
     ONYX_AST_NODE_KIND_BLOCK,
     ONYX_AST_NODE_KIND_SCOPE,
@@ -222,7 +221,7 @@ struct OnyxAstNodeWhile {
     OnyxAstNodeBlock *body;
 };
 
-struct OnyxAstNodeFuncDef {
+struct OnyxAstNodeFunction {
     OnyxAstNodeKind kind;
     u32 flags;
     OnyxToken *token; // This will point to the symbol token to identify it
@@ -262,7 +261,7 @@ struct OnyxAstNodeCall {
     u64 data;
     OnyxAstNode *next;
     OnyxAstNode *callee;        // NOTE: Function definition node
-    OnyxAstNode *arguments;        // NOTE: Expressions that form the actual param list
+    OnyxAstNode *arguments;     // NOTE: Expressions that form the actual param list
                                 // They will be chained down using the "next" property
                                 // unless this becomes used by something else
 };
@@ -277,16 +276,6 @@ struct OnyxAstNodeUse {
     OnyxToken *filename;
 };
 
-struct OnyxAstNodeFile {
-    OnyxAstNodeKind kind;
-    u32 flags;
-    OnyxToken *token;           // NOTE: unused
-    OnyxTypeInfo *type;         // NOTE: unused
-    u64 data;
-    OnyxAstNodeFile *next;      // NOTE: next file
-    OnyxAstNode *contents;      // NOTE: the first top-level element
-};
-
 union OnyxAstNode {
 
     // Generic node structure for capturing all binary ops and statements
@@ -302,7 +291,6 @@ union OnyxAstNode {
     };
 
     OnyxAstNodeBlock as_block;
-    OnyxAstNodeFuncDef as_funcdef;
     OnyxAstNodeParam as_param;
     OnyxAstNodeLocal as_local;
     OnyxAstNodeScope as_scope;
@@ -310,18 +298,25 @@ union OnyxAstNode {
     OnyxAstNodeNumLit as_numlit;
     OnyxAstNodeBinOp as_binop;
     OnyxAstNodeUnaryOp as_unaryop;
-    OnyxAstNodeForeign as_foreign;
-    OnyxAstNodeGlobal as_global;
     OnyxAstNodeIf as_if;
     OnyxAstNodeWhile as_while;
     OnyxAstNodeUse as_use;
-    OnyxAstNodeFile as_file;
+    OnyxAstNodeFunction as_function;
+    OnyxAstNodeGlobal as_global;
+    OnyxAstNodeForeign as_foreign;
 };
 
+typedef struct OnyxProgram {
+    bh_arr(OnyxAstNodeUse *) uses;
+    bh_arr(OnyxAstNodeGlobal *) globals;
+    bh_arr(OnyxAstNodeFunction *) functions;
+    bh_arr(OnyxAstNodeForeign *) foreigns;
+} OnyxProgram;
+
 const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind);
 void* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind);
 OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs);
 void onyx_parser_free(OnyxParser* parser);
-OnyxAstNodeFile* onyx_parse(OnyxParser *parser);
+OnyxAstNode* onyx_parse(OnyxParser *parser);
 
 #endif // #ifndef ONYXPARSER_H
index 2174c3f35a542485f4024503542637e844ac274d..eec0272281e4a37db8e0762ad2eedf075188c4f2 100644 (file)
@@ -28,13 +28,13 @@ typedef struct OnyxSemPassState {
 } OnyxSemPassState;
 
 // NOTE: Resolving all symbols in the tree
-void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNodeFile* root_node);
+void onyx_resolve_symbols(OnyxSemPassState* state, OnyxProgram* program);
 
 // NOTE: Inferring and checking types in the tree
-void onyx_type_check(OnyxSemPassState* state, OnyxAstNodeFile* root_node);
+void onyx_type_check(OnyxSemPassState* state, OnyxProgram* program);
 
 // NOTE: Full semantic pass
 OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs);
-void onyx_sempass(OnyxSemPassState* state, OnyxAstNodeFile* root_node);
+void onyx_sempass(OnyxSemPassState* state, OnyxProgram* program);
 
 #endif
index 327b08b71dcfebad4e778cfa660cc1215c144b28..1e6dcb901456d982f3d4de362464e4bbf8e0b93c 100644 (file)
@@ -308,7 +308,7 @@ typedef struct OnyxWasmModule {
 } OnyxWasmModule;
 
 OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs);
-void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program);
+void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program);
 void onyx_wasm_module_free(OnyxWasmModule* module);
 void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file);
 
diff --git a/onyx b/onyx
index c8eaac115b5090e2c5c48a211ceb77d0c451fd4f..28115a9de62cdf4498bb6fd3a3889669ce38740f 100755 (executable)
Binary files a/onyx and b/onyx differ
index 746003845519d3701124189d9a797771afa481a6..6a227be43e50d05e29348f8dd1eecdb5bc599238 100644 (file)
@@ -49,6 +49,8 @@ export main2 :: proc {
 }
 
 export main :: proc {
+    print_bool(in_unit_circle(0.5f, 0.5f));
+
     big_num := fib(factorial(4));
     something :: other_value(0);
 
index c7decffffaf08ad36dbb9e6b7a4176bcfcd275ae..4c1975c4b912d13cef43506ad8ee88603f04fe86 100644 (file)
@@ -55,10 +55,8 @@ typedef struct CompilerState {
     bh_table(bh_file_contents) loaded_files;
     bh_arr(const char *) queued_files;
 
-    OnyxAstNodeFile* first_file;
-    OnyxAstNodeFile* last_processed_file;
-
     OnyxMessages msgs;
+    OnyxProgram program;
     OnyxWasmModule wasm_mod;
 } CompilerState;
 
@@ -100,7 +98,7 @@ void compile_opts_free(OnyxCompileOptions* opts) {
     bh_arr_free(opts->files);
 }
 
-OnyxAstNodeFile* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) {
+OnyxAstNode* 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
     OnyxTokenizer tokenizer = onyx_tokenizer_create(compiler_state->token_alloc, file_contents);
     bh_printf("[Lexing]       %s\n", file_contents->filename);
@@ -126,44 +124,57 @@ CompilerProgress process_source_file(CompilerState* compiler_state, OnyxCompileO
     bh_file_contents fc = bh_file_read_contents(compiler_state->token_alloc, &file);
     bh_file_close(&file);
 
-    bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc);
     // NOTE: Need to reget the value out of the table so token references work
+    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);
 
-    OnyxAstNodeFile* file_node = parse_source_file(compiler_state, &fc);
+    OnyxAstNode* root_node = parse_source_file(compiler_state, &fc);
 
     if (opts->print_ast) {
-        onyx_ast_print((OnyxAstNode *) file_node, 0);
+        onyx_ast_print(root_node, 0);
         bh_printf("\n");
     }
 
-    if (!compiler_state->first_file)
-        compiler_state->first_file = file_node;
-
-    if (compiler_state->last_processed_file)
-        compiler_state->last_processed_file->next = file_node;
-
-    compiler_state->last_processed_file = file_node;
-
-
-    // HACK: This is very cobbled together right now but it will
-    // do for now
-    OnyxAstNode* walker = file_node->contents;
+    OnyxAstNode* walker = root_node;
     while (walker) {
-        if (walker->kind == ONYX_AST_NODE_KIND_USE) {
-            OnyxAstNodeUse* use_node = &walker->as_use;
-
-            char* formatted_name = bh_aprintf(
-                    global_heap_allocator,
-                    "%b.onyx",
-                    use_node->filename->token, use_node->filename->length);
-
-            bh_arr_push(compiler_state->queued_files, formatted_name);
+        switch (walker->kind) {
+            case ONYX_AST_NODE_KIND_USE:
+                bh_arr_push(compiler_state->program.uses, &walker->as_use);
+                break;
+
+            case ONYX_AST_NODE_KIND_GLOBAL:
+                bh_arr_push(compiler_state->program.globals, &walker->as_global);
+                break;
+
+            case ONYX_AST_NODE_KIND_FOREIGN:
+                bh_arr_push(compiler_state->program.foreigns, &walker->as_foreign);
+                break;
+
+            case ONYX_AST_NODE_KIND_FUNCTION:
+                bh_arr_push(compiler_state->program.functions, &walker->as_function);
+                break;
+
+            case ONYX_AST_NODE_KIND_PROGRAM:
+                // Dummy initial node
+                break;
+
+            default:
+                assert(("Invalid top level node", 0));
+                break;
         }
 
         walker = walker->next;
     }
 
+    bh_arr_each(OnyxAstNodeUse *, use_node, compiler_state->program.uses) {
+        char* formatted_name = bh_aprintf(
+                global_heap_allocator,
+                "%b.onyx",
+                (*use_node)->filename->token, (*use_node)->filename->length);
+
+        bh_arr_push(compiler_state->queued_files, formatted_name);
+    }
+
 
     if (onyx_message_has_errors(&compiler_state->msgs)) {
         return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
@@ -212,7 +223,7 @@ i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) {
     // NOTE: Check types and semantic rules
     bh_printf("[Checking semantics]\n");
     OnyxSemPassState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs);
-    onyx_sempass(&sp_state, compiler_state->first_file);
+    onyx_sempass(&sp_state, &compiler_state->program);
 
     if (onyx_message_has_errors(&compiler_state->msgs)) {
         return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
@@ -222,7 +233,7 @@ i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) {
     // NOTE: Generate WASM instructions
     bh_printf("[Generating WASM]\n");
     compiler_state->wasm_mod = onyx_wasm_module_create(opts->allocator, &compiler_state->msgs);
-    onyx_wasm_module_compile(&compiler_state->wasm_mod, compiler_state->first_file);
+    onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->program);
 
     if (onyx_message_has_errors(&compiler_state->msgs)) {
         return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN;
@@ -259,9 +270,20 @@ int main(int argc, char *argv[]) {
 
     OnyxCompileOptions compile_opts = compile_opts_parse(global_heap_allocator, argc, argv);
     CompilerState compile_state = {
+        .program = {
+            .uses = NULL,
+            .foreigns = NULL,
+            .globals = NULL,
+            .functions = NULL
+        },
         .wasm_mod = { 0 }
     };
 
+    bh_arr_new(global_heap_allocator, compile_state.program.uses, 4);
+    bh_arr_new(global_heap_allocator, compile_state.program.foreigns, 4);
+    bh_arr_new(global_heap_allocator, compile_state.program.globals, 4);
+    bh_arr_new(global_heap_allocator, compile_state.program.functions, 4);
+
     CompilerProgress compiler_progress = ONYX_COMPILER_PROGRESS_FAILED_READ;
 
     switch (compile_opts.action) {
index 5cf6f232b0118d5828f85fdd488bee0544dd2dac..d3379eba08d2f3f79b28c678ba139861cdb814f2 100644 (file)
@@ -8,7 +8,7 @@ static const char* ast_node_names[] = {
     "PROGRAM",
     "USE",
 
-    "FUNCDEF",
+    "FUNCTION",
     "FOREIGN",
     "BLOCK",
     "SCOPE",
@@ -77,7 +77,7 @@ static OnyxAstNodeBlock* parse_block(OnyxParser* parser);
 static OnyxAstNode* parse_statement(OnyxParser* parser);
 static OnyxTypeInfo* parse_type(OnyxParser* parser);
 static OnyxAstNodeParam* parse_function_params(OnyxParser* parser);
-static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser);
+static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser);
 static OnyxAstNode* parse_top_level_statement(OnyxParser* parser);
 
 static void parser_next_token(OnyxParser* parser) {
@@ -689,10 +689,10 @@ static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) {
     return first_param;
 }
 
-static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser) {
+static OnyxAstNodeFunction* parse_function_definition(OnyxParser* parser) {
     expect(parser, TOKEN_TYPE_KEYWORD_PROC);
 
-    OnyxAstNodeFuncDef* func_def = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCDEF);
+    OnyxAstNodeFunction* func_def = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCTION);
 
     OnyxAstNodeParam* params = parse_function_params(parser);
     func_def->params = params;
@@ -896,10 +896,10 @@ void onyx_parser_free(OnyxParser* parser) {
     bh_table_free(parser->identifiers);
 }
 
-OnyxAstNodeFile* onyx_parse(OnyxParser *parser) {
-    OnyxAstNodeFile* program = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM);
+OnyxAstNode* onyx_parse(OnyxParser *parser) {
+    OnyxAstNode* program = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM);
 
-    OnyxAstNode** prev_stmt = &program->contents;
+    OnyxAstNode** prev_stmt = &program->next;
     OnyxAstNode* curr_stmt = NULL;
     while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) {
         curr_stmt = parse_top_level_statement(parser);
index 9ce783a8bdda3aa26e5fbd96649074111a3f2e9d..856055f587ce8e8cdc1185e649fec4de0929d448 100644 (file)
@@ -23,80 +23,68 @@ OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc
 // WASM, this function may not be needed. It brings all of the locals
 // defined in sub-scopes up to the function-block level. This is a
 // requirement of WASM, but not of other targets.
-static void collapse_scopes(OnyxAstNodeFile* root_node) {
+static void collapse_scopes(OnyxProgram* program) {
     bh_arr(OnyxAstNodeBlock*) traversal_queue = NULL;
     bh_arr_new(global_scratch_allocator, traversal_queue, 4);
     bh_arr_set_length(traversal_queue, 0);
 
-    OnyxAstNode* walker;
-    OnyxAstNodeFile* top_walker = root_node;
-    while (top_walker) {
+    bh_arr_each(OnyxAstNodeFunction *, func, program->functions) {
+        OnyxAstNodeScope* top_scope = (*func)->body->scope;
 
-        walker = top_walker->contents;
-        while (walker) {
-            if (walker->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
-                OnyxAstNodeScope* top_scope = walker->as_funcdef.body->scope;
+        bh_arr_push(traversal_queue, (*func)->body);
+        while (!bh_arr_is_empty(traversal_queue)) {
+            OnyxAstNodeBlock* block = traversal_queue[0];
 
-                bh_arr_push(traversal_queue, walker->as_funcdef.body);
-                while (!bh_arr_is_empty(traversal_queue)) {
-                    OnyxAstNodeBlock* block = traversal_queue[0];
+            if (block->kind == ONYX_AST_NODE_KIND_IF) {
+                OnyxAstNodeIf* if_node = (OnyxAstNodeIf *) block;
+                if (if_node->true_block)
+                    bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->true_block);
 
-                    if (block->kind == ONYX_AST_NODE_KIND_IF) {
-                        OnyxAstNodeIf* if_node = (OnyxAstNodeIf *) block;
-                        if (if_node->true_block)
-                            bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->true_block);
+                if (if_node->false_block)
+                    bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->false_block);
 
-                        if (if_node->false_block)
-                            bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->false_block);
+            } else {
 
-                    } else {
+                if (block->scope != top_scope && block->scope->last_local != NULL) {
+                    OnyxAstNodeLocal* last_local = block->scope->last_local;
+                    while (last_local && last_local->prev_local != NULL) last_local = last_local->prev_local;
 
-                        if (block->scope != top_scope && block->scope->last_local != NULL) {
-                            OnyxAstNodeLocal* last_local = block->scope->last_local;
-                            while (last_local && last_local->prev_local != NULL) last_local = last_local->prev_local;
-
-                            last_local->prev_local = top_scope->last_local;
-                            top_scope->last_local = block->scope->last_local;
-                            block->scope->last_local = NULL;
-                        }
-
-                        OnyxAstNode* walker = block->body;
-                        while (walker) {
-                            if (walker->kind == ONYX_AST_NODE_KIND_BLOCK) {
-                                bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker);
+                    last_local->prev_local = top_scope->last_local;
+                    top_scope->last_local = block->scope->last_local;
+                    block->scope->last_local = NULL;
+                }
 
-                            } else if (walker->kind == ONYX_AST_NODE_KIND_WHILE) {
-                                bh_arr_push(traversal_queue, walker->as_while.body);
+                OnyxAstNode* walker = block->body;
+                while (walker) {
+                    if (walker->kind == ONYX_AST_NODE_KIND_BLOCK) {
+                        bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker);
 
-                            } else if (walker->kind == ONYX_AST_NODE_KIND_IF) {
-                                if (walker->as_if.true_block)
-                                    bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.true_block);
+                    } else if (walker->kind == ONYX_AST_NODE_KIND_WHILE) {
+                        bh_arr_push(traversal_queue, walker->as_while.body);
 
-                                if (walker->as_if.false_block)
-                                    bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.false_block);
-                            }
+                    } else if (walker->kind == ONYX_AST_NODE_KIND_IF) {
+                        if (walker->as_if.true_block)
+                            bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.true_block);
 
-                            walker = walker->next;
-                        }
+                        if (walker->as_if.false_block)
+                            bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.false_block);
                     }
 
-                    bh_arr_deleten(traversal_queue, 0, 1);
+                    walker = walker->next;
                 }
             }
 
-            walker = walker->next;
+            bh_arr_deleten(traversal_queue, 0, 1);
         }
-
-        top_walker = top_walker->next;
     }
 }
 
-void onyx_sempass(OnyxSemPassState* state, OnyxAstNodeFile* root_node) {
-    onyx_resolve_symbols(state, root_node);
+void onyx_sempass(OnyxSemPassState* state, OnyxProgram* program) {
+    onyx_resolve_symbols(state, program);
     if (onyx_message_has_errors(state->msgs)) return;
 
-    onyx_type_check(state, root_node);
+    onyx_type_check(state, program);
     if (onyx_message_has_errors(state->msgs)) return;
 
-    collapse_scopes(root_node);
+    collapse_scopes(program);
 }
index 636f05b6e9bb84d6a22a6a93ab7019c5bd6f384d..37c39aea632baf025b97ebc760b538be14ed5549 100644 (file)
@@ -17,7 +17,7 @@ static void symres_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode);
 static void symres_statement_chain(OnyxSemPassState* state, OnyxAstNode* walker, OnyxAstNode** trailer);
 static b32 symres_statement(OnyxSemPassState* state, OnyxAstNode* stmt);
 static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block);
-static void symres_function_definition(OnyxSemPassState* state, OnyxAstNodeFuncDef* func);
+static void symres_function(OnyxSemPassState* state, OnyxAstNodeFunction* func);
 
 static void symbol_introduce(OnyxSemPassState* state, OnyxAstNode* symbol) {
     onyx_token_null_toggle(*symbol->token);
@@ -238,7 +238,7 @@ static void symres_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) {
     scope_leave(state);
 }
 
-static void symres_function_definition(OnyxSemPassState* state, OnyxAstNodeFuncDef* func) {
+static void symres_function(OnyxSemPassState* state, OnyxAstNodeFunction* func) {
     forll(OnyxAstNodeParam, param, func->params, next) {
         symbol_introduce(state, (OnyxAstNode *) param);
     }
@@ -250,50 +250,24 @@ static void symres_function_definition(OnyxSemPassState* state, OnyxAstNodeFuncD
     }
 }
 
-void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNodeFile* root_node) {
-    OnyxAstNode* walker;
-    OnyxAstNodeFile* top_walker = root_node;
-    while (top_walker) {
-
-        walker = top_walker->contents;
-        while (walker) {
-            switch (walker->kind) {
-                case ONYX_AST_NODE_KIND_FUNCDEF:
-                case ONYX_AST_NODE_KIND_GLOBAL:
-                    if (!symbol_unique_introduce(state, walker)) return;
-                    break;
-
-                case ONYX_AST_NODE_KIND_FOREIGN:
-                    if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF
-                            || walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_GLOBAL) {
-                        if (!symbol_unique_introduce(state, walker->as_foreign.import)) return;
-                    }
-                    break;
-
-                default: break;
-            }
+void onyx_resolve_symbols(OnyxSemPassState* state, OnyxProgram* program) {
 
-            walker = walker->next;
-        }
+    // NOTE: First, introduce all global symbols
+    bh_arr_each(OnyxAstNodeGlobal *, global, program->globals)
+        if (!symbol_unique_introduce(state, (OnyxAstNode *) *global)) return;
 
-        top_walker = top_walker->next;
-    }
+    bh_arr_each(OnyxAstNodeFunction *, function, program->functions)
+        if (!symbol_unique_introduce(state, (OnyxAstNode *) *function)) return;
 
-    top_walker = root_node;
-    while (top_walker) {
+    bh_arr_each(OnyxAstNodeForeign *, foreign, program->foreigns) {
+        OnyxAstNodeKind import_kind = (*foreign)->import->kind;
 
-        walker = top_walker->contents;
-        while (walker) {
-            switch (walker->kind) {
-                case ONYX_AST_NODE_KIND_FUNCDEF:
-                    symres_function_definition(state, &walker->as_funcdef);
-                    break;
-                default: break;
-            }
+        if (import_kind == ONYX_AST_NODE_KIND_FUNCTION || import_kind == ONYX_AST_NODE_KIND_GLOBAL)
+            if (!symbol_unique_introduce(state, (*foreign)->import)) return;
+    }
 
-            walker = walker->next;
-        }
 
-        top_walker = top_walker->next;
-    }
+    // NOTE: Then, resolve all symbols in all functions
+    bh_arr_each(OnyxAstNodeFunction *, function, program->functions)
+        symres_function(state, *function);
 }
index b64bc42765bec7963d24dd8c19bdeb2f9a737aa8..9d2f96e339b8ac274273c395b8d565f457105d63 100644 (file)
@@ -1,7 +1,7 @@
 #define BH_DEBUG
 #include "onyxsempass.h"
 
-static void typecheck_function_defintion(OnyxSemPassState* state, OnyxAstNodeFuncDef* func);
+static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* func);
 static void typecheck_block(OnyxSemPassState* state, OnyxAstNodeBlock* block);
 static void typecheck_statement_chain(OnyxSemPassState* state, OnyxAstNode* start);
 static void typecheck_statement(OnyxSemPassState* state, OnyxAstNode* stmt);
@@ -101,7 +101,7 @@ static void typecheck_while(OnyxSemPassState* state, OnyxAstNodeWhile* whilenode
 }
 
 static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) {
-    OnyxAstNodeFuncDef* callee = (OnyxAstNodeFuncDef *) call->callee;
+    OnyxAstNodeFunction* callee = (OnyxAstNodeFunction *) call->callee;
 
     if (callee->kind == ONYX_AST_NODE_KIND_SYMBOL) {
         onyx_message_add(state->msgs,
@@ -111,7 +111,7 @@ static void typecheck_call(OnyxSemPassState* state, OnyxAstNodeCall* call) {
         return;
     }
 
-    if (callee->kind != ONYX_AST_NODE_KIND_FUNCDEF) {
+    if (callee->kind != ONYX_AST_NODE_KIND_FUNCTION) {
         onyx_message_add(state->msgs,
                 ONYX_MESSAGE_TYPE_CALL_NON_FUNCTION,
                 call->token->pos,
@@ -322,7 +322,7 @@ static void typecheck_block(OnyxSemPassState* state, OnyxAstNodeBlock* block) {
     }
 }
 
-static void typecheck_function_defintion(OnyxSemPassState* state, OnyxAstNodeFuncDef* func) {
+static void typecheck_function(OnyxSemPassState* state, OnyxAstNodeFunction* func) {
     forll(OnyxAstNodeParam, param, func->params, next) {
         if (!param->type->is_known) {
             onyx_message_add(state->msgs,
@@ -347,46 +347,11 @@ static void typecheck_function_defintion(OnyxSemPassState* state, OnyxAstNodeFun
     }
 }
 
-void onyx_type_check(OnyxSemPassState* state, OnyxAstNodeFile* root_node) {
-    // TODO: This code is very ugly, but the types of globals need to
-    // be resolved before any function can use them
+void onyx_type_check(OnyxSemPassState* state, OnyxProgram* program) {
 
-    OnyxAstNode* walker;
-    OnyxAstNodeFile* top_walker = root_node;
-    while (top_walker) {
+    bh_arr_each(OnyxAstNodeGlobal *, global, program->globals)
+        typecheck_global(state, *global);
 
-        walker = top_walker->contents;
-        while (walker) {
-            switch (walker->kind) {
-                case ONYX_AST_NODE_KIND_GLOBAL:
-                    typecheck_global(state, &walker->as_global);
-                    break;
-
-                default: break;
-            }
-
-            walker = walker->next;
-        }
-
-        top_walker = top_walker->next;
-    }
-
-    top_walker = root_node;
-    while (top_walker) {
-
-        walker = top_walker->contents;
-        while (walker) {
-            switch (walker->kind) {
-                case ONYX_AST_NODE_KIND_FUNCDEF:
-                    typecheck_function_defintion(state, &walker->as_funcdef);
-                    break;
-
-                default: break;
-            }
-
-            walker = walker->next;
-        }
-
-        top_walker = top_walker->next;
-    }
+    bh_arr_each(OnyxAstNodeFunction *, function, program->functions)
+        typecheck_function(state, *function);
 }
index b40a44c0f2832684ec6dad2b4b53f1bf4c2060e2..207260262a955453a4923ec7397546899ebead97 100644 (file)
@@ -17,17 +17,6 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) {
     bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind));
 
     switch (node->kind) {
-    case ONYX_AST_NODE_KIND_PROGRAM: {
-        OnyxAstNodeFile* file_node = &node->as_file;
-        if (file_node->contents)
-            onyx_ast_print(file_node->contents, indent + 1);
-
-        if (node->next)
-            onyx_ast_print(node->next, indent);
-
-        break;
-    }
-
     case ONYX_AST_NODE_KIND_USE: {
          OnyxAstNodeUse* use_node = &node->as_use;
          bh_printf("%b", use_node->filename->token, use_node->filename->length);
@@ -38,10 +27,10 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) {
          break;
      }
 
-    case ONYX_AST_NODE_KIND_FUNCDEF: {
+    case ONYX_AST_NODE_KIND_FUNCTION: {
         if (node->token)
             bh_printf("(%b) ", node->token->token, node->token->length);
-        OnyxAstNodeFuncDef* fd = &node->as_funcdef;
+        OnyxAstNodeFunction* fd = &node->as_function;
 
         print_indent;
         bh_printf("Params ");
@@ -151,7 +140,7 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) {
     case ONYX_AST_NODE_KIND_CALL: {
         OnyxAstNodeCall* call = &node->as_call;
         if (call->callee) {
-            if (call->callee->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
+            if (call->callee->kind == ONYX_AST_NODE_KIND_FUNCTION) {
                 bh_printf("function: %b", call->callee->token->token, call->callee->token->length);
             } else {
                 onyx_ast_print(call->callee, indent + 1);
index fd9690bf65452cb4538b18bd354bfc514f1c43ee..206883f2e2fc75186cb96956d3eef6f8cad674b5 100644 (file)
@@ -209,7 +209,7 @@ static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) {
     return WASM_TYPE_VOID;
 }
 
-static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFuncDef* fd);
+static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFunction* fd);
 static void compile_block(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeBlock* block);
 static void compile_statement(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* stmt);
 static void compile_assign_lval(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* lval);
@@ -222,7 +222,7 @@ static void compile_expression(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pco
 static void compile_cast(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeUnaryOp* cast);
 static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNode* ret);
 
-static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFuncDef* fd) {
+static void compile_function_body(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode, OnyxAstNodeFunction* fd) {
     if (fd->body == NULL) return;
 
     bh_arr(WasmInstruction) code = *pcode;
@@ -639,7 +639,7 @@ static void compile_return(OnyxWasmModule* mod, bh_arr(WasmInstruction)* pcode,
     *pcode = code;
 }
 
-static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFuncDef* fd) {
+static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) {
     static char type_repr_buf[128];
 
     char* t = type_repr_buf;
@@ -681,7 +681,7 @@ static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFuncDef* fd) {
     return type_idx;
 }
 
-static void compile_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* fd) {
+static void compile_function(OnyxWasmModule* mod, OnyxAstNodeFunction* fd) {
     i32 type_idx = generate_type_idx(mod, fd);
 
     WasmFunc wasm_func = {
@@ -786,8 +786,8 @@ static void compile_global_declaration(OnyxWasmModule* module, OnyxAstNodeGlobal
 }
 
 static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) {
-    if (foreign->import->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
-        i32 type_idx = generate_type_idx(module, &foreign->import->as_funcdef);
+    if (foreign->import->kind == ONYX_AST_NODE_KIND_FUNCTION) {
+        i32 type_idx = generate_type_idx(module, &foreign->import->as_function);
 
         WasmImport import = {
             .kind = WASM_FOREIGN_FUNCTION,
@@ -861,88 +861,37 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) {
     return module;
 }
 
-void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program) {
-    OnyxAstNode* walker;
-    OnyxAstNodeFile* top_walker = program;
-    while (top_walker) {
+void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxProgram* program) {
 
-        walker = top_walker->contents;
-        while (walker) {
-            if (walker->kind == ONYX_AST_NODE_KIND_FOREIGN) {
-                if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF)
-                    module->next_func_idx++;
+    // NOTE: First, introduce all indicies for globals and functions
+    bh_arr_each(OnyxAstNodeForeign *, foreign, program->foreigns) {
+        OnyxAstNodeKind import_kind = (*foreign)->import->kind;
 
-                if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_GLOBAL)
-                    module->next_global_idx++;
-            }
-
-            walker = walker->next;
+        if (import_kind == ONYX_AST_NODE_KIND_FUNCTION) {
+            module->next_func_idx++;
+            bh_imap_put(&module->func_map, (u64) (*foreign)->import, module->next_import_func_idx++);
         }
-
-        top_walker = top_walker->next;
-    }
-
-    top_walker = program;
-    while (top_walker) {
-
-        walker = top_walker->contents;
-        while (walker) {
-            if (walker->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
-                i32 func_idx = module->next_func_idx++;
-                bh_imap_put(&module->func_map, (u64) walker, func_idx);
-            }
-
-            if (walker->kind == ONYX_AST_NODE_KIND_GLOBAL) {
-                i32 global_idx = module->next_global_idx++;
-                bh_imap_put(&module->global_map, (u64) walker, global_idx);
-            }
-
-            if (walker->kind == ONYX_AST_NODE_KIND_FOREIGN) {
-                OnyxAstNodeForeign* foreign = &walker->as_foreign;
-
-                if (foreign->import->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
-                    i32 func_idx = module->next_import_func_idx++;
-                    bh_imap_put(&module->func_map, (u64) foreign->import, func_idx);
-                }
-
-                if (foreign->import->kind == ONYX_AST_NODE_KIND_GLOBAL) {
-                    i32 global_idx = module->next_import_global_idx++;
-                    bh_imap_put(&module->global_map, (u64) foreign->import, global_idx);
-                }
-            }
-
-            walker = walker->next;
+        else if (import_kind == ONYX_AST_NODE_KIND_GLOBAL) {
+            module->next_global_idx++;
+            bh_imap_put(&module->global_map, (u64) (*foreign)->import, module->next_import_func_idx++);
         }
 
-        top_walker = top_walker->next;
+        compile_foreign(module, *foreign);
     }
 
-    top_walker = program;
-    while (top_walker) {
+    bh_arr_each(OnyxAstNodeFunction *, function, program->functions)
+        bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++);
 
-        walker = top_walker->contents;
-        while (walker) {
-            switch (walker->kind) {
-                case ONYX_AST_NODE_KIND_FUNCDEF:
-                    compile_function_definition(module, &walker->as_funcdef);
-                    break;
+    bh_arr_each(OnyxAstNodeGlobal *, global, program->globals)
+        bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++);
 
-                case ONYX_AST_NODE_KIND_GLOBAL:
-                    compile_global_declaration(module, &walker->as_global);
-                    break;
 
-                case ONYX_AST_NODE_KIND_FOREIGN:
-                    compile_foreign(module, &walker->as_foreign);
-                    break;
+    // NOTE: Then, compile everything
+    bh_arr_each(OnyxAstNodeFunction *, function, program->functions)
+        compile_function(module, *function);
 
-                default: break;
-            }
-
-            walker = walker->next;
-        }
-
-        top_walker = top_walker->next;
-    }
+    bh_arr_each(OnyxAstNodeGlobal *, global, program->globals)
+        compile_global_declaration(module, *global);
 }
 
 void onyx_wasm_module_free(OnyxWasmModule* module) {