From: Brendan Hansen Date: Fri, 12 Nov 2021 20:46:35 +0000 (-0600) Subject: theoretical improvement to yielding in blocks X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=6e44a33c8d199031a33a8f2aa50bdc31f2c8684c;p=onyx.git theoretical improvement to yielding in blocks --- diff --git a/include/astnodes.h b/include/astnodes.h index 6c9e8d5c..a00ea249 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -705,6 +705,8 @@ struct AstBlock { Scope *scope; Scope *binding_scope; BlockRule rules; + + u32 statement_idx; }; struct AstDefer { AstNode_base; AstNode *stmt; }; struct AstFor { diff --git a/src/checker.c b/src/checker.c index 253f4db7..8b871e7a 100644 --- a/src/checker.c +++ b/src/checker.c @@ -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; } diff --git a/src/symres.c b/src/symres.c index 9757e6e8..5bbb228f 100644 --- a/src/symres.c +++ b/src/symres.c @@ -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();