removed: return #from_enclosing; added: repeated `return`
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 6 Mar 2023 04:45:06 +0000 (22:45 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 6 Mar 2023 04:45:14 +0000 (22:45 -0600)
compiler/include/astnodes.h
compiler/src/checker.c
compiler/src/parser.c
compiler/src/wasm_emit.c
core/container/optional.onyx
core/container/result.onyx
core/os/file.onyx

index 65741b13c53de1bdb7eb16361760a0189d5bc792..bfe28a13d1eead57a5a3305397ef679e5b258d36 100644 (file)
@@ -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 {
index 559b07cda9692878a48a1aac62ddba474db7a056..b9f6fbe3a6e1f18837cfa37556c1d3ae4d071908 100644 (file)
@@ -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);
index c1ebbf89c8c0bcfe9c328c4a46881e1fec89073a..acc460c1c08b417647abca4ef99db615f5f84801 100644 (file)
@@ -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;
index 88ca1d351807c4617a81bac9c744dff419eba379..076d3a2958d282b9cec62404f39256baaa4b0470 100644 (file)
@@ -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);
index 2db77f0a60d14ec6fe2c3f844486d35e8b20bc51..30d458a97ef067b1ee507c9aaca008feb0362c0f 100644 (file)
@@ -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 .{};
 }
 
 
index 6f4983552dd7e32c3ac0d558f02d4ed2c279edb1..4e0ce7cc3a2dc200cd31fc4897e54b01c6ffa79c 100644 (file)
@@ -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.
     """
index 5d1d86598cbb016c3ffa100e241e36a751da8c4f..70a77314c0c02e07e7c1926ee87a5d7bf8292983 100644 (file)
@@ -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 } };