Slight refactoring and improvements
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 18 Jul 2020 22:12:29 +0000 (17:12 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 18 Jul 2020 22:12:29 +0000 (17:12 -0500)
13 files changed:
include/onyxastnodes.h
include/onyxir.h
include/onyxlex.h
include/onyxsempass.h
include/onyxwasm.h
onyx
src/onyx.c
src/onyxchecker.c
src/onyxlex.c
src/onyxmsgs.c
src/onyxsempass.c
src/onyxsymres.c
src/onyxwasm.c

index f297648935d416d1fc69fa370632676f33dc2846..fcd257d48ff6bc8e37b28cb86d743050b32b1bb9 100644 (file)
@@ -271,16 +271,37 @@ struct AstOverloadedFunction {
     bh_arr(AstTyped *) overloads;
 };
 
-// NOTE: Simple data structure for storing what comes out of the parser
-typedef struct ParserOutput {
-    bh_arr(AstBinding *)  top_level_bindings;
-    bh_arr(AstNode *)     nodes_to_process;
 
-    bh_arr(AstFunction *) functions;
-    bh_arr(AstGlobal *)   globals;
-} ParserOutput;
+// NOTE: An Entity represents something will need to be
+// processed later down the pipeline.
+typedef enum EntityType {
+    Entity_Type_Unknown,
+    Entity_Type_Function,
+    Entity_Type_Overloaded_Function,
+    Entity_Type_Global,
+    Entity_Type_Expression
+} EntityType;
+
+typedef struct Entity {
+    EntityType type;
 
+    union {
+        AstFunction*           function;
+        AstOverloadedFunction* overloaded_function;
+        AstGlobal*             global;
+        AstTyped*              expr;
+    };
+} Entity;
+
+
+// NOTE: Simple data structure for storing what comes out of the parser
+typedef struct ProgramInfo {
+    bh_arr(AstBinding *)  bindings;
+    bh_arr(Entity)        entities;
 
+    u32 foreign_func_count;
+    u32 foreign_global_count;
+} ProgramInfo;
 
 
 
index 97e0a3cb1be88b61463641068f44d92d05257046..5a506da1c9085946222bb8311c35dd3d89f23f1d 100644 (file)
@@ -53,6 +53,6 @@ typedef struct IrContext {
 
 IrContext ir_context_create(bh_allocator allocator);
 void ir_context_free(IrContext* context);
-void ir_generate(IrContext* context, ParserOutput parse_output);
+void ir_generate(IrContext* context, ProgramInfo parse_output);
 
 #endif // #ifndef ONYXIR_H
index 87e957e7e85b49eccb93d6a011bff65ee140db16..24168862ebf78088dbc67a92f033a94289728911 100644 (file)
@@ -50,7 +50,10 @@ typedef enum TokenType {
 typedef struct OnyxFilePos {
     const char* filename;
     char* line_start;
-    u32 line, column;
+    u32 line;
+    
+    // NOTE: This assumes that no line is no longer than 2^16 chars
+    u16 column, length;
 } OnyxFilePos;
 
 typedef struct OnyxToken {
index c9227a04915e63064b713c04bab29846a9ab8efb..af2766f2c92e04bef7719a8d23ecf51c8cd19d2d 100644 (file)
@@ -23,13 +23,13 @@ typedef struct SemState {
 } SemState;
 
 // NOTE: Resolving all symbols in the tree
-void onyx_resolve_symbols(SemState* state, ParserOutput* program);
+void onyx_resolve_symbols(SemState* state, ProgramInfo* program);
 
 // NOTE: Inferring and checking types in the tree
-void onyx_type_check(SemState* state, ParserOutput* program);
+void onyx_type_check(SemState* state, ProgramInfo* program);
 
 // NOTE: Full semantic pass
 SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs);
-void onyx_sempass(SemState* state, ParserOutput* program);
+void onyx_sempass(SemState* state, ProgramInfo* program);
 
 #endif
index 55be4e15f5d8fc65713aefda828f5371d3f21ee0..fe6aa6b46ac7d7e2bca16c478696ab37f48818e2 100644 (file)
@@ -279,10 +279,11 @@ typedef struct OnyxWasmModule {
     bh_allocator allocator;
     OnyxMessages* msgs;
 
+    // NOTE: Mapping ptrs to function / global indicies
+    bh_imap index_map;
+
     // NOTE: Mapping from local ast node ptrs to indicies
     bh_imap local_map;
-    bh_imap global_map;
-    bh_imap func_map; // NOTE: Maps from ast node pointers to the function index
 
     // NOTE: Used internally as a map from strings that represent function types,
     // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 )
@@ -292,19 +293,21 @@ typedef struct OnyxWasmModule {
     bh_arr(u8) structured_jump_target;
 
     bh_arr(WasmFuncType*) types; // NOTE: This have to be pointers because the type is variadic in size
-    bh_arr(WasmImport) imports;
-    bh_table(WasmExport) exports;
-    bh_arr(WasmGlobal) globals;
-    bh_arr(WasmFunc) funcs;
-
-    u16 next_type_idx;
-    u16 next_func_idx;
-    u16 next_global_idx;
-    u16 export_count;
+    bh_arr(WasmImport)    imports;
+    bh_table(WasmExport)  exports;
+    bh_arr(WasmGlobal)    globals;
+    bh_arr(WasmFunc)      funcs;
+
+    u32 next_type_idx;
+    u32 export_count;
+    u32 next_func_idx;
+    u32 next_foreign_func_idx;
+    u32 next_global_idx;
+    u32 next_foreign_global_idx;
 } OnyxWasmModule;
 
 OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs);
-void onyx_wasm_module_compile(OnyxWasmModule* module, ParserOutput* program);
+void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* 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 b356f8a4dedf47c866d40633a76409a632a8a61c..0791ddf04cb41f4c72f037c9e51e4538d381c291 100755 (executable)
Binary files a/onyx and b/onyx differ
index 127b8247ce46c7938c1660749167d63e733111d6..028eafc88ed62db82861c93e309f1f723bee5096 100644 (file)
@@ -41,29 +41,6 @@ typedef struct OnyxCompileOptions {
     const char* target_file;
 } OnyxCompileOptions;
 
-typedef enum CompilerProgress {
-    ONYX_COMPILER_PROGRESS_FAILED_READ,
-    ONYX_COMPILER_PROGRESS_FAILED_PARSE,
-    ONYX_COMPILER_PROGRESS_FAILED_SEMPASS,
-    ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN,
-    ONYX_COMPILER_PROGRESS_FAILED_OUTPUT,
-    ONYX_COMPILER_PROGRESS_SUCCESS
-} CompilerProgress;
-
-typedef struct CompilerState {
-    OnyxCompileOptions* options;
-
-    bh_arena                  ast_arena, msg_arena, sp_arena;
-    bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc;
-
-    bh_table(bh_file_contents) loaded_files;
-    bh_arr(const char *) queued_files;
-
-    OnyxMessages msgs;
-    ParserOutput parse_output;
-    OnyxWasmModule wasm_mod;
-} CompilerState;
-
 static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *argv[]) {
     OnyxCompileOptions options = {
         .allocator = alloc,
@@ -106,6 +83,75 @@ static void compile_opts_free(OnyxCompileOptions* opts) {
     bh_arr_free(opts->files);
 }
 
+
+
+
+
+typedef enum CompilerProgress {
+    ONYX_COMPILER_PROGRESS_FAILED_READ,
+    ONYX_COMPILER_PROGRESS_FAILED_PARSE,
+    ONYX_COMPILER_PROGRESS_FAILED_SEMPASS,
+    ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN,
+    ONYX_COMPILER_PROGRESS_FAILED_OUTPUT,
+    ONYX_COMPILER_PROGRESS_SUCCESS
+} CompilerProgress;
+
+typedef struct CompilerState {
+    OnyxCompileOptions* options;
+
+    bh_arena                  ast_arena, msg_arena, sp_arena;
+    bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc;
+
+    bh_table(bh_file_contents) loaded_files;
+    bh_arr(const char *) queued_files;
+
+    OnyxMessages msgs;
+    ProgramInfo prog_info;
+    OnyxWasmModule wasm_mod;
+} CompilerState;
+
+static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOptions* opts) {
+    compiler_state->options = opts;
+
+    bh_arr_new(global_heap_allocator, compiler_state->prog_info.bindings, 4);
+    bh_arr_new(global_heap_allocator, compiler_state->prog_info.entities, 4);
+
+    bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096);
+    compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena);
+
+    bh_table_init(opts->allocator, compiler_state->loaded_files, 15);
+
+    onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs, &compiler_state->loaded_files);
+
+    compiler_state->token_alloc = opts->allocator;
+
+    // NOTE: Create the arena where AST nodes will exist
+    // Prevents nodes from being scattered across memory due to fragmentation
+    bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB
+    compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena);
+
+    bh_arena_init(&compiler_state->sp_arena, opts->allocator, 16 * 1024);
+    compiler_state->sp_alloc = bh_arena_allocator(&compiler_state->sp_arena);
+
+    bh_arr_new(opts->allocator, compiler_state->queued_files, 4);
+
+    // NOTE: Add all files passed by command line to the queue
+    bh_arr_each(const char *, filename, opts->files)
+        bh_arr_push(compiler_state->queued_files, (char *) *filename);
+}
+
+static void compiler_state_free(CompilerState* cs) {
+    bh_arena_free(&cs->ast_arena);
+    bh_arena_free(&cs->msg_arena);
+    bh_arena_free(&cs->sp_arena);
+    bh_table_free(cs->loaded_files);
+    onyx_wasm_module_free(&cs->wasm_mod);
+}
+
+
+
+
+
 static ParseResults 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)
