- 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 ...
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 {
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);
// 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;
}
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'.",
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;
}
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);
*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--;
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;
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;