From 6c0da57cf3d4f4d5ab297e02fe2de52e35a66082 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 5 Mar 2023 22:45:06 -0600 Subject: [PATCH] removed: return #from_enclosing; added: repeated `return` --- compiler/include/astnodes.h | 2 +- compiler/src/checker.c | 12 ++++-------- compiler/src/parser.c | 6 ++++-- compiler/src/wasm_emit.c | 2 +- core/container/optional.onyx | 4 ++-- core/container/result.onyx | 6 +++--- core/os/file.onyx | 2 +- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index 65741b13..bfe28a13 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -770,7 +770,7 @@ struct AstDirectiveSolidify { }; // 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 { diff --git a/compiler/src/checker.c b/compiler/src/checker.c index 559b07cd..b9f6fbe3 100644 --- a/compiler/src/checker.c +++ b/compiler/src/checker.c @@ -138,15 +138,11 @@ static bh_arr(Type **) expected_return_type_stack = NULL; 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); diff --git a/compiler/src/parser.c b/compiler/src/parser.c index c1ebbf89..acc460c1 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -1431,9 +1431,11 @@ static i32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret) 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; diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 88ca1d35..076d3a29 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -3755,7 +3755,7 @@ EMIT_FUNC(return, AstReturn* ret) { 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); diff --git a/core/container/optional.onyx b/core/container/optional.onyx index 2db77f0a..30d458a9 100644 --- a/core/container/optional.onyx +++ b/core/container/optional.onyx @@ -85,7 +85,7 @@ package core value := o; if value.has_value do return value.value; - return #from_enclosing .{}; + return return .{}; } catch :: macro (o: ?$T, body: Code) -> T { @@ -125,7 +125,7 @@ package core value := opt; if value do return value.value; - return #from_enclosing .{}; + return return .{}; } diff --git a/core/container/result.onyx b/core/container/result.onyx index 6f498355..4e0ce7cc 100644 --- a/core/container/result.onyx +++ b/core/container/result.onyx @@ -141,7 +141,7 @@ Result_Data :: struct (T: type_expr, E: type_expr) { 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 """ @@ -152,14 +152,14 @@ Result_Data :: struct (T: type_expr, E: type_expr) { 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. """ diff --git a/core/os/file.onyx b/core/os/file.onyx index 5d1d8659..70a77314 100644 --- a/core/os/file.onyx +++ b/core/os/file.onyx @@ -164,7 +164,7 @@ file_logger_open :: (filename: str, allocator := context.allocator) -> Result(&F 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 } }; -- 2.25.1