theoretical improvement to yielding in blocks
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 12 Nov 2021 20:46:35 +0000 (14:46 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 12 Nov 2021 20:46:35 +0000 (14:46 -0600)
include/astnodes.h
src/checker.c
src/symres.c

index 6c9e8d5ca802b61b807e37fc92bb801ab2cdf59b..a00ea249669b9aa43a008668c16e8e286c2371a2 100644 (file)
@@ -705,6 +705,8 @@ struct AstBlock         {
     Scope *scope;
     Scope *binding_scope;
     BlockRule rules;
+
+    u32 statement_idx;
 };
 struct AstDefer         { AstNode_base; AstNode *stmt; };
 struct AstFor           {
index 253f4db72f099df981c6130db54d3bfee20948bc..8b871e7a0ed41e1d851bf062b603e6a5acf440a7 100644 (file)
@@ -1849,29 +1849,30 @@ CheckStatus check_statement_chain(AstNode** start) {
 }
 
 CheckStatus check_block(AstBlock* block) {
-    CHECK(statement_chain, &block->body);
-
-    // CLEANUP: There will need to be some other method of 
-    // checking the following conditions.
-    //
-    // bh_arr_each(AstTyped *, value, block->allocate_exprs) {
-    //     fill_in_type(*value);
-
-    //     if ((*value)->kind == Ast_Kind_Local) {
-    //         if ((*value)->type == NULL) {
-    //             onyx_report_error((*value)->token->pos,
-    //                     "Unable to resolve type for local '%b'.",
-    //                     (*value)->token->text, (*value)->token->length);
-    //             return Check_Error;
-    //         }
-
-    //         if ((*value)->type->kind == Type_Kind_Compound) {
-    //             onyx_report_error((*value)->token->pos,
-    //                     "Compound type not allowed as local variable type. Try splitting this into multiple variables.");
-    //             return Check_Error;
-    //         }
-    //     }
-    // }
+    // This used to use statement_chain, but since block optimize which statements need to be rechecked,
+    // it has to be its own thing.
+
+    AstNode** start = &block->body;
+    fori (i, 0, block->statement_idx) {
+        start = &(*start)->next;
+    }
+
+    while (*start) {
+        CheckStatus cs = check_statement(start);
+        switch (cs) {
+            case Check_Success:
+                start = &(*start)->next;
+                block->statement_idx++;
+                break;
+
+            case Check_Return_To_Symres:
+                block->statement_idx = 0;
+
+            default:
+                return cs;
+        }
+
+    }
 
     return Check_Success;
 }
index 9757e6e853e67507127f634103ba214086884d10..5bbb228fb4e4ba48c07d3068a3dfe7ee6d050051 100644 (file)
@@ -860,8 +860,38 @@ static SymresStatus symres_block(AstBlock* block) {
     if (block->binding_scope != NULL)
         scope_include(curr_scope, block->binding_scope, block->token->pos);
 
-    if (block->body)
-        SYMRES(statement_chain, &block->body);
+    if (block->body) {
+        AstNode** start = &block->body;
+        fori (i, 0, block->statement_idx) {
+            start = &(*start)->next;
+        }
+
+        b32 remove = 0;
+
+        while (*start) {
+            SymresStatus cs = symres_statement(start, &remove);
+
+            if (remove) {
+                remove = 0;
+                AstNode* tmp = (*start)->next;
+                (*start)->next = NULL;
+                (*start) = tmp;
+
+            } else {
+                switch (cs) {
+                    case Symres_Success:
+                        start = &(*start)->next;
+                        block->statement_idx++;
+                        break;
+
+                    default:
+                        return cs;
+                }
+            }
+        }
+
+        block->statement_idx = 0;
+    }
 
     if (block->rules & Block_Rule_New_Scope)
         scope_leave();