"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/onyx",
- "args": ["progs/new_minimal.onyx"],
+ "args": ["progs/test.onyx"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
[X] Consequence of the above, recursion works
+ [X] Better compiler interface
+ - Proper command line options
+ - Compiling multiple files at once
+ - Changing output location
+ - Viewing help screen
+
[ ] Devise and implement a simple set of implicit type casting rules.
- Numeric literals always type cast to whatever type is needed (very flexible).
}
b32 bh__arr_free(void **arr) {
+ if (*arr == NULL) return 0;
+
bh__arr* arrptr = bh__arrhead(*arr);
bh_free(arrptr->allocator, arrptr);
*arr = NULL;
}
b32 bh__table_free(bh__table **table) {
+ if (*table == NULL) return 0;
+
for (i32 i = 0; i < (*table)->table_size; i++) {
if ((*table)->arrs[i] != NULL) {
bh_arr_free((*table)->arrs[i]);
typedef struct OnyxAstNodeFuncDef OnyxAstNodeFuncDef;
typedef struct OnyxAstNodeForeign OnyxAstNodeForeign;
typedef struct OnyxAstNodeCall OnyxAstNodeCall;
+typedef struct OnyxAstNodeFile OnyxAstNodeFile;
typedef struct OnyxParser {
OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts
// unless this becomes used by something else
};
+struct OnyxAstNodeFile {
+ OnyxAstNodeKind kind;
+ u32 flags;
+ OnyxToken *token; // NOTE: unused
+ OnyxTypeInfo *type; // NOTE: unused
+ 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
OnyxAstNodeNumLit as_numlit;
OnyxAstNodeForeign as_foreign;
OnyxAstNodeIf as_if;
+ OnyxAstNodeFile as_file;
};
const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind);
OnyxAstNode* 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);
-OnyxAstNode* onyx_parse(OnyxParser *parser);
+OnyxAstNodeFile* onyx_parse(OnyxParser *parser);
#endif // #ifndef ONYXPARSER_H
} OnyxSemPassState;
// NOTE: Resolving all symbols in the tree
-void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNode* root_node);
+void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNodeFile* root_node);
// NOTE: Inferring and checking types in the tree
-void onyx_type_check(OnyxSemPassState* state, OnyxAstNode* root_node);
+void onyx_type_check(OnyxSemPassState* state, OnyxAstNodeFile* root_node);
// NOTE: Full semantic pass
OnyxSemPassState onyx_sempass_create(bh_allocator alloc, bh_allocator node_alloc, OnyxMessages* msgs);
-void onyx_sempass(OnyxSemPassState* state, OnyxAstNode* root_node);
+void onyx_sempass(OnyxSemPassState* state, OnyxAstNodeFile* root_node);
#endif
} OnyxWasmModule;
OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc);
-void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNode* program);
+void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program);
void onyx_wasm_module_free(OnyxWasmModule* module);
void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file);
+++ /dev/null
-use "core"; /* Looks for "core.onyx" in the current directory */
-
-Foo :: struct { x i32, y i32 };
-
-add :: proc (a i32, b i32) -> i32 {
- return a + b + 1234.56;
-};
print(fib(5));
- { a :: 2; b :: 3; print(a + b); }
-
print(output);
print_float(float_test());
--- /dev/null
+
+other_value :: proc -> i32 {
+ return 8675309 + something_else();
+}
// Foreign functions are included this way:
// sym_name :: foreign "module" "name" proc ...
-print :: foreign "host" "print" proc (value i32) ---
-
-get_value :: foreign "env" "get_val" proc -> i32 ---
+print :: foreign "host" "print" proc (value i32) ---
+something_else :: proc -> i32 {
+ return 100;
+}
// This is the entry point
export main :: proc {
nineteen :: 5 * 3 + 4;
- thirty_five :: 5 * (3 + 4) + get_value();
+ thirty_five :: 5 * (3 + 4);
+
+ something :: other_value();
print(nineteen);
print(thirty_five);
+ print(something);
}
#include "onyxutils.h"
#include "onyxwasm.h"
+#define VERSION "0.1"
+
+static const char* docstring = "Onyx compiler version " VERSION "\n"
+ "\n"
+ "The standard compiler for the Onyx programming language.\n";
+
+typedef enum CompileAction {
+ ONYX_COMPILE_ACTION_COMPILE,
+ ONYX_COMPILE_ACTION_CHECK_ERRORS,
+ ONYX_COMPILE_ACTION_PRINT_HELP,
+} CompileAction;
+
+typedef struct OnyxCompileOptions {
+ bh_allocator allocator;
+ CompileAction action;
+
+ bh_arr(const char *) files;
+ 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 {
+ bh_arena token_arena, ast_arena, msg_arena, sp_arena;
+ bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc;
+ bh_table(bh_file_contents) loaded_files;
+
+ OnyxMessages msgs;
+ OnyxWasmModule wasm_mod;
+} CompilerState;
+
+static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *argv[]) {
+ OnyxCompileOptions options = {
+ .allocator = alloc,
+ .action = ONYX_COMPILE_ACTION_PRINT_HELP,
+
+ .files = NULL,
+ .target_file = "out.wasm",
+ };
+
+ bh_arr_new(alloc, options.files, 1);
+
+ fori(i, 1, argc - 1) {
+ if (!strcmp(argv[i], "--help")) {
+ options.action = ONYX_COMPILE_ACTION_PRINT_HELP;
+ break;
+ }
+ else if (!strcmp(argv[i], "-o")) {
+ options.action = ONYX_COMPILE_ACTION_COMPILE;
+ options.target_file = argv[++i];
+ }
+ else {
+ options.action = ONYX_COMPILE_ACTION_COMPILE;
+ bh_arr_push(options.files, argv[i]);
+ }
+ }
+
+ return options;
+}
+
+void compile_opts_free(OnyxCompileOptions* opts) {
+ bh_arr_free(opts->files);
+}
+
+OnyxAstNodeFile* parse_source_file(bh_file_contents* file_contents, CompilerState* compiler_state) {
+ // 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);
+ onyx_lex_tokens(&tokenizer);
+
+ OnyxParser parser = onyx_parser_create(compiler_state->ast_alloc, &tokenizer, &compiler_state->msgs);
+ return onyx_parse(&parser);
+}
+
+i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) {
+
+ bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096);
+ compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena);
+
+ onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs);
+
+ // NOTE: Create the arena for tokens from the lexer
+ bh_arena_init(&compiler_state->token_arena, opts->allocator, 16 * 1024 * 1024); // 16 MB
+ compiler_state->token_alloc = bh_arena_allocator(&compiler_state->token_arena);
+
+ // 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_table_init(opts->allocator, compiler_state->loaded_files, 7);
+
+ bh_arr_each(const char *, filename, opts->files) {
+ bh_file file;
+
+ bh_file_error err = bh_file_open(&file, *filename);
+ if (err != BH_FILE_ERROR_NONE) {
+ bh_printf_err("Failed to open file %s\n", filename);
+ return ONYX_COMPILER_PROGRESS_FAILED_READ;
+ }
+
+ 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);
+ }
+
+ OnyxAstNodeFile* root_file = NULL;
+ OnyxAstNodeFile* prev_file = NULL;
+ bh_table_each_start(bh_file_contents, compiler_state->loaded_files);
+ OnyxAstNodeFile* file_node = parse_source_file(&value, compiler_state);
+
+ if (!root_file) {
+ root_file = file_node;
+ }
+
+ if (prev_file) {
+ prev_file->next = file_node;
+ }
+
+ prev_file = file_node;
+ bh_table_each_end;
+
+ if (onyx_message_has_errors(&compiler_state->msgs)) {
+ return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
+ }
+
+ OnyxSemPassState sp_state = onyx_sempass_create( compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs);
+ onyx_sempass(&sp_state, root_file);
+
+ if (onyx_message_has_errors(&compiler_state->msgs)) {
+ return ONYX_COMPILER_PROGRESS_FAILED_SEMPASS;
+ }
+
+ compiler_state->wasm_mod = onyx_wasm_module_create(opts->allocator);
+ onyx_wasm_module_compile(&compiler_state->wasm_mod, root_file);
+
+ if (onyx_message_has_errors(&compiler_state->msgs)) {
+ return ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN;
+ }
+
+ bh_file output_file;
+ if (bh_file_create(&output_file, opts->target_file) != BH_FILE_ERROR_NONE) {
+ return ONYX_COMPILER_PROGRESS_FAILED_OUTPUT;
+ }
+
+ onyx_wasm_module_write_to_file(&compiler_state->wasm_mod, output_file);
+
+ return ONYX_COMPILER_PROGRESS_SUCCESS;
+}
+
+void compiler_state_free(CompilerState* cs) {
+ bh_arena_free(&cs->ast_arena);
+ bh_arena_free(&cs->msg_arena);
+ bh_arena_free(&cs->token_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_allocator alloc = bh_heap_allocator();
bh_scratch_init(&global_scratch, alloc, 16 * 1024); // NOTE: 16 KB
global_scratch_allocator = bh_scratch_allocator(&global_scratch);
- bh_file source_file;
- bh_file_error err = bh_file_open(&source_file, argv[1]);
- if (err != BH_FILE_ERROR_NONE) {
- bh_printf_err("Failed to open file %s\n", argv[1]);
- return EXIT_FAILURE;
- }
+ OnyxCompileOptions compile_opts = compile_opts_parse(alloc, argc, argv);
+ CompilerState compile_state = {
+ .wasm_mod = { 0 }
+ };
- // NOTE: 1st: Read file contents
- bh_file_contents fc = bh_file_read_contents(alloc, &source_file);
- bh_file_close(&source_file);
+ CompilerProgress compiler_progress = ONYX_COMPILER_PROGRESS_FAILED_READ;
- // NOTE: 2nd: Tokenize the contents
- OnyxTokenizer tokenizer = onyx_tokenizer_create(alloc, &fc);
- onyx_lex_tokens(&tokenizer);
- bh_arr(OnyxToken) token_arr = tokenizer.tokens;
+ switch (compile_opts.action) {
+ case ONYX_COMPILE_ACTION_PRINT_HELP:
+ // NOTE: This could probably be made better
+ bh_printf(docstring);
+ return 1;
- // NOTE: Create the buffer for where compiler messages will be written
- bh_arena msg_arena;
- bh_arena_init(&msg_arena, alloc, 4096);
- bh_allocator msg_alloc = bh_arena_allocator(&msg_arena);
+ case ONYX_COMPILE_ACTION_COMPILE:
+ compiler_progress = onyx_compile(&compile_opts, &compile_state);
- OnyxMessages msgs;
- onyx_message_create(msg_alloc, &msgs);
+ break;
- // NOTE: Create the arena where AST nodes will exist
- // Prevents nodes from being scattered across memory due to fragmentation
- bh_arena ast_arena;
- bh_arena_init(&ast_arena, alloc, 16 * 1024 * 1024); // 16MB
- bh_allocator ast_alloc = bh_arena_allocator(&ast_arena);
-
- // NOTE: 3rd: parse the tokens to an AST
- OnyxParser parser = onyx_parser_create(ast_alloc, &tokenizer, &msgs);
- OnyxAstNode* program = onyx_parse(&parser);
-
- bh_arena sp_arena;
- bh_arena_init(&sp_arena, alloc, 16 * 1024);
- bh_allocator sp_alloc = bh_arena_allocator(&sp_arena);
-
- OnyxSemPassState sp_state = onyx_sempass_create(sp_alloc, ast_alloc, &msgs);
- onyx_sempass(&sp_state, program);
-
- // NOTE: if there are errors, assume the parse tree was generated wrong,
- // even if it may have still been generated correctly.
- if (onyx_message_has_errors(&msgs)) {
- onyx_message_print(&msgs);
- goto main_exit;
- } else {
- // onyx_ast_print(program, 1);
- bh_printf("\nNo errors.\n");
+ default: break;
+ }
+
+ switch (compiler_progress) {
+ case ONYX_COMPILER_PROGRESS_FAILED_READ:
+ // NOTE: Do nothing since it was already printed above
+ break;
+
+ case ONYX_COMPILER_PROGRESS_FAILED_PARSE:
+ case ONYX_COMPILER_PROGRESS_FAILED_SEMPASS:
+ case ONYX_COMPILER_PROGRESS_FAILED_BINARY_GEN:
+ onyx_message_print(&compile_state.msgs);
+ break;
+
+ case ONYX_COMPILER_PROGRESS_FAILED_OUTPUT:
+ bh_printf_err("Failed to open file for writing: '%s'\n", compile_opts.target_file);
+ break;
+
+ case ONYX_COMPILER_PROGRESS_SUCCESS:
+ bh_printf("Successfully compiled to '%s'\n", compile_opts.target_file);
+ break;
}
- // NOTE: 4th: Generate a WASM module from the parse tree and
- // write it to a file.
- OnyxWasmModule wasm_mod = onyx_wasm_module_create(alloc);
- onyx_wasm_module_compile(&wasm_mod, program);
-
- bh_file out_file;
- bh_file_create(&out_file, "out.wasm");
- onyx_wasm_module_write_to_file(&wasm_mod, out_file);
- bh_file_close(&out_file);
-
- onyx_wasm_module_free(&wasm_mod);
-main_exit: // NOTE: Cleanup, since C doesn't have defer
- bh_arena_free(&sp_arena);
- bh_arena_free(&msg_arena);
- bh_arena_free(&ast_arena);
- onyx_parser_free(&parser);
- onyx_tokenizer_free(&tokenizer);
- bh_file_contents_free(&fc);
-
- return 0;
+ compiler_state_free(&compile_state);
+
+ return compiler_progress == ONYX_COMPILER_PROGRESS_SUCCESS;
}
// NOTE: Old bits of code that may be useful again at some point.
bh_table_free(parser->identifiers);
}
-OnyxAstNode* onyx_parse(OnyxParser *parser) {
- OnyxAstNode* program = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM);
+OnyxAstNodeFile* onyx_parse(OnyxParser *parser) {
+ OnyxAstNodeFile* program = (OnyxAstNodeFile *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM);
- OnyxAstNode** prev_stmt = &program->next;
+ OnyxAstNode** prev_stmt = &program->contents;
OnyxAstNode* curr_stmt = NULL;
while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) {
curr_stmt = parse_top_level_statement(parser);
// 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(OnyxAstNode* root_node) {
+static void collapse_scopes(OnyxAstNodeFile* root_node) {
bh_arr(OnyxAstNodeBlock*) traversal_queue = NULL;
bh_arr_new(global_scratch_allocator, traversal_queue, 4);
bh_arr_set_length(traversal_queue, 0);
- OnyxAstNode* walker = root_node;
- while (walker) {
- if (walker->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
- OnyxAstNodeScope* top_scope = walker->as_funcdef.body->scope;
+ OnyxAstNode* walker;
+ OnyxAstNodeFile* top_walker = root_node;
+ while (top_walker) {
- bh_arr_push(traversal_queue, walker->as_funcdef.body);
- while (!bh_arr_is_empty(traversal_queue)) {
- OnyxAstNodeBlock* block = traversal_queue[0];
+ walker = top_walker->contents;
+ while (walker) {
+ if (walker->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
+ OnyxAstNodeScope* top_scope = walker->as_funcdef.body->scope;
- 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);
+ bh_arr_push(traversal_queue, walker->as_funcdef.body);
+ while (!bh_arr_is_empty(traversal_queue)) {
+ OnyxAstNodeBlock* block = traversal_queue[0];
- if (if_node->false_block)
- bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->false_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);
- } else {
+ if (if_node->false_block)
+ bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) if_node->false_block);
- 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;
+ } else {
- last_local->prev_local = top_scope->last_local;
- top_scope->last_local = block->scope->last_local;
- block->scope->last_local = NULL;
- }
+ 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;
- 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_IF) {
- if (walker->as_if.true_block)
- bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker->as_if.true_block);
+ OnyxAstNode* walker = block->body;
+ while (walker) {
+ if (walker->kind == ONYX_AST_NODE_KIND_BLOCK) {
+ bh_arr_push(traversal_queue, (OnyxAstNodeBlock *) walker);
- 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);
+ }
+
+ walker = walker->next;
+ }
}
- }
- bh_arr_deleten(traversal_queue, 0, 1);
+ bh_arr_deleten(traversal_queue, 0, 1);
+ }
}
+
+ walker = walker->next;
}
- walker = walker->next;
+ top_walker = top_walker->next;
}
}
-void onyx_sempass(OnyxSemPassState* state, OnyxAstNode* root_node) {
+void onyx_sempass(OnyxSemPassState* state, OnyxAstNodeFile* root_node) {
onyx_resolve_symbols(state, root_node);
+ if (onyx_message_has_errors(state->msgs)) return;
+
onyx_type_check(state, root_node);
+ if (onyx_message_has_errors(state->msgs)) return;
+
collapse_scopes(root_node);
}
}
}
-void onyx_resolve_symbols(OnyxSemPassState* state, OnyxAstNode* root_node) {
- OnyxAstNode* walker = root_node;
- while (walker) {
- switch (walker->kind) {
- case ONYX_AST_NODE_KIND_FUNCDEF:
- if (!define_function(state, &walker->as_funcdef)) return;
- break;
-
- case ONYX_AST_NODE_KIND_FOREIGN:
- if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
- if (!define_function(state, &walker->as_foreign.import->as_funcdef)) return;
- }
- break;
-
- default: break;
+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:
+ if (!define_function(state, &walker->as_funcdef)) return;
+ break;
+
+ case ONYX_AST_NODE_KIND_FOREIGN:
+ if (walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
+ if (!define_function(state, &walker->as_foreign.import->as_funcdef)) return;
+ }
+ break;
+
+ default: break;
+ }
+
+ walker = walker->next;
}
- walker = walker->next;
+ top_walker = top_walker->next;
}
- walker = root_node;
- while (walker) {
- switch (walker->kind) {
- case ONYX_AST_NODE_KIND_FUNCDEF:
- symres_function_definition(state, &walker->as_funcdef);
- break;
- default: break;
+ top_walker = root_node;
+ while (top_walker) {
+
+ 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;
+ }
+
+ walker = walker->next;
}
- walker = walker->next;
+ top_walker = top_walker->next;
}
}
}
}
-void onyx_type_check(OnyxSemPassState* state, OnyxAstNode* root_node) {
- OnyxAstNode* walker = root_node;
- while (walker) {
- switch (walker->kind) {
- case ONYX_AST_NODE_KIND_FUNCDEF:
- typecheck_function_defintion(state, &walker->as_funcdef);
- break;
- default: break;
+void onyx_type_check(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:
+ typecheck_function_defintion(state, &walker->as_funcdef);
+ break;
+ default: break;
+ }
+
+ walker = walker->next;
}
- walker = walker->next;
+ top_walker = top_walker->next;
}
}
return module;
}
-void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNode* program) {
- OnyxAstNode* walker = program;
- while (walker) {
- if (walker->kind == ONYX_AST_NODE_KIND_FOREIGN
- && walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
- module->next_func_idx++;
+void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program) {
+ OnyxAstNode* walker;
+ OnyxAstNodeFile* top_walker = program;
+ while (top_walker) {
+
+ walker = top_walker->contents;
+ while (walker) {
+ if (walker->kind == ONYX_AST_NODE_KIND_FOREIGN
+ && walker->as_foreign.import->kind == ONYX_AST_NODE_KIND_FUNCDEF) {
+ module->next_func_idx++;
+ }
+
+ walker = walker->next;
}
- walker = walker->next;
+ top_walker = top_walker->next;
}
- walker = program;
- 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);
- }
+ 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_FOREIGN) {
- OnyxAstNodeForeign* foreign = &walker->as_foreign;
+ 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_FUNCDEF) {
+ i32 func_idx = module->next_import_func_idx++;
+ bh_imap_put(&module->func_map, (u64) foreign->import, func_idx);
+ }
}
+
+ walker = walker->next;
}
- walker = walker->next;
+ top_walker = top_walker->next;
}
- walker = program;
- while (walker) {
- switch (walker->kind) {
- case ONYX_AST_NODE_KIND_FUNCDEF:
- compile_function_definition(module, &walker->as_funcdef);
- break;
- case ONYX_AST_NODE_KIND_FOREIGN:
- compile_foreign(module, &walker->as_foreign);
- break;
- default: break;
- }
+ top_walker = program;
+ while (top_walker) {
+
+ walker = top_walker->contents;
+ while (walker) {
+ switch (walker->kind) {
+ case ONYX_AST_NODE_KIND_FUNCDEF:
+ compile_function_definition(module, &walker->as_funcdef);
+ break;
+ case ONYX_AST_NODE_KIND_FOREIGN:
+ compile_foreign(module, &walker->as_foreign);
+ break;
+ default: break;
+ }
- walker = walker->next;
- }
+ walker = walker->next;
+ }
+
+ top_walker = top_walker->next;
+ }
}
void onyx_wasm_module_free(OnyxWasmModule* module) {