#include #include 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); } 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 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 env = PIT_NIL; while (freevars != PIT_NIL) { pit_value sym = pit_value_cons_car(rt, freevars); pit_value cell = pit_symtab_get_value_cell(rt, sym); env = pit_value_cons(rt, pit_value_cons(rt, sym, cell), env); freevars = pit_value_cons_cdr(rt, freevars); } h->hsort = PIT_VALUE_HEAVY_SORT_FUNC; pit_value arg_cells = PIT_NIL; pit_value arg_rest_nm = PIT_NIL; pit_value separator = pit_symtab_intern_cstr(rt, "&"); while (args != PIT_NIL) { pit_value nm = pit_value_cons_car(rt, args); if (pit_value_eq(nm, separator)) { pit_value next_nm = pit_value_cons_car(rt, pit_value_cons_cdr(rt, args)); if (next_nm == PIT_NIL) { pit_error(rt, "invalid & in lambda list"); return PIT_NIL; } arg_rest_nm = next_nm; arg_cells = pit_value_cons(rt, next_nm, arg_cells); break; } else { arg_cells = pit_value_cons(rt, nm, arg_cells); args = pit_value_cons_cdr(rt, args); } } arg_cells = pit_value_list_reverse(rt, arg_cells); 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); return ret; } pit_value pit_value_nativefunc_new_with_data(pit_runtime *rt, pit_nativefunc f, void *data) { 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 nativefunc"); return PIT_NIL; } h->hsort = PIT_VALUE_HEAVY_SORT_NATIVEFUNC; h->in.nativefunc.f = f; h->in.nativefunc.data = data; return ret; } pit_value pit_value_nativefunc_new(pit_runtime *rt, pit_nativefunc f) { return pit_value_nativefunc_new_with_data(rt, f, NULL); }