Skip to content

Commit 1dd6975

Browse files
committed
added: very basic implicit closure code
This still required `use ()` after the procedure parameters.
1 parent 17affae commit 1dd6975

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

compiler/src/checker.c

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,32 @@ CHECK_FUNC(symbol, AstNode** symbol_node) {
205205
OnyxToken* token = (*symbol_node)->token;
206206
AstNode* res = symbol_resolve(context, context->checker.current_scope, token);
207207

208+
//
209+
// If the symbol wasn't found, try a very crude search for "capture-able" variables in
210+
// the enclosing scope of the function if that is possible.
211+
if (!res) {
212+
AstFunction *current_func = context->checker.current_entity->function;
213+
214+
if (current_func->kind == Ast_Kind_Function && current_func->captures && current_func->scope_to_lookup_captured_values) {
215+
AstCaptureBlock *block = current_func->captures;
216+
AstTyped *resolved = (AstTyped *) symbol_resolve(context, current_func->scope_to_lookup_captured_values, token);
217+
218+
if (resolved) {
219+
AstCaptureLocal *capture = onyx_ast_node_new(context->ast_alloc, sizeof(AstCaptureLocal), Ast_Kind_Capture_Local);
220+
capture->captured_value = resolved;
221+
capture->token = token;
222+
223+
CHECK(expression, (AstTyped **) &capture);
224+
capture->offset = block->total_size_in_bytes;
225+
block->total_size_in_bytes += type_size_of(capture->type);
226+
227+
bh_arr_push(block->captures, capture);
228+
229+
res = (AstNode *) capture;
230+
}
231+
}
232+
}
233+
208234
if (!res) {
209235
if (context->cycle_detected) {
210236
token_toggle_end(token);
@@ -3509,15 +3535,17 @@ CHECK_FUNC(capture_block, AstCaptureBlock *block, Scope *captured_scope) {
35093535
block->total_size_in_bytes = 8;
35103536

35113537
bh_arr_each(AstCaptureLocal *, capture, block->captures) {
3512-
OnyxToken *token = (*capture)->token;
3513-
AstTyped *resolved = (AstTyped *) symbol_resolve(context, captured_scope, token);
3538+
if (!(*capture)->captured_value) {
3539+
OnyxToken *token = (*capture)->token;
3540+
AstTyped *resolved = (AstTyped *) symbol_resolve(context, captured_scope, token);
35143541

3515-
if (!resolved) {
3516-
// Should this do a yield? In there any case that that would make sense?
3517-
ERROR_(token->pos, "'%b' is not found in the enclosing scope.", token->text, token->length);
3518-
}
3542+
if (!resolved) {
3543+
// Should this do a yield? In there any case that that would make sense?
3544+
ERROR_(token->pos, "'%b' is not found in the enclosing scope.", token->text, token->length);
3545+
}
35193546

3520-
(*capture)->captured_value = resolved;
3547+
(*capture)->captured_value = resolved;
3548+
}
35213549

35223550
CHECK(expression, (AstTyped **) capture);
35233551
if (!(*capture)->type) YIELD((*capture)->token->pos, "Waiting to resolve captures type.");

0 commit comments

Comments
 (0)