diff options
Diffstat (limited to 'pit/src/runtime/value')
| -rw-r--r-- | pit/src/runtime/value/func.c | 18 |
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); |
