};
// Intruction Node
-struct AstReturn { AstNode_base; AstTyped* expr; b32 from_enclosing_scope: 1; };
+struct AstReturn { AstNode_base; AstTyped* expr; u32 count; }; // Note: This count is one less than it should be, because internal codegen with macros would have to know about this and that is error prone.
struct AstJump { AstNode_base; JumpType jump; u32 count; };
typedef struct QualifiedUse {
CheckStatus check_return(AstReturn* retnode) {
Type ** expected_return_type;
- if (retnode->from_enclosing_scope) {
- if (bh_arr_length(expected_return_type_stack) <= 1) {
- ERROR(retnode->token->pos, "#from_enclosing is not valid here, as this return statement is not inside of a do-block or expression macro.");
- }
-
- expected_return_type = expected_return_type_stack[bh_arr_length(expected_return_type_stack) - 2];
- } else {
- expected_return_type = expected_return_type_stack[bh_arr_length(expected_return_type_stack) - 1];
+ if (retnode->count >= (u32) bh_arr_length(expected_return_type_stack)) {
+ ERROR_(retnode->token->pos, "Too many repeated 'return's here. Expected a maximum of %d.",
+ bh_arr_length(expected_return_type_stack));
}
+ expected_return_type = expected_return_type_stack[bh_arr_length(expected_return_type_stack) - retnode->count - 1];
if (retnode->expr) {
CHECK(expression, &retnode->expr);
static AstReturn* parse_return_stmt(OnyxParser* parser) {
AstReturn* return_node = make_node(AstReturn, Ast_Kind_Return);
return_node->token = expect_token(parser, Token_Type_Keyword_Return);
+ return_node->count = 0;
- if (parse_possible_directive(parser, "from_enclosing")) {
- return_node->from_enclosing_scope = 1;
+ while (parser->curr->type == Token_Type_Keyword_Return) {
+ consume_token(parser);
+ return_node->count += 1;
}
AstTyped* expr = NULL;
bh_arr(WasmInstruction) code = *pcode;
AstLocal* result_destination = NULL;
- i64 jump_label = get_structured_jump_label(mod, Jump_Type_Return, ret->from_enclosing_scope ? 2 : 1);
+ i64 jump_label = get_structured_jump_label(mod, Jump_Type_Return, ret->count + 1);
if (bh_arr_length(mod->return_location_stack) > 0 && jump_label >= 0) {
result_destination = bh_arr_last(mod->return_location_stack);
value := o;
if value.has_value do return value.value;
- return #from_enclosing .{};
+ return return .{};
}
catch :: macro (o: ?$T, body: Code) -> T {
value := opt;
if value do return value.value;
- return #from_enclosing .{};
+ return return .{};
}
res := r;
if res.status == .Ok do return res.__data.value;
- return #from_enclosing .{ .Err, .{ error = res.__data.error } };
+ return return .{ .Err, .{ error = res.__data.error } };
}
#doc """
res := r;
if res.status == .Ok do return res.__data.value;
- return #from_enclosing v;
+ return return v;
}
#doc """
If result contains Err, the given code is run. This code is
expected to either:
- Return a good value with `return`
- - Return an error value with `return #from_enclosing`
+ - Return an error value with `return return`
This procedure is subject to change.
"""
raw_free(allocator, file_logger.file);
raw_free(allocator, file_logger);
- return #from_enclosing .{ .Err, .{error = "Unable to open file for logging."} };
+ return return .{ .Err, .{error = "Unable to open file for logging."} };
});
return .{ .Ok, .{ value=file_logger } };