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.c133
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;
- }
- }
-}