aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/primitives.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r--src/bootstrap/primitives.c24
1 files changed, 23 insertions, 1 deletions
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:
104 // Extend environment. 104 // Extend environment.
105 env = env_extend(tmp, env); 105 env = env_extend(tmp, env);
106 } 106 }
107
108 // Create temporary environment to store bindings.
109 Environment *tmp = env_create(env);
110 push_active_env(tmp);
111
112 // Evaluate arguments in temporary environment.
107 while (params != obj_nil) { 113 while (params != obj_nil) {
108 if (args == obj_nil) { 114 if (args == obj_nil) {
109 error_push((Error){ 115 error_push((Error){
@@ -124,7 +130,7 @@ eval_lambda:
124 }); 130 });
125 return obj_err; 131 return obj_err;
126 } 132 }
127 env_add_or_update_current(env, symbol, value); 133 env_add_or_update_current(tmp, symbol, value);
128 args = args->cdr; 134 args = args->cdr;
129 params = params->cdr; 135 params = params->cdr;
130 } 136 }
@@ -135,6 +141,22 @@ eval_lambda:
135 }); 141 });
136 return obj_err; 142 return obj_err;
137 } 143 }
144
145 // Copy temporary environment values to closure environment.
146 args = root->cdr;
147 params = lambda->params;
148 while (params != obj_nil) {
149 Object *symbol = params->car;
150 Object *value = env_lookup(tmp, symbol);
151 env_add_or_update_current(env, symbol, value);
152 args = args->cdr;
153 params = params->cdr;
154 }
155
156 // Release the temporary environment protection.
157 pop_active_env();
158
159 // Run the body of the function.
138 root = lambda->body; 160 root = lambda->body;
139 while (root->cdr != obj_nil) { 161 while (root->cdr != obj_nil) {
140 if (eval(env, root->car) == obj_err) { 162 if (eval(env, root->car) == obj_err) {