@@ -121,6 +167,49 @@ static ParseResults parse_source_file(CompilerState* compiler_state, bh_file_con
     return onyx_parse(&parser);
 }
 
+static void merge_parse_results(CompilerState* compiler_state, ParseResults* results) {
+    bh_arr_each(AstUse *, use_node, results->uses) {
+        char* formatted_name = bh_aprintf(
+                global_heap_allocator,
+                "%b.onyx",
+                (*use_node)->filename->text, (*use_node)->filename->length);
+
+        bh_arr_push(compiler_state->queued_files, formatted_name);
+    }
+
+    bh_arr_each(AstBinding *, binding_node, results->bindings)
+        bh_arr_push(compiler_state->prog_info.bindings, *binding_node);
+
+    bh_arr_each(AstNode *, node, results->nodes_to_process) {
+        Entity ent = { Entity_Type_Unknown };
+
+        AstKind nkind    = (*node)->kind;
+        switch (nkind) {
+            case Ast_Kind_Function:
+                ent.type     = Entity_Type_Function;
+                ent.function = (AstFunction *) *node;
+                break;
+
+            case Ast_Kind_Overloaded_Function:
+                ent.type                = Entity_Type_Overloaded_Function;
+                ent.overloaded_function = (AstOverloadedFunction *) *node;
+                break;
+
+            case Ast_Kind_Global:
+                ent.type   = Entity_Type_Global;
+                ent.global = (AstGlobal *) *node;
+                break;
+
+            default:
+                ent.type = Entity_Type_Expression;
+                ent.expr = (AstTyped *) *node;
+                break;
+        }
+
+        bh_arr_push(compiler_state->prog_info.entities, ent);
+    }
+}
+
 static CompilerProgress process_source_file(CompilerState* compiler_state, char* filename) {
     if (bh_table_has(bh_file_contents, compiler_state->loaded_files, filename)) return ONYX_COMPILER_PROGRESS_SUCCESS;
 
@@ -143,21 +232,7 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char*
     fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename);
 
     ParseResults results = parse_source_file(compiler_state, &fc);
