From 781b87e9574acc6049b9bd1405cfdb0c57c38c82 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 24 Jun 2020 17:33:39 -0500 Subject: [PATCH] Better compiler frontend; compile many files at once --- .vimspector.json | 2 +- docs/plan | 6 + include/bh.h | 4 + include/onyxparser.h | 13 +- include/onyxsempass.h | 6 +- include/onyxwasm.h | 2 +- onyx | Bin 192552 -> 195792 bytes progs/demo.onyx | 7 -- progs/minimal.onyx | 2 - progs/other.onyx | 4 + progs/test.onyx | 12 +- src/onyx.c | 270 ++++++++++++++++++++++++++++++++---------- src/onyxparser.c | 6 +- src/onyxsempass.c | 85 +++++++------ src/onyxsymres.c | 61 ++++++---- src/onyxtypecheck.c | 25 ++-- src/onyxwasm.c | 83 ++++++++----- 17 files changed, 400 insertions(+), 188 deletions(-) delete mode 100644 progs/demo.onyx create mode 100644 progs/other.onyx diff --git a/.vimspector.json b/.vimspector.json index 6444b264..e309f7f9 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -6,7 +6,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/onyx", - "args": ["progs/new_minimal.onyx"], + "args": ["progs/test.onyx"], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], diff --git a/docs/plan b/docs/plan index ac906133..649fc86b 100644 --- a/docs/plan +++ b/docs/plan @@ -78,6 +78,12 @@ HOW: [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). diff --git a/include/bh.h b/include/bh.h index 063989c8..20a9e9f0 100644 --- a/include/bh.h +++ b/include/bh.h @@ -1653,6 +1653,8 @@ b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap) { } b32 bh__arr_free(void **arr) { + if (*arr == NULL) return 0; + bh__arr* arrptr = bh__arrhead(*arr); bh_free(arrptr->allocator, arrptr); *arr = NULL; @@ -1739,6 +1741,8 @@ b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size) { } 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]); diff --git a/include/onyxparser.h b/include/onyxparser.h index c9d77e6b..27b903a3 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -16,6 +16,7 @@ typedef struct OnyxAstNodeParam OnyxAstNodeParam; 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 @@ -198,6 +199,15 @@ struct OnyxAstNodeCall { // 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 @@ -220,12 +230,13 @@ union OnyxAstNode { 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 diff --git a/include/onyxsempass.h b/include/onyxsempass.h index 238e1035..12d87920 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -28,13 +28,13 @@ typedef struct OnyxSemPassState { } 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 diff --git a/include/onyxwasm.h b/include/onyxwasm.h index 1fcd8d36..adebd8bc 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -293,7 +293,7 @@ typedef struct OnyxWasmModule { } 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); diff --git a/onyx b/onyx index b4bfa5a720d8fa7f9f1b3a9c0d8ae25ec2738ca7..0a10774a060fda1613f33dedddd8a4a609b13473 100755 GIT binary patch delta 73134 zcmdqK33wF6)<4|UlgvzpWHQ+oNHSS~gb)(;9l{a_$c`ZUzVBNEWEn652_Zmepg|&w zAfg~!*kuz$R8(-e0^)+85JVAoKxMw)sp{@Dx!m{O_y7N%_x+x4o~P!VsycPfsZ&dz zQ{6qY?P`S!_bV)q44xM+@lU1zlIz!^YFqtAg^KK`qRZ)y;dex4_#Gvf)o`3_EV3sX zEA3egzj-#1J*3QMi{iUfXFOXTR<{bO>Pm{dJ#=Npmc(xD@7G=O?wv`$w@i&`Sf}`` zQY!ai?*9HMNnTxJKA!9HzSxYE@(LOJQPoK*()hjr?-DMQCkQrcPz zlnzk?#8A~jk9_XY|=GC*`m zT5xB^T*{n~Wl<3(qC~UnlCa7o42t=e-&jH;*Kq)*$HT zbNaf^C|BYuv2T@o@v+r8Ykbv-7{57LZ-gbRqb7!*-*nbg0+seapAH zl9}+7tZq}*CZx-kUsm2taNFFND5X!mto)R)i8WG`#2NuRS}-Y34m^{I166zx_2N-Dk^C_V7)uXyl%LwNi=e?k;t)3$*FDS0GDBIW9VYtW_N;1+`G5PR1m3m| z_hfcKkJ9{>?pq6~ywG>x<7mey*Xwq0?oShJZdU-^$&#k^ewO{W)J3b@H{B@drZjH2 zME0+%ywflvpw%TwD)5oB*JKxl)mN;ImitvnMe73Js;NqsE}`=3eM)rG82gzOBsAxc zQqUz`~^osVm1MD~H;|%h`KNuC%Elvs^`PH!`Z#yOMNdjZ8Y!O$3f5l?G5+QF*rA zd;SZOP$EoFTj|q2Gpg1*Am1s-e}0>j{{>L`ol??%io7#Xsrtkn_LLIdp^<#bqjc*~ zEWa{Ox!WPZ-u-1F_U*1jcWfi)Y*U7GT*o}h!;Y1GWz;NJKCDwwY1Jv3xs?H(l9{z+ zQ6~rUx6Y+T9XDndPHvzK-WMtF-l81r+ye_Qpi4yRpzQoPYldYP_*53tDXX;R$?UUP z+xRRf?6EDopl(hWADE|=&RxQ)e!Cvr3bMA*UJ}HS+|tPGf-d�_nDIY3Ljh2GuZL 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 UxO^^+u7`dXXph>RYREZE!` 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 diff --git a/progs/demo.onyx b/progs/demo.onyx deleted file mode 100644 index b36b5c89..00000000 --- a/progs/demo.onyx +++ /dev/null @@ -1,7 +0,0 @@ -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; -}; diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 319c48f2..76197666 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -19,8 +19,6 @@ export main :: proc { print(fib(5)); - { a :: 2; b :: 3; print(a + b); } - print(output); print_float(float_test()); diff --git a/progs/other.onyx b/progs/other.onyx new file mode 100644 index 00000000..1dadc9e7 --- /dev/null +++ b/progs/other.onyx @@ -0,0 +1,4 @@ + +other_value :: proc -> i32 { + return 8675309 + something_else(); +} diff --git a/progs/test.onyx b/progs/test.onyx index 5c6f3671..ad83c20a 100644 --- a/progs/test.onyx +++ b/progs/test.onyx @@ -1,17 +1,21 @@ // 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); } diff --git a/src/onyx.c b/src/onyx.c index 6561b53c..dee3930b 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -9,6 +9,175 @@ #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(); @@ -16,77 +185,50 @@ int main(int argc, char *argv[]) { 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. diff --git a/src/onyxparser.c b/src/onyxparser.c index a0edfa65..743333fd 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -779,10 +779,10 @@ void onyx_parser_free(OnyxParser* parser) { 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); diff --git a/src/onyxsempass.c b/src/onyxsempass.c index 587786a4..d86a3090 100644 --- a/src/onyxsempass.c +++ b/src/onyxsempass.c @@ -23,66 +23,77 @@ 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(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); } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 6e2b2a2a..cfe7f19d 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -261,35 +261,48 @@ static void symres_function_definition(OnyxSemPassState* state, OnyxAstNodeFuncD } } -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; } } diff --git a/src/onyxtypecheck.c b/src/onyxtypecheck.c index 3f0cb9e7..6949bf57 100644 --- a/src/onyxtypecheck.c +++ b/src/onyxtypecheck.c @@ -301,16 +301,23 @@ static void typecheck_function_defintion(OnyxSemPassState* state, OnyxAstNodeFun } } -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; } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 94a83ba5..2eef58d7 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -674,50 +674,69 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { 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) { -- 2.25.1