diff options
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r-- | src/bootstrap/primitives.c | 24 |
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) { |