From: Brendan Hansen Date: Sat, 5 Sep 2020 14:11:07 +0000 (-0500) Subject: added some robustness and better errors X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=21aba7785cee033e714d5bfdaba222328570d933;p=onyx.git added some robustness and better errors --- diff --git a/docs/plan b/docs/plan index a7657694..8b0c0b62 100644 --- a/docs/plan +++ b/docs/plan @@ -230,7 +230,7 @@ HOW: - This looks very simple - I think all the infrastructure is there for this - [ ] data structure based iteration + [X] data structure based iteration - Currently, I do not plan on having custom iterators. This may very well change in the near future. - For now, a for loop will be reimagined to look like: for val: iterable ... diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 599a5adb..4ec59f57 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -177,6 +177,8 @@ typedef enum AstFlags { Ast_Flag_Struct_Is_Union = BH_BIT(17), Ast_Flag_No_Clone = BH_BIT(18), + + Ast_Flag_Cannot_Take_Addr = BH_BIT(19), } AstFlags; typedef enum UnaryOp { diff --git a/onyx b/onyx index 93ad2c33..4bf58d11 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/poly_test.onyx b/progs/poly_test.onyx index f966ab9b..f682285b 100644 --- a/progs/poly_test.onyx +++ b/progs/poly_test.onyx @@ -94,7 +94,24 @@ print_v2 :: proc (v: V2) #add_overload print { print(")"); } +switch_demo :: proc { + switch a := 4; a { + case 4, 5, 6 { + print("a was 4, 5, or 6\n"); + fallthrough fallthrough; + } + + case 10 do print("a was 10\n"); + + case #default { + print("a was something else.\n"); + } + } +} + main :: proc (args: [] cstring) { + switch_demo(); + res := compose(5, proc (x: i32) -> i32 do return x * 3;, proc (x: i32) -> i32 do return x + 5;); print(res); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index d2f1f51a..56e63db0 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -113,6 +113,7 @@ b32 check_for(AstFor* fornode) { // NOTE: Blindly copy the first range member's type which will // be the low value. - brendanfh 2020/09/04 fornode->var->type = builtin_range_type_type->Struct.memarr[0]->type; + fornode->var->flags |= Ast_Flag_Cannot_Take_Addr; fornode->loop_type = For_Loop_Range; } @@ -142,6 +143,9 @@ b32 check_for(AstFor* fornode) { fornode->loop_type = For_Loop_DynArr; } + if (fornode->by_pointer) + fornode->var->flags |= Ast_Flag_Cannot_Take_Addr; + if (!can_iterate) { onyx_report_error(fornode->iter->token->pos, "Cannot iterate over a '%s'.", @@ -807,11 +811,12 @@ b32 check_struct_literal(AstStructLiteral* sl) { b32 check_address_of(AstAddressOf* aof) { if (check_expression(&aof->expr)) return 1; - if (aof->expr->kind != Ast_Kind_Array_Access + if ((aof->expr->kind != Ast_Kind_Array_Access && aof->expr->kind != Ast_Kind_Dereference && aof->expr->kind != Ast_Kind_Field_Access && aof->expr->kind != Ast_Kind_Memres - && aof->expr->kind != Ast_Kind_Local) { + && aof->expr->kind != Ast_Kind_Local) + || (aof->expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) { onyx_report_error(aof->token->pos, "Cannot take the address of value."); return 1; } diff --git a/src/onyxparser.c b/src/onyxparser.c index fe9c353d..9fa2a706 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -897,7 +897,11 @@ static AstSwitch* parse_switch_stmt(OnyxParser* parser) { if (parse_possible_directive(parser, "default")) { switch_node->default_case = parse_block(parser); - continue; + + if (parser->curr->type != '}') { + onyx_report_error(parser->curr->pos, "The #default case must be the last case in a switch statement.\n"); + } + break; } AstTyped* value = parse_expression(parser); diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 9661f1d6..bddcf32e 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -420,15 +420,17 @@ EMIT_FUNC(block, AstBlock* block, b32 generate_block_headers) { *pcode = code; } -EMIT_FUNC(structured_jump, i32 jump_count, JumpType jump) { +EMIT_FUNC(structured_jump, AstJump* jump) { bh_arr(WasmInstruction) code = *pcode; static const u8 wants[Jump_Type_Count] = { 1, 2, 3 }; i32 labelidx = 0; - u8 wanted = wants[jump]; + u8 wanted = wants[jump->jump]; b32 success = 0; + u32 jump_count = jump->count; + i32 len = bh_arr_length(mod->structured_jump_target) - 1; for (u8* t = &bh_arr_last(mod->structured_jump_target); len >= 0; len--, t--) { if (*t == wanted) jump_count--; @@ -446,7 +448,7 @@ EMIT_FUNC(structured_jump, i32 jump_count, JumpType jump) { if (bh_arr_last(code).type != WI_JUMP) WID(WI_JUMP, labelidx); } else { - assert(("Invalid structured jump", 0)); + onyx_report_error(jump->token->pos, "Invalid structured jump."); } *pcode = code; @@ -461,7 +463,7 @@ EMIT_FUNC(statement, AstNode* stmt) { case Ast_Kind_While: emit_while(mod, &code, (AstIfWhile *) stmt); break; case Ast_Kind_For: emit_for(mod, &code, (AstFor *) stmt); break; case Ast_Kind_Switch: emit_switch(mod, &code, (AstSwitch *) stmt); break; - case Ast_Kind_Jump: emit_structured_jump(mod, &code, ((AstJump *) stmt)->count, ((AstJump *) stmt)->jump); break; + case Ast_Kind_Jump: emit_structured_jump(mod, &code, (AstJump *) stmt); break; case Ast_Kind_Block: emit_block(mod, &code, (AstBlock *) stmt, 1); break; case Ast_Kind_Defer: emit_defer(mod, &code, (AstDefer *) stmt); break; default: emit_expression(mod, &code, (AstTyped *) stmt); break;