summaryrefslogtreecommitdiff
path: root/pit/src/runtime/value
diff options
context:
space:
mode:
Diffstat (limited to 'pit/src/runtime/value')
-rw-r--r--pit/src/runtime/value/func.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/pit/src/runtime/value/func.c b/pit/src/runtime/value/func.c
index af039eb..3843553 100644
--- a/pit/src/runtime/value/func.c
+++ b/pit/src/runtime/value/func.c
@@ -94,10 +94,9 @@ pit_value pit_value_func_lambda(pit_runtime *rt, pit_value args, pit_value body)
}
}
arg_cells = pit_value_list_reverse(rt, arg_cells);
- h->in.func.args = arg_cells;
- h->in.func.arg_rest_nm = arg_rest_nm;
- h->in.func.env = env;
- h->in.func.body = expanded;
+ pit_value closure[4] = {env, arg_cells, arg_rest_nm, expanded};
+ h->in.func.nm = PIT_NIL;
+ h->in.func.closure = pit_value_array_from_buf(rt, closure, 4);
return ret;
}
pit_value pit_value_nativefunc_new_with_data(pit_runtime *rt, pit_nativefunc f, void *data) {
@@ -127,7 +126,11 @@ pit_value pit_value_apply(pit_runtime *rt, pit_value f, pit_value args) {
if (h->hsort == PIT_VALUE_HEAVY_SORT_FUNC) {
/* calling a Lisp function is simple! */
pit_value bound = PIT_NIL;
- pit_value env = h->in.func.env;
+ pit_value env = pit_value_array_get(rt, h->in.func.closure, 0);
+ pit_value anames = pit_value_array_get(rt, h->in.func.closure, 1);
+ pit_value arg_rest_nm = pit_value_array_get(rt, h->in.func.closure, 2);
+ pit_value body = pit_value_array_get(rt, h->in.func.closure, 3);
+ if (rt->error != PIT_NIL) return PIT_NIL;
while (env != PIT_NIL) { /* first, bind all entries in the closure */
pit_value b = pit_value_cons_car(rt, env);
pit_value nm = pit_value_cons_car(rt, b);
@@ -135,11 +138,10 @@ pit_value pit_value_apply(pit_runtime *rt, pit_value f, pit_value args) {
bound = pit_value_cons(rt, nm, bound);
env = pit_value_cons_cdr(rt, env);
}
- pit_value anames = h->in.func.args;
while (anames != PIT_NIL) { /* bind all argument names to their values */
pit_value nm = pit_value_cons_car(rt, anames);
pit_value cell = pit_value_cell_new(rt, PIT_NIL);
- if (h->in.func.arg_rest_nm != PIT_NIL && pit_value_eq(nm, h->in.func.arg_rest_nm)) {
+ if (arg_rest_nm != PIT_NIL && pit_value_eq(nm, arg_rest_nm)) {
pit_value_cell_set(rt, cell, args, nm);
pit_symtab_bind(rt, nm, cell);
break;
@@ -151,7 +153,7 @@ pit_value pit_value_apply(pit_runtime *rt, pit_value f, pit_value args) {
args = pit_value_cons_cdr(rt, args);
anames = pit_value_cons_cdr(rt, anames);
}
- pit_value ret = pit_eval(rt, h->in.func.body); /* evaluate the body */
+ pit_value ret = pit_eval(rt, body); /* evaluate the body */
while (bound != PIT_NIL) { /* unbind everything we bound earlier, in reverse */
pit_symtab_unbind(rt, pit_value_cons_car(rt, bound));
bound = pit_value_cons_cdr(rt, bound);