aboutsummaryrefslogtreecommitdiff
path: root/environment.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-07-14 14:13:23 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-07-14 14:13:23 -0400
commitd3f14cf53cf857b90184900a726e3ee0875dea80 (patch)
treeb1f89d5be1781ce4ed1384446bc53b51118d0350 /environment.c
parent4e6d8162bfa7149c3b947c6c759f82c1f52ef4d7 (diff)
Support nested lambda closures
Diffstat (limited to 'environment.c')
-rw-r--r--environment.c15
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;