From b9a80d8bbc568ae8e995fde0ea1710359ab4ab1c Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 18 Oct 2021 16:32:39 +0200 Subject: Fix a bug with too early binding of parameters --- src/bootstrap/primitives.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src/bootstrap/primitives.c') diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 0f1498d..7ac9bf7 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -104,6 +104,12 @@ eval_lambda: // Extend environment. env = env_extend(tmp, env); } + + // Create temporary environment to store bindings. + Environment *tmp = env_create(env); + push_active_env(tmp); + + // Evaluate arguments in temporary environment. while (params != obj_nil) { if (args == obj_nil) { error_push((Error){ @@ -124,7 +130,7 @@ eval_lambda: }); return obj_err; } - env_add_or_update_current(env, symbol, value); + env_add_or_update_current(tmp, symbol, value); args = args->cdr; params = params->cdr; } @@ -135,6 +141,22 @@ eval_lambda: }); return obj_err; } + + // Copy temporary environment values to closure environment. + args = root->cdr; + params = lambda->params; + while (params != obj_nil) { + Object *symbol = params->car; + Object *value = env_lookup(tmp, symbol); + env_add_or_update_current(env, symbol, value); + args = args->cdr; + params = params->cdr; + } + + // Release the temporary environment protection. + pop_active_env(); + + // Run the body of the function. root = lambda->body; while (root->cdr != obj_nil) { if (eval(env, root->car) == obj_err) { -- cgit v1.2.1