diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bootstrap/objects.h | 2 | ||||
-rw-r--r-- | src/bootstrap/primitives.c | 24 |
2 files changed, 24 insertions, 2 deletions
diff --git a/src/bootstrap/objects.h b/src/bootstrap/objects.h index 56821eb..cba6f10 100644 --- a/src/bootstrap/objects.h +++ b/src/bootstrap/objects.h | |||
@@ -56,7 +56,7 @@ typedef struct Object { | |||
56 | 56 | ||
57 | // Object constructors. | 57 | // Object constructors. |
58 | Object * make_fixnum(ssize_t num); | 58 | Object * make_fixnum(ssize_t num); |
59 | Object * make_procedure(Object *(*proc)(struct Environment *, struct Object *args)); | 59 | Object * make_procedure(Object *(*proc)(struct Environment *, Object *args)); |
60 | Object * make_pair(Object *car, Object *cdr); | 60 | Object * make_pair(Object *car, Object *cdr); |
61 | Object * make_symbol(StringView sv); | 61 | Object * make_symbol(StringView sv); |
62 | Object * make_string(void); | 62 | Object * make_string(void); |
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) { |