-
-    bh_arr_each(AstUse *, use_node, results.uses) {
-        char* formatted_name = bh_aprintf(
-                global_heap_allocator,
-                "%b.onyx",
-                (*use_node)->filename->text, (*use_node)->filename->length);
-
-        bh_arr_push(compiler_state->queued_files, formatted_name);
-    }
-
-    bh_arr_each(AstBinding *, binding_node, results.bindings)
-        bh_arr_push(compiler_state->parse_output.top_level_bindings, *binding_node);
-
-    bh_arr_each(AstNode *, node, results.nodes_to_process)
-        bh_arr_push(compiler_state->parse_output.nodes_to_process, *node);
+    merge_parse_results(compiler_state, &results);
 
     if (onyx_message_has_errors(&compiler_state->msgs)) {
         return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
@@ -166,37 +241,6 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char*
     }
 }
 
-static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOptions* opts) {
-    compiler_state->options = opts;
-
-    bh_arr_new(global_heap_allocator, compiler_state->parse_output.top_level_bindings, 4);
-    bh_arr_new(global_heap_allocator, compiler_state->parse_output.nodes_to_process, 4);
-    bh_arr_new(global_heap_allocator, compiler_state->parse_output.functions, 4);
-    bh_arr_new(global_heap_allocator, compiler_state->parse_output.globals, 4);
-
-    bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096);
-    compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena);
-
-    bh_table_init(opts->allocator, compiler_state->loaded_files, 15);
-
-    onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs, &compiler_state->loaded_files);
-
-    compiler_state->token_alloc = opts->allocator;
-
-    // NOTE: Create the arena where AST nodes will exist
-    // Prevents nodes from being scattered across memory due to fragmentation
-    bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB
-    compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena);
-
-    bh_arena_init(&compiler_state->sp_arena, opts->allocator, 16 * 1024);
-    compiler_state->sp_alloc = bh_arena_allocator(&compiler_state->sp_arena);
-
-    bh_arr_new(opts->allocator, compiler_state->queued_files, 4);
-
-    // NOTE: Add all files passed by command line to the queue
-    bh_arr_each(const char *, filename, opts->files)
-        bh_arr_push(compiler_state->queued_files, (char *) *filename);
-}
 
 static i32 onyx_compile(CompilerState* compiler_state) {
 
@@ -216,7 +260,7 @@ static i32 onyx_compile(CompilerState* compiler_state) {
         bh_printf("[Checking semantics]\n");
 
     SemState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs);
-    onyx_sempass(&sp_state, &compiler_state->parse_output);
+    onyx_sempass(&sp_state, &compiler_state->prog_info);
 
     if (onyx_message_has_errors(&compiler_state->msgs)) {
         return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
@@ -228,7 +272,7 @@ static i32 onyx_compile(CompilerState* compiler_state) {
         bh_printf("[Generating WASM]\n");
 
     compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator, &compiler_state->msgs);
-    onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->parse_output);
+    onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->prog_info);
 
     if (onyx_message_has_errors(&compiler_state->msgs)) {
         return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN;
@@ -249,14 +293,6 @@ static i32 onyx_compile(CompilerState* compiler_state) {
     return ONYX_COMPILER_PROGRESS_SUCCESS;
 }
 
-static void compiler_state_free(CompilerState* cs) {
-    bh_arena_free(&cs->ast_arena);
-    bh_arena_free(&cs->msg_arena);
-    bh_arena_free(&cs->sp_arena);
-    bh_table_free(cs->loaded_files);
-    onyx_wasm_module_free(&cs->wasm_mod);
-}
-
 int main(int argc, char *argv[]) {
 
     bh_scratch_init(&global_scratch, bh_heap_allocator(), 16 * 1024); // NOTE: 16 KB
index 709a76829842a3801abe1752d5b74e27d88acf2d..e1c215ca8e21253025afba9e804db8d4a133c6fa 100644 (file)
@@ -361,7 +361,7 @@ CHECK(array_access, AstArrayAccess* aa) {
     if (!type_is_pointer(aa->addr->type)) {
         onyx_message_add(state->msgs,
                 ONYX_MESSAGE_TYPE_LITERAL,
-                aa->addr->token->pos,
+                aa->token->pos,
                 "expected pointer type for left of array access");
         return 1;
     }
@@ -370,7 +370,7 @@ CHECK(array_access, AstArrayAccess* aa) {
             || (aa->expr->type->Basic.flags & Basic_Flag_Integer) == 0) {
         onyx_message_add(state->msgs,
                 ONYX_MESSAGE_TYPE_LITERAL,
-                aa->expr->token->pos,
+                aa->token->pos,
                 "expected integer type for index");
         return 1;
     }
@@ -625,16 +625,30 @@ CHECK(node, AstNode* node) {
     }
 }
 
-void onyx_type_check(SemState* state, ParserOutput* program) {
-    bh_arr_each(AstNode *, node, program->nodes_to_process) {
-        check_node(state, *node);
+void onyx_type_check(SemState* state, ProgramInfo* program) {
+    bh_arr_each(Entity, entity, program->entities) {
+        switch (entity->type) {
+            case Entity_Type_Function:
+                if (entity->function->flags & Ast_Kind_Foreign) program->foreign_func_count++;
 
-        if ((*node)->kind == Ast_Kind_Function) {
-            bh_arr_push(program->functions, (AstFunction *) *node);
-        }
+                if (check_function(state, entity->function)) return;
+                break;
+
+            case Entity_Type_Overloaded_Function:
+                if (check_overloaded_function(state, entity->overloaded_function)) return;
+                break;
+
+            case Entity_Type_Global:
+                if (entity->global->flags & Ast_Kind_Foreign) program->foreign_global_count++;
+
+                if (check_global(state, entity->global)) return;
+                break;
+
+            case Entity_Type_Expression:
+                if (check_expression(state, entity->expr)) return;
+                break;
 
-        if ((*node)->kind == Ast_Kind_Global) {
-            bh_arr_push(program->globals, (AstGlobal *) *node);
+            default: DEBUG_HERE; break;
         }
     }
 }
index 1c6edea84312af007cd9b8be035502f6347b8819..8a1da57b1b3ae13755e298201646159be489f1fa 100644 (file)
@@ -107,7 +107,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
     tk.pos.line_start = tokenizer->line_start;
     tk.pos.filename = tokenizer->filename;
     tk.pos.line = tokenizer->line_number;
-    tk.pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1;
+    tk.pos.column = (u16)(tokenizer->curr - tokenizer->line_start) + 1;
 
     if (tokenizer->curr == tokenizer->end) {
         tk.type = Token_Type_End_Stream;
@@ -220,6 +220,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
     INCREMENT_CURR_TOKEN(tokenizer);
 
 token_parsed:
+    tk.pos.length = (u16) tk.length;
     bh_arr_push(tokenizer->tokens, tk);
 
     return &tokenizer->tokens[bh_arr_length(tokenizer->tokens) - 1];
index 15768a387202d631e78b63e4faae011b6b6cc2aa..2ca0e761a9593e48a884a8f53e94c5468bc3dc3d 100644 (file)
@@ -56,11 +56,12 @@ static void print_detailed_message(OnyxMessage* msg, bh_file_contents* fc) {
     bh_printf("| %b\n", msg->pos.line_start, linelength);
 
     char* pointer_str = bh_alloc_array(global_scratch_allocator, char, linelength);
-    memset(pointer_str, 0, linelength);
-    memset(pointer_str, '~', msg->pos.column - 1);
+    memset(pointer_str, ' ', linelength);
+    memset(pointer_str + msg->pos.column, '~', msg->pos.length - 1);
     pointer_str[msg->pos.column - 1] = '^';
+    pointer_str[msg->pos.column + msg->pos.length - 1] = 0;
 
-    bh_printf("|~%s\n", pointer_str);
+    bh_printf("| %s\n", pointer_str);
 }
 
 void onyx_message_print(OnyxMessages* msgs) {
index 6d7936809302d49a07871a448d47381a3f76cfd6..e19cfcb0d06845cf177c768359a30c6f5bd6a23c 100644 (file)
@@ -16,7 +16,7 @@ SemState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMe
     return state;
 }
 
-void onyx_sempass(SemState* state, ParserOutput* program) {
+void onyx_sempass(SemState* state, ProgramInfo* program) {
     onyx_resolve_symbols(state, program);
     if (onyx_message_has_errors(state->msgs)) return;
 
index c9779517bfca622c300d85a4610fcca3f715ba46..179dc9a1fc3a73af96208c1768cacb152181c41c 100644 (file)
@@ -291,35 +291,7 @@ static void symres_overloaded_function(SemState* state, AstOverloadedFunction* o
     }
 }
 
-static void symres_top_node(SemState* state, AstNode** node) {
-    switch ((*node)->kind) {
-        case Ast_Kind_Call:
-        case Ast_Kind_Unary_Op:
-        case Ast_Kind_Binary_Op:
-        case Ast_Kind_Literal:
-        case Ast_Kind_Symbol:
-             symres_expression(state, (AstTyped **) node);
-             break;
-
-        case Ast_Kind_Global:
-             symres_global(state, (AstGlobal *) *node);
-             break;
-
-        case Ast_Kind_Function:
-             symres_function(state, (AstFunction *) *node);
-             break;
-
-        case Ast_Kind_Overloaded_Function:
-             symres_overloaded_function(state, (AstOverloadedFunction *) *node);
-             break;
-
-        default:
-             DEBUG_HERE;
-             break;
-    }
-}
-
-void onyx_resolve_symbols(SemState* state, ParserOutput* program) {
+void onyx_resolve_symbols(SemState* state, ProgramInfo* program) {
 
     state->global_scope = scope_create(state->node_allocator, NULL);
     scope_enter(state, state->global_scope);
@@ -339,9 +311,17 @@ void onyx_resolve_symbols(SemState* state, ParserOutput* program) {
     symbol_basic_type_introduce(state, &basic_type_f64);
     symbol_basic_type_introduce(state, &basic_type_rawptr);
 
-    bh_arr_each(AstBinding *, binding, program->top_level_bindings)
+    bh_arr_each(AstBinding *, binding, program->bindings)
         if (!symbol_introduce(state, (*binding)->token, (*binding)->node)) return;
 
-    bh_arr_each(AstNode *, node, program->nodes_to_process)
-        symres_top_node(state, node);
+    bh_arr_each(Entity, entity, program->entities) {
+        switch (entity->type) {
+            case Entity_Type_Function:            symres_function(state, entity->function); break;
+            case Entity_Type_Overloaded_Function: symres_overloaded_function(state, entity->overloaded_function); break;
+            case Entity_Type_Global:              symres_global(state, entity->global); break;
+            case Entity_Type_Expression:          symres_expression(state, &entity->expr); break;
+
+            default: break;
+        }
+    }
 }
index fcb145435af24c05f06788350c27abedd609d2b6..d8040ae78edfe75a1169c525ed1c6b1c6f566a88 100644 (file)
@@ -319,7 +319,7 @@ COMPILE_FUNC(assignment, AstBinaryOp* assign) {
         WID(WI_LOCAL_SET, localidx);
 
     } else if (lval->kind == Ast_Kind_Global) {
-        i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) lval);
+        i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) lval);
 
         compile_expression(mod, &code, assign->right);
         WID(WI_GLOBAL_SET, globalidx);
@@ -553,7 +553,7 @@ COMPILE_FUNC(call, AstCall* call) {
         compile_expression(mod, &code, arg->value);
     }
 
-    i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee);
+    i32 func_idx = (i32) bh_imap_get(&mod->index_map, (u64) call->callee);
     bh_arr_push(code, ((WasmInstruction){ WI_CALL, func_idx }));
 
     *pcode = code;
@@ -653,7 +653,7 @@ COMPILE_FUNC(expression, AstTyped* expr) {
 
         case Ast_Kind_Global:
             {
-                i32 globalidx = (i32) bh_imap_get(&mod->global_map, (u64) expr);
+                i32 globalidx = (i32) bh_imap_get(&mod->index_map, (u64) expr);
 
                 WID(WI_GLOBAL_GET, globalidx);
                 break;
@@ -880,7 +880,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) {
     if (fd->flags & Ast_Flag_Exported) {
         token_toggle_end(fd->exported_name);
 
-        i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) fd);
+        i32 func_idx = (i32) bh_imap_get(&mod->index_map, (u64) fd);
 
         WasmExport wasm_export = {
             .kind = WASM_FOREIGN_FUNCTION,
@@ -931,7 +931,7 @@ static void compile_function(OnyxWasmModule* mod, AstFunction* fd) {
     bh_imap_clear(&mod->local_map);
 }
 
-static void compile_global_declaration(OnyxWasmModule* module, AstGlobal* global) {
+static void compile_global(OnyxWasmModule* module, AstGlobal* global) {
     WasmType global_type = onyx_type_to_wasm_type(global->type);
 
     if (global->flags & Ast_Flag_Foreign) {
@@ -955,7 +955,7 @@ static void compile_global_declaration(OnyxWasmModule* module, AstGlobal* global
     if ((global->flags & Ast_Flag_Exported) != 0) {
         token_toggle_end(global->exported_name);
 
-        i32 global_idx = (i32) bh_imap_get(&module->func_map, (u64) global);
+        i32 global_idx = (i32) bh_imap_get(&module->index_map, (u64) global);
 
         WasmExport wasm_export = {
             .kind = WASM_FOREIGN_GLOBAL,
@@ -992,6 +992,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) {
 
         .funcs = NULL,
         .next_func_idx = 0,
+        .next_foreign_func_idx = 0,
 
         .exports = NULL,
         .export_count = 0,
@@ -1000,6 +1001,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) {
 
         .globals = NULL,
         .next_global_idx = 0,
+        .next_foreign_global_idx = 0,
 
         .structured_jump_target = NULL,
     };
@@ -1016,55 +1018,63 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc, OnyxMessages* msgs) {
     bh_table_init(global_heap_allocator, module.type_map, 61);
     bh_table_init(global_heap_allocator, module.exports, 61);
 
-    bh_imap_init(&module.local_map,  global_heap_allocator, 16);
-    bh_imap_init(&module.func_map,   global_heap_allocator, 16);
-    bh_imap_init(&module.global_map, global_heap_allocator, 16);
+    bh_imap_init(&module.index_map, global_heap_allocator, 128);
+    bh_imap_init(&module.local_map, global_heap_allocator, 16);
 
     return module;
 }
 
-void onyx_wasm_module_compile(OnyxWasmModule* module, ParserOutput* program) {
-    bh_arr_each(AstFunction *, function, program->functions) {
-        if ((*function)->flags & Ast_Flag_Foreign) {
-            bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++);
-        }
-    }
+void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) {
 
-    bh_arr_each(AstGlobal *, global, program->globals) {
-        if ((*global)->flags & Ast_Flag_Foreign) {
-            bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++);
-        }
-    }
+    module->next_func_idx   = program->foreign_func_count;
+    module->next_global_idx = program->foreign_global_count;
 
-    bh_arr_each(AstFunction *, function, program->functions) {
-        if ((*function)->flags & Ast_Flag_Foreign) continue;
+    // NOTE: First, assign indicies to all functions / globals
+    bh_arr_each(Entity, entity, program->entities) {
+        switch (entity->type) {
+            case Entity_Type_Function: {
+                if (entity->function->flags & Ast_Flag_Intrinsic) break;
 
-        if (((*function)->flags & Ast_Flag_Intrinsic) == 0)
-            bh_imap_put(&module->func_map, (u64) *function, module->next_func_idx++);
-    }
+                u64 func_idx;
+                if ((entity->function->flags & Ast_Flag_Foreign) != 0)
+                    func_idx = module->next_foreign_func_idx++;
+                else
+                    func_idx = module->next_func_idx++;
 
-    bh_arr_each(AstGlobal *, global, program->globals) {
-        if ((*global)->flags & Ast_Flag_Foreign) continue;
+                bh_imap_put(&module->index_map, (u64) entity->function, func_idx);
+                break;
+            }
 
-        bh_imap_put(&module->global_map, (u64) *global, module->next_global_idx++);
-    }
+            case Entity_Type_Global: {
+                u64 global_idx;
+                if ((entity->global->flags & Ast_Flag_Foreign) != 0)
+                    global_idx = module->next_foreign_global_idx++;
+                else
+                    global_idx = module->next_global_idx++;
 
-    // NOTE: Then, compile everything
-    bh_arr_each(AstGlobal *, global, program->globals)
-        compile_global_declaration(module, *global);
+                bh_imap_put(&module->index_map, (u64) entity->global, global_idx);
+                break;
+            }
 
-    bh_arr_each(AstFunction *, function, program->functions)
-        compile_function(module, *function);
+            default: break;
+        }
+    }
 
-    // bh_arr_each(AstGlobal *, global, program->globals)
-    //     compile_global_declaration(module, *global);
+    // NOTE: Then, compile everything
+    bh_arr_each(Entity, entity, program->entities) {
+        switch (entity->type) {
+            case Entity_Type_Function: compile_function(module, entity->function); break;
+            case Entity_Type_Global:   compile_global(module,   entity->global); break;
+            default: break;
+        }
+    }
 }
 
 void onyx_wasm_module_free(OnyxWasmModule* module) {
     bh_arr_free(module->types);
     bh_arr_free(module->funcs);
     bh_imap_free(&module->local_map);
-    bh_imap_free(&module->func_map);
+    bh_imap_free(&module->index_map);
     bh_table_free(module->type_map);
     bh_table_free(module->exports);
 }