diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-07-14 14:13:23 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-07-14 14:13:23 -0400 |
| commit | d3f14cf53cf857b90184900a726e3ee0875dea80 (patch) | |
| tree | b1f89d5be1781ce4ed1384446bc53b51118d0350 /environment.c | |
| parent | 4e6d8162bfa7149c3b947c6c759f82c1f52ef4d7 (diff) | |
Support nested lambda closures
Diffstat (limited to 'environment.c')
| -rw-r--r-- | environment.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/environment.c b/environment.c index 65130c37..1fe698d2 100644 --- a/environment.c +++ b/environment.c @@ -372,11 +372,16 @@ env_t *namespace_env(env_t *env, const char *namespace_name) binding_t *get_binding(env_t *env, const char *name) { binding_t *b = Table$str_get(*env->locals, name); - if (!b && env->fn_ctx && env->fn_ctx->closure_scope) { - b = Table$str_get(*env->fn_ctx->closure_scope, name); - if (b) { - Table$str_set(env->fn_ctx->closed_vars, name, b); - return new(binding_t, .type=b->type, .code=CORD_all("userdata->", name)); + if (!b) { + for (fn_ctx_t *fn_ctx = env->fn_ctx; fn_ctx; fn_ctx = fn_ctx->parent) { + if (!fn_ctx->closure_scope) continue; + b = Table$str_get(*fn_ctx->closure_scope, name); + if (b) { + Table$str_set(env->fn_ctx->closed_vars, name, b); + binding_t *b2 = new(binding_t, .type=b->type, .code=CORD_all("userdata->", name)); + Table$str_set(env->locals, name, b2); + return b2; + } } } return b; |
