diff options
Diffstat (limited to 'pit/src/runtime/value/func.c')
| -rw-r--r-- | pit/src/runtime/value/func.c | 133 |
1 files changed, 5 insertions, 128 deletions
diff --git a/pit/src/runtime/value/func.c b/pit/src/runtime/value/func.c index 5f88cb0..ad5ce4c 100644 --- a/pit/src/runtime/value/func.c +++ b/pit/src/runtime/value/func.c @@ -1,61 +1,6 @@ #include <lcq/pit/runtime/value/func.h> -static pit_value free_vars(pit_runtime *rt, pit_value initial_bound, pit_value body) { - i64 expr_stack_reset = rt->expr_stack->next; - pit_value ret = PIT_NIL; - if (pit_vec_push(pit_value)(rt->expr_stack, pit_value_cons(rt, initial_bound, body)) < 0) { - pit_error(rt, "free variable search stack overflow"); - return PIT_NIL; - } - while (rt->expr_stack->next > expr_stack_reset) { - pit_value boundscur, bound, cur; - if (pit_vec_pop(pit_value)(rt->expr_stack, &boundscur) < 0) { - pit_error(rt, "free variable search stack underflow"); - return PIT_NIL; - } - bound = pit_value_cons_car(rt, boundscur); - cur = pit_value_cons_cdr(rt, boundscur); - if (pit_value_is_cons(rt, cur)) { - pit_value fsym = pit_value_cons_car(rt, cur); - bool is_symbol = pit_value_is_symbol(rt, fsym); - pit_value fargs = pit_value_cons_cdr(rt, cur); - if (is_symbol && pit_symtab_symbol_name_match_cstr(rt, fsym, "lambda")) { - pit_value new_bound = pit_value_list_append(rt, pit_value_cons_car(rt, fargs), bound); - fargs = pit_value_cons_cdr(rt, fargs); - while (fargs != PIT_NIL) { - if (pit_vec_push(pit_value)(rt->expr_stack, pit_value_cons(rt, new_bound, pit_value_cons_car(rt, fargs))) < 0) { - pit_error(rt, "free variable search stack overflow"); - return PIT_NIL; - } - fargs = pit_value_cons_cdr(rt, fargs); - } - } else if (is_symbol && pit_symtab_symbol_name_match_cstr(rt, fsym, "quote")) { - /* don't look inside quote! - if we add other special forms, make sure to consider them here if necessary! */ - } else { - while (fargs != PIT_NIL) { - if (pit_vec_push(pit_value)(rt->expr_stack, pit_value_cons(rt, bound, pit_value_cons_car(rt, fargs))) < 0) { - pit_error(rt, "free variable search stack overflow"); - return PIT_NIL; - } - fargs = pit_value_cons_cdr(rt, fargs); - } - if (!is_symbol) { - if (pit_vec_push(pit_value)(rt->expr_stack, pit_value_cons(rt, bound, fsym)) < 0) { - pit_error(rt, "free variable search stack overflow"); - return PIT_NIL; - } - } - } - } else if (pit_value_is_symbol(rt, cur)) { - if (pit_value_list_contains_eq(rt, cur, bound) == PIT_NIL) { - ret = pit_value_cons(rt, cur, ret); - } - } - } - rt->expr_stack->next = expr_stack_reset; - return ret; -} +#include <stdio.h> bool pit_value_is_func(pit_runtime *rt, pit_value a) { return pit_value_is_ref_heavy_sort(rt, a, PIT_VALUE_HEAVY_SORT_FUNC); @@ -63,12 +8,13 @@ bool pit_value_is_func(pit_runtime *rt, pit_value a) { bool pit_value_is_nativefunc(pit_runtime *rt, pit_value a) { return pit_value_is_ref_heavy_sort(rt, a, PIT_VALUE_HEAVY_SORT_NATIVEFUNC); } -pit_value pit_value_func_lambda(pit_runtime *rt, pit_value args, pit_value body) { +pit_value pit_value_func_lambda(pit_runtime *rt, pit_value args, pit_value freevars, pit_value compiled) { + // fprintf(stderr, "lambda args: "); pit_dump_to_file(rt, stderr, args, false); fprintf(stderr, "\n"); + // fprintf(stderr, "lambda freevars: "); pit_dump_to_file(rt, stderr, freevars, false); fprintf(stderr, "\n"); + // fprintf(stderr, "lambda compiled: "); pit_dump_to_file(rt, stderr, compiled, false); fprintf(stderr, "\n"); pit_value ret = pit_value_ref_heavy_new(rt); pit_value_heavy *h = pit_value_ref_deref(rt, pit_value_as_ref(rt, ret)); if (!h) { pit_error(rt, "failed to create new heavy value for lambda"); return PIT_NIL; } - pit_value expanded = pit_macroexpand(rt, pit_value_cons(rt, pit_symtab_intern_cstr(rt, "progn"), body)); - pit_value freevars = free_vars(rt, args, expanded); pit_value env = PIT_NIL; while (freevars != PIT_NIL) { pit_value sym = pit_value_cons_car(rt, freevars); @@ -94,7 +40,6 @@ pit_value pit_value_func_lambda(pit_runtime *rt, pit_value args, pit_value body) } } arg_cells = pit_value_list_reverse(rt, arg_cells); - pit_value compiled = pit_vm_compile(rt, expanded); pit_value closure[4] = {env, arg_cells, arg_rest_nm, compiled}; h->in.func.nm = PIT_NIL; h->in.func.closure = pit_value_array_from_buf(rt, closure, 4); @@ -112,71 +57,3 @@ pit_value pit_value_nativefunc_new_with_data(pit_runtime *rt, pit_nativefunc f, pit_value pit_value_nativefunc_new(pit_runtime *rt, pit_nativefunc f) { return pit_value_nativefunc_new_with_data(rt, f, NULL); } -pit_value pit_value_apply(pit_runtime *rt, pit_value f, pit_value args) { - char buf[256] = {0}; - if (pit_value_is_symbol(rt, f)) { - f = pit_symtab_fget(rt, f); - } - /* if f is not a symbol, assume it is a func or nativefunc - most commonly, this happens when you funcall a variable - with a function in the value cell, e.g. passing a lambda to a function */ - switch (pit_value_sort(f)) { - case PIT_VALUE_SORT_REF: { - pit_value_heavy *h = pit_value_ref_deref(rt, pit_value_as_ref(rt, f)); - if (!h) { pit_error(rt, "bad ref"); return PIT_NIL; } - if (h->hsort == PIT_VALUE_HEAVY_SORT_FUNC) { - /* calling a Lisp function is simple! */ - pit_value bound = PIT_NIL; - 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); - pit_symtab_bind(rt, nm, pit_value_cons_cdr(rt, b)); - bound = pit_value_cons(rt, nm, bound); - env = pit_value_cons_cdr(rt, env); - } - 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 (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; - } else { - pit_value_cell_set(rt, cell, pit_value_cons_car(rt, args), nm); - pit_symtab_bind(rt, nm, cell); - } - bound = pit_value_cons(rt, nm, bound); - args = pit_value_cons_cdr(rt, args); - anames = pit_value_cons_cdr(rt, anames); - } - /* TODO */ - pit_value ret = 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); - } - return ret; - } else if (h->hsort == PIT_VALUE_HEAVY_SORT_NATIVEFUNC) { - /* calling native functions is even simpler */ - return h->in.nativefunc.f(rt, args, h->in.nativefunc.data); - } else { - i64 end = pit_dump(rt, buf, sizeof(buf) - 1, f, true); - buf[end] = 0; - pit_error(rt, "attempted to apply non-function ref: %s", buf); - return PIT_NIL; - } - } - default: { - i64 end = pit_dump(rt, buf, sizeof(buf) - 1, f, true); - buf[end] = 0; - pit_error(rt, "attempted to apply non-function value: %s", buf); - return PIT_NIL; - } - } -} |
