From: Brendan Hansen Date: Wed, 6 Jan 2021 00:55:59 +0000 (-0600) Subject: `defer` has better semantics with targeted jump statements X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c3a2da9a10c7e448d0e6a1b897187b8644ce12ba;p=onyx.git `defer` has better semantics with targeted jump statements --- diff --git a/bin/onyx b/bin/onyx index 0c6aa12d..f7892b47 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/onyx.exe b/onyx.exe index 3236d2a7..192f9e4f 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyx.c b/src/onyx.c index d342d348..defec5e2 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -234,6 +234,8 @@ static char* lookup_included_file(CompilerState* cs, char* filename) { #define DIR_SEPARATOR '\\' #endif + fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR; + bh_arr_each(const char *, folder, cs->options->included_folders) { if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR) bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index f58a3cfc..d3d7d472 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -216,6 +216,7 @@ CheckStatus check_switch(AstSwitch* switchnode) { if (switchnode->assignment != NULL) CHECK(statement, (AstNode *) switchnode->assignment); CHECK(expression, &switchnode->expr); + resolve_expression_type(switchnode->expr); if (!type_is_integer(switchnode->expr->type) && switchnode->expr->type->kind != Type_Kind_Enum) { onyx_report_error(switchnode->expr->token->pos, "expected integer or enum type for switch expression"); return Check_Error; @@ -387,6 +388,10 @@ CheckStatus check_call(AstCall* call) { // NOTE: Build callee's type fill_in_type((AstTyped *) callee); + if (callee->type == NULL) { + onyx_report_error(call->token->pos, "There was an error with looking up the type of this function."); + return Check_Error; + } if (callee->type->kind != Type_Kind_Function) { onyx_report_error(call->token->pos, diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 83e690a3..1a9ede09 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -256,7 +256,7 @@ EMIT_FUNC(structured_jump, AstJump* jump) { static const u8 wants[Jump_Type_Count] = { 1, 2, 3 }; - i32 labelidx = 0; + u64 labelidx = 0; u8 wanted = wants[jump->jump]; b32 success = 0; @@ -273,6 +273,14 @@ EMIT_FUNC(structured_jump, AstJump* jump) { labelidx++; } + if (bh_arr_length(mod->deferred_stmts) != 0) { + i32 i = bh_arr_length(mod->deferred_stmts) - 1; + while (i >= 0 && mod->deferred_stmts[i].depth >= labelidx) { + emit_statement(mod, &code, mod->deferred_stmts[i].stmt); + i--; + } + } + if (success) { // NOTE: If the previous instruction was a non conditional jump, // don't emit another jump since it will never be reached. diff --git a/tests/defer_with_continue b/tests/defer_with_continue new file mode 100644 index 00000000..66f7581c --- /dev/null +++ b/tests/defer_with_continue @@ -0,0 +1,28 @@ +Doing something with Index is 0 +Doing something with Index is 1 +Doing something with Index is 2 +Skipping 3!! +Index is 3 +Doing something with Index is 4 +Doing something with Index is 5 +Doing something with Index is 6 +Doing something with Index is 7 +Doing something with Index is 8 +Doing something with Index is 9 +i is 10 + + +=================================== +Doing something with Index is 0 +Doing something with Index is 1 +Doing something with Index is 2 +Skipping 3!! +Index is 3 +i is 4 + + +=================================== +In block deferred! +Deferred! +Default! +At the end! diff --git a/tests/defer_with_continue.onyx b/tests/defer_with_continue.onyx new file mode 100644 index 00000000..45190817 --- /dev/null +++ b/tests/defer_with_continue.onyx @@ -0,0 +1,51 @@ +#load "core/std/js" + +use package core + +main :: proc (args: [] cstr) { + defer println("At the end!"); + i := 0; + while i < 10 { + defer i += 1; + defer printf("Index is %i\n", i); + + if i == 3 { + printf("Skipping %i!!\n", i); + continue; + } + + printf("Doing something with "); + } + printf("i is %i\n", i); + + println("\n\n==================================="); + i = 0; + while i < 10 { + defer i += 1; + defer printf("Index is %i\n", i); + + if i == 3 { + printf("Skipping %i!!\n", i); + break; + } + + printf("Doing something with "); + } + printf("i is %i\n", i); + + println("\n\n==================================="); + switch i { + case 4 { + defer println("Deferred!"); + { + defer println("In block deferred!"); + fallthrough; + } + println("Case 4!"); + } + + case #default { + println("Default!"); + } + } +}