CheckStatus check_constraint(AstConstraint *constraint);
CheckStatus check_constraint_context(ConstraintContext *cc, Scope *scope, OnyxFilePos pos);
CheckStatus check_polyquery(AstPolyQuery *query);
+CheckStatus check_directive_first(AstDirectiveFirst *first);
// HACK HACK HACK
b32 expression_types_must_be_known = 0;
b32 all_checks_are_final = 1;
b32 inside_for_iterator = 0;
+bh_arr(AstFor *) for_node_stack = NULL;
#define STATEMENT_LEVEL 1
#define EXPRESSION_LEVEL 2
fornode->flags |= Ast_Flag_Has_Been_Checked;
+
fornode_expr_checked:
+ bh_arr_push(for_node_stack, fornode);
+
old_inside_for_iterator = inside_for_iterator;
inside_for_iterator = 0;
iter_type = fornode->iter->type;
if (cs > Check_Errors_Start) return cs;
} while(0);
+ bh_arr_pop(for_node_stack);
return Check_Success;
}
if (expr->type == NULL) YIELD(expr->token->pos, "Waiting to know globals type.");
break;
+ case Ast_Kind_Directive_First:
+ CHECK(directive_first, (AstDirectiveFirst *) expr);
+ break;
+
case Ast_Kind_StrLit: break;
case Ast_Kind_File_Contents: break;
case Ast_Kind_Overloaded_Function: break;
return Check_Success;
}
+CheckStatus check_directive_first(AstDirectiveFirst *first) {
+ if (bh_arr_length(for_node_stack) == 0) {
+ ERROR(first->token->pos, "#first is only allowed in the body of a for-loop.");
+ }
+
+ first->for_node = bh_arr_last(for_node_stack);
+ assert(first->for_node);
+
+ first->for_node->has_first = 1;
+
+ return Check_Success;
+}
+
CheckStatus check_statement(AstNode** pstmt) {
AstNode* stmt = *pstmt;
}
}
- inside_for_iterator = 0;
expected_return_type = &func->type->Function.return_type;
+
+ inside_for_iterator = 0;
+ if (for_node_stack) bh_arr_clear(for_node_stack);
+
if (func->body) {
CheckStatus status = check_block(func->body);
if (status == Check_Error && func->generated_from && context.cycle_detected == 0)
WIL(for_node->token, WI_LOCAL_TEE, low_local);
WIL(for_node->token, WI_LOCAL_SET, iter_local);
+ if (for_node->has_first) {
+ for_node->first_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
+ WIL(for_node->token, WI_I32_CONST, 1);
+ WIL(for_node->token, WI_LOCAL_SET, for_node->first_local);
+ }
+
emit_enter_structured_block(mod, &code, SBT_Breakable_Block, for_node->token);
emit_enter_structured_block(mod, &code, SBT_Basic_Loop, for_node->token);
emit_enter_structured_block(mod, &code, SBT_Continue_Block, for_node->token);
WIL(for_node->token, WI_LOCAL_GET, step_local);
WI(for_node->token, WI_I32_ADD);
WIL(for_node->token, WI_LOCAL_SET, iter_local);
+
+ if (for_node->has_first) {
+ WIL(for_node->token, WI_I32_CONST, 0);
+ WIL(for_node->token, WI_LOCAL_SET, for_node->first_local);
+ }
if (bh_arr_last(code).type != WI_JUMP)
WID(for_node->token, WI_JUMP, 0x00);
emit_leave_structured_block(mod, &code);
emit_leave_structured_block(mod, &code);
+ if (for_node->has_first) local_raw_free(mod->local_alloc, WASM_TYPE_INT32);
local_raw_free(mod->local_alloc, onyx_type_to_wasm_type(low_mem.type));
local_raw_free(mod->local_alloc, onyx_type_to_wasm_type(high_mem.type));
local_raw_free(mod->local_alloc, onyx_type_to_wasm_type(step_mem.type));
WI(for_node->token, WI_PTR_ADD);
WIL(for_node->token, WI_LOCAL_SET, end_ptr_local);
+ if (for_node->has_first) {
+ for_node->first_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
+ WIL(for_node->token, WI_I32_CONST, 1);
+ WIL(for_node->token, WI_LOCAL_SET, for_node->first_local);
+ }
+
emit_enter_structured_block(mod, &code, SBT_Breakable_Block, for_node->token);
emit_enter_structured_block(mod, &code, SBT_Basic_Loop, for_node->token);
emit_enter_structured_block(mod, &code, SBT_Continue_Block, for_node->token);
WI(for_node->token, WI_PTR_ADD);
WIL(for_node->token, WI_LOCAL_SET, ptr_local);
+ if (for_node->has_first) {
+ WIL(NULL, WI_I32_CONST, 0);
+ WIL(NULL, WI_LOCAL_SET, for_node->first_local);
+ }
+
if (bh_arr_last(code).type != WI_JUMP)
WID(for_node->token, WI_JUMP, 0x00);
emit_leave_structured_block(mod, &code);
emit_leave_structured_block(mod, &code);
+ if (for_node->has_first) local_raw_free(mod->local_alloc, WASM_TYPE_INT32);
+
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
if (!for_node->by_pointer) local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
WI(for_node->token, WI_PTR_ADD);
WIL(for_node->token, WI_LOCAL_SET, end_ptr_local);
+ if (for_node->has_first) {
+ for_node->first_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
+ WIL(for_node->token, WI_I32_CONST, 1);
+ WIL(for_node->token, WI_LOCAL_SET, for_node->first_local);
+ }
+
emit_enter_structured_block(mod, &code, SBT_Breakable_Block, for_node->token);
emit_enter_structured_block(mod, &code, SBT_Basic_Loop, for_node->token);
emit_enter_structured_block(mod, &code, SBT_Continue_Block, for_node->token);
WI(for_node->token, WI_PTR_ADD);
WIL(for_node->token, WI_LOCAL_SET, ptr_local);
+ if (for_node->has_first) {
+ WIL(NULL, WI_I32_CONST, 0);
+ WIL(NULL, WI_LOCAL_SET, for_node->first_local);
+ }
+
if (bh_arr_last(code).type != WI_JUMP)
WID(for_node->token, WI_JUMP, 0x00);
emit_leave_structured_block(mod, &code);
emit_leave_structured_block(mod, &code);
+ if (for_node->has_first) local_raw_free(mod->local_alloc, WASM_TYPE_INT32);
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
if (!for_node->by_pointer) local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
bh_arr_push(mod->for_remove_info, remove_info);
}
+ if (for_node->has_first) {
+ for_node->first_local = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
+ WIL(for_node->token, WI_I32_CONST, 1);
+ WIL(for_node->token, WI_LOCAL_SET, for_node->first_local);
+ }
+
AstLocal* var = for_node->var;
b32 it_is_local = (b32) ((iter_local & LOCAL_IS_WASM) != 0);
u64 offset = 0;
WID(for_node->token, WI_COND_JUMP, 0x01);
emit_block(mod, &code, for_node->stmt, 0);
+
+ if (for_node->has_first) {
+ WIL(NULL, WI_I32_CONST, 0);
+ WIL(NULL, WI_LOCAL_SET, for_node->first_local);
+ }
+
WID(for_node->token, WI_JUMP, 0x00);
emit_leave_structured_block(mod, &code);
bh_arr_pop(mod->for_remove_info);
+ if (for_node->has_first) local_raw_free(mod->local_alloc, WASM_TYPE_INT32);
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
local_raw_free(mod->local_alloc, WASM_TYPE_FUNC);
local_raw_free(mod->local_alloc, WASM_TYPE_FUNC);
break;
}
+ case Ast_Kind_Directive_First: {
+ AstDirectiveFirst *first = (AstDirectiveFirst *) expr;
+ WIL(first->token, WI_LOCAL_GET, first->for_node->first_local);
+ break;
+ }
+
default:
bh_printf("Unhandled case: %d\n", expr->kind);
DEBUG_HERE;