summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-09-06 17:40:51 -0400
committerLLLL Colonq <llll@colonq>2026-09-06 17:40:51 -0400
commit71bfa9094a4a25f762d681bb07f79f92a95dbb87 (patch)
tree1b7ff31dad86e072a37e4270e762a5e0f12f87ac
parent843ea34efc2c5ea10edc4d534304f8287f97fbbc (diff)
pit: Fix evaluator bug
-rw-r--r--pit/include/lcq/pit/arena.h6
-rw-r--r--pit/include/lcq/pit/runtime/gc.h1
-rw-r--r--pit/include/lcq/pit/runtime/symtab.h3
-rw-r--r--pit/src/arena.c4
-rw-r--r--pit/src/library.c11
-rw-r--r--pit/src/runtime/compile.c3
-rw-r--r--pit/src/runtime/eval.c102
-rw-r--r--pit/src/runtime/gc.c12
-rw-r--r--pit/src/runtime/symtab.c16
-rw-r--r--pit/src/runtime/value/cell.c2
-rw-r--r--pit/src/runtime/value/small.c8
-rw-r--r--pit/test/array.pit (renamed from pit/test/array.lisp)0
-rw-r--r--pit/test/broken.pit (renamed from pit/test/broken.lisp)0
-rw-r--r--pit/test/fold.pit (renamed from pit/test/fold.lisp)0
-rw-r--r--pit/test/nonbroken.pit (renamed from pit/test/nonbroken.lisp)0
-rw-r--r--pit/test/struct.pit (renamed from pit/test/struct.lisp)0
-rw-r--r--pit/test/test.pit (renamed from pit/test/test.lisp)0
-rw-r--r--pit/test/test10.pit5
-rw-r--r--pit/test/test11.pit4
-rw-r--r--pit/test/test2.pit (renamed from pit/test/test2.lisp)0
-rw-r--r--pit/test/test3.pit (renamed from pit/test/test3.lisp)0
-rw-r--r--pit/test/test5.pit3
-rw-r--r--pit/test/thebug.pit (renamed from pit/test/thebug.lisp)0
-rw-r--r--pit/test/thebug2.pit (renamed from pit/test/thebug2.lisp)0
-rw-r--r--pit/test/y.pit (renamed from pit/test/y.lisp)0
25 files changed, 107 insertions, 73 deletions
diff --git a/pit/include/lcq/pit/arena.h b/pit/include/lcq/pit/arena.h
index fcaca55..82f66a5 100644
--- a/pit/include/lcq/pit/arena.h
+++ b/pit/include/lcq/pit/arena.h
@@ -2,6 +2,7 @@
#define LCOLONQ_PIT_ARENA_H
#include <lcq/pit/types.h>
+#include <lcq/pit/utils.h>
typedef i64 pit_arena_index;
@@ -21,6 +22,11 @@ typedef struct {
u8 data[];
} pit_arena;
+static inline i64 pit_arena_byte_idx(pit_arena *a, pit_arena_index idx) {
+ i64 byte_idx = 0; pit_mul(&byte_idx, a->elem_size, idx);
+ return byte_idx;
+}
+
/* create a new arena in a buffer of buf_len size in bytes that stores elements of elem_size */
pit_arena *pit_arena_new(u8 *buf, i64 buf_len, i64 elem_size);
diff --git a/pit/include/lcq/pit/runtime/gc.h b/pit/include/lcq/pit/runtime/gc.h
index 49921f0..713c7d4 100644
--- a/pit/include/lcq/pit/runtime/gc.h
+++ b/pit/include/lcq/pit/runtime/gc.h
@@ -4,5 +4,6 @@
#include <lcq/pit/runtime.h>
void pit_gc(pit_runtime *rt);
+void pit_gc_if_necessary(pit_runtime *rt);
#endif
diff --git a/pit/include/lcq/pit/runtime/symtab.h b/pit/include/lcq/pit/runtime/symtab.h
index e385884..183af8d 100644
--- a/pit/include/lcq/pit/runtime/symtab.h
+++ b/pit/include/lcq/pit/runtime/symtab.h
@@ -20,7 +20,8 @@ void pit_symtab_symbol_mark_macro(pit_runtime *rt, pit_value sym);
void pit_symtab_mset(pit_runtime *rt, pit_value sym, pit_value v);
bool pit_symtab_is_symbol_special_form(pit_runtime *rt, pit_value sym);
void pit_symtab_symbol_mark_special_form(pit_runtime *rt, pit_value sym);
-void pit_symtab_bind(pit_runtime *rt, pit_value sym, pit_value v);
+void pit_symtab_replace(pit_runtime *rt, pit_value sym, pit_value cell);
+void pit_symtab_bind(pit_runtime *rt, pit_value sym, pit_value cell);
pit_value pit_symtab_unbind(pit_runtime *rt, pit_value sym);
#endif
diff --git a/pit/src/arena.c b/pit/src/arena.c
index aedf0fb..ca76b12 100644
--- a/pit/src/arena.c
+++ b/pit/src/arena.c
@@ -19,10 +19,6 @@ void pit_arena_reset(pit_arena *a) {
a->next = 0;
a->back = a->capacity;
}
-static i64 pit_arena_byte_idx(pit_arena *a, pit_arena_index idx) {
- i64 byte_idx = 0; pit_mul(&byte_idx, a->elem_size, idx);
- return byte_idx;
-}
pit_arena_index pit_arena_alloc_index(pit_arena *a) {
i64 ret = a->next;
i64 byte_idx = pit_arena_byte_idx(a, ret);
diff --git a/pit/src/library.c b/pit/src/library.c
index b911321..10f56f4 100644
--- a/pit/src/library.c
+++ b/pit/src/library.c
@@ -257,9 +257,7 @@ static pit_value impl_error(pit_runtime *rt, pit_value args, void *data) {
}
static pit_value impl_eval(pit_runtime *rt, pit_value args, void *data) {
(void) data;
- // TODO
- return PIT_NIL;
- // return pit_eval(rt, pit_value_cons_car(rt, args));
+ return pit_vm_eval(rt, pit_compile(rt, pit_value_cons_car(rt, args)));
}
static pit_value impl_eq_p(pit_runtime *rt, pit_value args, void *data) {
(void) data;
@@ -679,6 +677,12 @@ static pit_value impl_div(pit_runtime *rt, pit_value args, void *data) {
}
return pit_value_integer_new(rt, total);
}
+static pit_value impl_mod(pit_runtime *rt, pit_value args, void *data) {
+ (void) data;
+ i64 x = pit_value_as_integer(rt, pit_value_cons_car(rt, args));
+ i64 y = pit_value_as_integer(rt, pit_value_cons_car(rt, pit_value_cons_cdr(rt, args)));
+ return pit_value_integer_new(rt, x % y);
+}
static pit_value impl_not(pit_runtime *rt, pit_value args, void *data) {
(void) data;
if (pit_value_cons_car(rt, args) == PIT_NIL) {
@@ -831,6 +835,7 @@ void pit_install_library_essential(pit_runtime *rt) {
pit_symtab_fset(rt, pit_symtab_intern_cstr(rt, "-"), pit_value_nativefunc_new(rt, impl_sub));
pit_symtab_fset(rt, pit_symtab_intern_cstr(rt, "*"), pit_value_nativefunc_new(rt, impl_mul));
pit_symtab_fset(rt, pit_symtab_intern_cstr(rt, "/"), pit_value_nativefunc_new(rt, impl_div));
+ pit_symtab_fset(rt, pit_symtab_intern_cstr(rt, "%"), pit_value_nativefunc_new(rt, impl_mod));
/* booleans */
pit_symtab_fset(rt, pit_symtab_intern_cstr(rt, "not"), pit_value_nativefunc_new(rt, impl_not));
/* comparisons */
diff --git a/pit/src/runtime/compile.c b/pit/src/runtime/compile.c
index 7cfc091..61959b2 100644
--- a/pit/src/runtime/compile.c
+++ b/pit/src/runtime/compile.c
@@ -180,8 +180,6 @@ static void compile_interpret_traversal_entry(pit_runtime *rt, pit_traversal_ent
}
}
-#include <stdio.h>
-
pit_value pit_compile(pit_runtime *rt, pit_value top) {
/* compilation proceeds in a somewhat unintuitive manner */
/* typically, we would simply recursively traverse the tree, accumulating the output code */
@@ -302,7 +300,6 @@ end: {
}
rt->compilation_stack->next = compilation_stack_reset;
rt->traversal->next = traversal_reset;
- pit_fprintf(rt, stderr, "here: %v\n", ret, ret);
return ret;
}
}
diff --git a/pit/src/runtime/eval.c b/pit/src/runtime/eval.c
index 5966fdb..7c64418 100644
--- a/pit/src/runtime/eval.c
+++ b/pit/src/runtime/eval.c
@@ -1,7 +1,5 @@
#include <lcq/pit/runtime/eval.h>
-#include <stdio.h>
-
/* add a new stack frame to the vm (with a tag and callsite annotation) */
static void vm_push_code_func(pit_runtime *rt, pit_value code, pit_value tag, pit_annotation ann, pit_value bound) {
pit_callstack_entry ent;
@@ -15,11 +13,11 @@ static void vm_push_code_func(pit_runtime *rt, pit_value code, pit_value tag, pi
}
/* add a new stack frame to the vm (with no annotation) */
-static void vm_push_code(pit_runtime *rt, pit_value code) {
+static void vm_push_code(pit_runtime *rt, pit_value code, pit_value bound) {
pit_annotation ann;
ann.line = -1;
ann.column = -1;
- vm_push_code_func(rt, code, PIT_NIL, ann, PIT_NIL);
+ vm_push_code_func(rt, code, PIT_NIL, ann, bound);
}
static void vm_push(pit_runtime *rt, pit_value v) {
@@ -36,8 +34,19 @@ static pit_value vm_pop(pit_runtime *rt) {
return ret;
}
-static void vm_call_lisp(pit_runtime *rt, pit_value tag, pit_value closure, pit_value args) {
- pit_value bound = PIT_NIL;
+static pit_value vm_bind_or_replace(pit_runtime *rt, pit_value nm, pit_value cell, pit_value bound) {
+ if (pit_value_list_contains_eq(rt, nm, bound)) {
+ /* if we're already responsible for unbinding this symbol (e.g. in a tail call), */
+ /* simply replace the old binding - this keeps the binding stack from growing for TCO purposes */
+ pit_symtab_replace(rt, nm, cell);
+ } else {
+ pit_symtab_bind(rt, nm, cell);
+ bound = pit_value_cons(rt, nm, bound);
+ }
+ return bound;
+}
+
+static void vm_call_lisp(pit_runtime *rt, pit_value tag, pit_value closure, pit_value args, pit_value bound) {
pit_value env = pit_value_array_get(rt, closure, 0);
pit_value anames = pit_value_array_get(rt, closure, 1);
pit_value arg_rest_nm = pit_value_array_get(rt, closure, 2);
@@ -46,8 +55,7 @@ static void vm_call_lisp(pit_runtime *rt, pit_value tag, pit_value closure, pit_
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);
+ bound = vm_bind_or_replace(rt, nm, pit_value_cons_cdr(rt, b), bound);
env = pit_value_cons_cdr(rt, env);
}
while (anames != PIT_NIL) { /* bind all argument names to their values */
@@ -55,13 +63,12 @@ static void vm_call_lisp(pit_runtime *rt, pit_value tag, pit_value closure, pit_
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);
+ bound = vm_bind_or_replace(rt, nm, cell, bound);
break;
} else {
pit_value_cell_set(rt, cell, pit_value_cons_car(rt, args), nm);
- pit_symtab_bind(rt, nm, cell);
+ bound = vm_bind_or_replace(rt, nm, cell, bound);
}
- bound = pit_value_cons(rt, nm, bound);
args = pit_value_cons_cdr(rt, args);
anames = pit_value_cons_cdr(rt, anames);
}
@@ -71,7 +78,7 @@ static void vm_call_lisp(pit_runtime *rt, pit_value tag, pit_value closure, pit_
vm_push_code_func(rt, body, tag, ann, bound);
}
-static bool vm_call(pit_runtime *rt, pit_value f, pit_value args) {
+static bool vm_call(pit_runtime *rt, pit_value f, pit_value args, pit_value bound) {
char buf[256] = {0};
if (pit_value_is_symbol(rt, f)) f = pit_symtab_fget(rt, f);
switch (pit_value_sort(f)) {
@@ -79,11 +86,17 @@ static bool vm_call(pit_runtime *rt, pit_value f, pit_value args) {
pit_value_heavy *h = pit_value_ref_deref(rt, pit_value_as_ref(rt, f));
if (!h) { pit_error(rt, "bad ref for function"); return false; }
switch (h->hsort) {
- case PIT_VALUE_HEAVY_SORT_NATIVEFUNC:
+ case PIT_VALUE_HEAVY_SORT_NATIVEFUNC: {
vm_push(rt, h->in.nativefunc.f(rt, args, h->in.nativefunc.data));
+ /* if we've performed a native call, the frame is over - unbind everything left over */
+ while (bound != PIT_NIL) {
+ pit_symtab_unbind(rt, pit_value_cons_car(rt, bound));
+ bound = pit_value_cons_cdr(rt, bound);
+ }
break;
+ }
case PIT_VALUE_HEAVY_SORT_FUNC:
- vm_call_lisp(rt, h->in.func.nm, h->in.func.closure, args);
+ vm_call_lisp(rt, h->in.func.nm, h->in.func.closure, args, bound);
break;
default: {
i64 end = pit_dump(rt, buf, sizeof(buf) - 1, f, true);
@@ -104,33 +117,40 @@ static bool vm_call(pit_runtime *rt, pit_value f, pit_value args) {
return true;
}
-static void vm_erase_empty(pit_runtime *rt) {
+/* remove all empty frames atop the stack. if unbind is true, unbind all associated bindings */
+/* if unbind is false, return all the bindings that need to be unbound, in order */
+/* the intention is that if we're finishing a frame "normally", we can just unbind everything */
+/* if we're finishing a frame by pushing another frame that should run within this frame's context */
+/* (e.g. a tail call or other control flow), we can give that new frame responsibility for this frame's */
+/* bindings. this allows us to avoid growing the call stack while also ensuring that things are unbound */
+/* at the correct time. */
+static pit_value vm_erase_empty(pit_runtime *rt, bool unbind) {
pit_callstack_entry *ent = NULL;
+ pit_value ret = PIT_NIL;
+ if (rt->callstack->next < 1) return ret;
while ((ent = pit_vec_get(pit_callstack_entry)(rt->callstack, rt->callstack->next - 1))
&& ent->code == PIT_NIL) {
- pit_value bound = ent->bound;
- while (bound != PIT_NIL) { /* unbind everything we bound for the frame, in reverse */
- pit_symtab_unbind(rt, pit_value_cons_car(rt, bound));
- bound = pit_value_cons_cdr(rt, bound);
- }
- pit_vec_pop(pit_callstack_entry)(rt->callstack, NULL); /* pop the frame, and try again */
+ pit_value bound = ent->bound;
+ if (unbind) { /* we only unbind unconditionally when searching for the next instruction */
+ while (bound != PIT_NIL) { /* unbind everything we bound for the frame, in reverse */
+ pit_symtab_unbind(rt, pit_value_cons_car(rt, bound));
+ bound = pit_value_cons_cdr(rt, bound);
+ }
+ } else {
+ ret = pit_value_list_append(rt, bound, ret);
+ }
+ pit_vec_pop(pit_callstack_entry)(rt->callstack, NULL); /* pop the frame, and try again */
}
+ return ret;
}
/* run one instruction of the VM */
bool pit_vm_run_one(pit_runtime *rt) {
+ vm_erase_empty(rt, true);
if (rt->callstack->next < 1) return false;
- vm_erase_empty(rt);
pit_callstack_entry *ent = pit_vec_get(pit_callstack_entry)(rt->callstack, rt->callstack->next - 1);
if (ent == NULL) { pit_error(rt, "malformed call stack"); return false; }
- // for (i64 i = 0; i < rt->callstack->next; ++i) {
- // pit_callstack_entry *e = pit_vec_get(pit_callstack_entry)(rt->callstack, i);
- // fprintf(stderr, "frame: "); pit_dump_to_file(rt, stderr, e->code, false); fprintf(stderr, "\n");
- // }
pit_value ins = pit_value_cons_car(rt, ent->code);
- fprintf(stderr, "ins: "); pit_dump_to_file(rt, stderr, ins, false); fprintf(stderr, "\n");
- fprintf(stderr, "code: "); pit_dump_to_file(rt, stderr, ent->code, false); fprintf(stderr, "\n");
- // fprintf(stderr, "foo: "); pit_dump_to_file(rt, stderr, pit_symtab_get_function_cell(rt, pit_symtab_intern_cstr(rt, "foo")), false); fprintf(stderr, "\n");
if (ins == PIT_NIL) { pit_error(rt, "malformed vm instruction: %v %v", ins); return false; }
ent->code = pit_value_cons_cdr(rt, ent->code);
pit_value op = pit_value_cons_car(rt, ins);
@@ -160,42 +180,36 @@ bool pit_vm_run_one(pit_runtime *rt) {
pit_value c = vm_pop(rt);
pit_value t = vm_pop(rt);
pit_value e = vm_pop(rt);
- vm_erase_empty(rt);
- vm_push_code(rt, c != PIT_NIL ? t : e);
+ pit_value bindings = vm_erase_empty(rt, false);
+ vm_push_code(rt, c != PIT_NIL ? t : e, bindings);
} else if (pit_symtab_symbol_name_match_cstr(rt, op, "apply")) {
/* pop an arity n and a function, and then n arguments, and apply the function */
i64 arity = pit_value_as_integer(rt, pit_value_cons_car(rt, pit_value_cons_cdr(rt, ins)));
pit_value f = vm_pop(rt);
pit_value args = PIT_NIL;
while (arity-- > 0) args = pit_value_cons(rt, vm_pop(rt), args);
- vm_erase_empty(rt);
- if (!vm_call(rt, f, args)) return false;
+ pit_value bindings = vm_erase_empty(rt, false);
+ if (!vm_call(rt, f, args, bindings)) return false;
} else {
pit_error(rt, "unknown vm operation");
return false;
}
+ vm_erase_empty(rt, true);
return true;
}
/* run the VM until evaluation of this code finishes, returning the result */
pit_value pit_vm_eval(pit_runtime *rt, pit_value v) {
i64 start = rt->callstack->next;
- vm_push_code(rt, v);
- i64 gc = 0;
- while (pit_vm_run_one(rt) && rt->callstack->next > start) {
- gc += 1;
- if (gc > 100 && rt->expr_stack->next == 0 && rt->compilation_stack->next == 0) {
- gc = 0;
- pit_gc(rt); /* TODO hack to avoid running GC during macroexpansion */
- }
- }
+ vm_push_code(rt, v, PIT_NIL);
+ while (rt->callstack->next > start && pit_vm_run_one(rt)) pit_gc_if_necessary(rt);
return vm_pop(rt);
}
/* run the VM until this function call finishes, returning the result */
pit_value pit_vm_apply(pit_runtime *rt, pit_value f, pit_value args) {
i64 start = rt->callstack->next;
- vm_call(rt, f, args);
- while (pit_vm_run_one(rt) && rt->callstack->next > start);
+ vm_call(rt, f, args, PIT_NIL);
+ while (rt->callstack->next > start && pit_vm_run_one(rt)) pit_gc_if_necessary(rt);
return vm_pop(rt);
}
diff --git a/pit/src/runtime/gc.c b/pit/src/runtime/gc.c
index 119861a..7fd42fa 100644
--- a/pit/src/runtime/gc.c
+++ b/pit/src/runtime/gc.c
@@ -1,3 +1,4 @@
+#include <lcq/pit/arena.h>
#include <lcq/pit/runtime/gc.h>
static i64 gc_copy(pit_runtime *rt, pit_value_heavy *h) {
@@ -27,10 +28,8 @@ static pit_value gc_copy_value(pit_runtime *rt, pit_value v) {
return v;
}
}
-// #include <stdio.h>
+
void pit_gc(pit_runtime *rt) {
- return;
- // fprintf(stderr, "running gc: heap size is %ld\n", rt->heap->next);
rt->frozen_values = 0;
rt->frozen_symtab = 0;
pit_arena *fromspace = rt->heap;
@@ -114,5 +113,10 @@ void pit_gc(pit_runtime *rt) {
rt->annotations = tospace_ann;
rt->annotations_backbuffer = fromspace_ann;
pit_hashtable_reset(pit_ref, pit_annotation)(rt->annotations_backbuffer);
- // fprintf(stderr, "done! heap size is %ld\n", rt->heap->next);
+}
+
+void pit_gc_if_necessary(pit_runtime *rt) {
+ if (pit_arena_byte_idx(rt->heap, rt->heap->next * 5) > rt->heap->back * 4) {
+ pit_gc(rt);
+ }
}
diff --git a/pit/src/runtime/symtab.c b/pit/src/runtime/symtab.c
index 5684074..0f46fff 100644
--- a/pit/src/runtime/symtab.c
+++ b/pit/src/runtime/symtab.c
@@ -104,24 +104,26 @@ void pit_symtab_symbol_mark_special_form(pit_runtime *rt, pit_value sym) {
if (!ent) { pit_error(rt, "bad symbol"); return; }
ent->is_special_form = true;
}
-#include <stdio.h>
+void pit_symtab_replace(pit_runtime *rt, pit_value sym, pit_value cell) {
+ /* rebind a symbol without pushing the old binding to the stack */
+ /* this is used in e.g. tail calls, where the old bindings are no longer accessible */
+ pit_symtab_entry *ent = pit_symtab_lookup(rt, sym);
+ if (!ent) { pit_error(rt, "bad symbol"); return; }
+ ent->value = cell;
+}
void pit_symtab_bind(pit_runtime *rt, pit_value sym, pit_value cell) {
/* although we cannot set frozen symbols, we can still bind them temporarily - no need to check */
- fprintf(stderr, "binding "); pit_dump_to_file(rt, stderr, sym, false);
- fprintf(stderr, " to "); pit_dump_to_file(rt, stderr, cell, false);
- fprintf(stderr, "\n");
pit_symtab_entry *ent = pit_symtab_lookup(rt, sym);
if (!ent) { pit_error(rt, "bad symbol"); return; }
if (pit_vec_push(pit_value)(rt->saved_bindings, ent->value) < 0) pit_error(rt, "binding stack overflow");
ent->value = cell;
}
pit_value pit_symtab_unbind(pit_runtime *rt, pit_value sym) {
+ /* unbind a symbol! pops a cell from the saved binding stack and resets the symbol's value cell */
+ /* note that we must be careful to unbind symbols in the exact opposite order that we bind them */
pit_symtab_entry *ent = pit_symtab_lookup(rt, sym);
if (!ent) { pit_error(rt, "bad symbol"); return PIT_NIL; }
pit_value old = ent->value;
- fprintf(stderr, "unbinding "); pit_dump_to_file(rt, stderr, sym, false);
- fprintf(stderr, " (was "); pit_dump_to_file(rt, stderr, old, false);
- fprintf(stderr, ")\n");
if (pit_vec_pop(pit_value)(rt->saved_bindings, &ent->value) < 0) pit_error(rt, "binding stack underflow");
return old;
}
diff --git a/pit/src/runtime/value/cell.c b/pit/src/runtime/value/cell.c
index 2a99ce2..34b9226 100644
--- a/pit/src/runtime/value/cell.c
+++ b/pit/src/runtime/value/cell.c
@@ -11,13 +11,11 @@ pit_value pit_value_cell_new(pit_runtime *rt, pit_value v) {
h->in.cell = v;
return ret;
}
-#include <stdio.h>
pit_value pit_value_cell_get(pit_runtime *rt, pit_value cell, pit_value sym) {
if (pit_value_sort(cell) != PIT_VALUE_SORT_REF) {
char buf[256];
i64 end = pit_dump(rt, buf, sizeof(buf) - 1, sym, false);
buf[end] = 0;
- fprintf(stderr, "attempted to get unbound variable/function: %s\n", buf);
pit_error(rt, "attempted to get unbound variable/function: %s", buf);
return PIT_NIL;
}
diff --git a/pit/src/runtime/value/small.c b/pit/src/runtime/value/small.c
index f07e405..e0bdf0a 100644
--- a/pit/src/runtime/value/small.c
+++ b/pit/src/runtime/value/small.c
@@ -3,7 +3,7 @@
#ifndef PIT_NO_DOUBLE
double pit_value_as_double(pit_runtime *rt, pit_value v) {
if (pit_value_sort(v) != PIT_VALUE_SORT_DOUBLE) {
- pit_error(rt, "invalid use of value as double");
+ pit_error(rt, "invalid use of value %v as double", v);
return 0.0;
}
union { double dval; u64 ival; } x;
@@ -23,7 +23,7 @@ pit_value pit_value_double_new(pit_runtime *rt, double d) {
i64 pit_value_as_integer(pit_runtime *rt, pit_value v) {
if (pit_value_sort(v) != PIT_VALUE_SORT_INTEGER) {
- pit_error(rt, "invalid use of value as integer");
+ pit_error(rt, "invalid use of value %v as integer", v);
return -1;
}
u64 lo = pit_value_data(v);
@@ -44,7 +44,7 @@ pit_value pit_value_bool_new(pit_runtime *rt, bool i) {
pit_symbol pit_value_as_symbol(pit_runtime *rt, pit_value v) {
if (pit_value_sort(v) != PIT_VALUE_SORT_SYMBOL) {
- pit_error(rt, "invalid use of value as symbol");
+ pit_error(rt, "invalid use of value %v as symbol", v);
return -1;
}
return (pit_symbol) (pit_value_data(v) & 0xffffffff);
@@ -59,7 +59,7 @@ pit_value pit_value_symbol_new(pit_runtime *rt, pit_symbol s) {
pit_ref pit_value_as_ref(pit_runtime *rt, pit_value v) {
if (pit_value_sort(v) != PIT_VALUE_SORT_REF) {
- pit_error(rt, "invalid use of value as ref");
+ pit_error(rt, "invalid use of value %v as ref", v);
return -1;
}
return (pit_ref) (pit_value_data(v) & 0xffffffff);
diff --git a/pit/test/array.lisp b/pit/test/array.pit
index 976f70d..976f70d 100644
--- a/pit/test/array.lisp
+++ b/pit/test/array.pit
diff --git a/pit/test/broken.lisp b/pit/test/broken.pit
index 09f4afc..09f4afc 100644
--- a/pit/test/broken.lisp
+++ b/pit/test/broken.pit
diff --git a/pit/test/fold.lisp b/pit/test/fold.pit
index 89031d0..89031d0 100644
--- a/pit/test/fold.lisp
+++ b/pit/test/fold.pit
diff --git a/pit/test/nonbroken.lisp b/pit/test/nonbroken.pit
index 350f64f..350f64f 100644
--- a/pit/test/nonbroken.lisp
+++ b/pit/test/nonbroken.pit
diff --git a/pit/test/struct.lisp b/pit/test/struct.pit
index 9e35654..9e35654 100644
--- a/pit/test/struct.lisp
+++ b/pit/test/struct.pit
diff --git a/pit/test/test.lisp b/pit/test/test.pit
index ef13abb..ef13abb 100644
--- a/pit/test/test.lisp
+++ b/pit/test/test.pit
diff --git a/pit/test/test10.pit b/pit/test/test10.pit
new file mode 100644
index 0000000..0eea605
--- /dev/null
+++ b/pit/test/test10.pit
@@ -0,0 +1,5 @@
+(list/find
+ (lambda (y)
+ (and (eq? (list/len y) 3)
+ (list/all? (lambda (x) (equal? x 2)) y)))
+ '((1 2 3) (2 2 2 2) (2 3 4) (2 2 2))) \ No newline at end of file
diff --git a/pit/test/test11.pit b/pit/test/test11.pit
new file mode 100644
index 0000000..83d4816
--- /dev/null
+++ b/pit/test/test11.pit
@@ -0,0 +1,4 @@
+(print! 'here)
+(list/foldl '+ 0 '(1 2 3))
+(print! 'there)
+(print! (list/foldl '+ 0 '(1 2 3))) \ No newline at end of file
diff --git a/pit/test/test2.lisp b/pit/test/test2.pit
index 79a9791..79a9791 100644
--- a/pit/test/test2.lisp
+++ b/pit/test/test2.pit
diff --git a/pit/test/test3.lisp b/pit/test/test3.pit
index 2febb75..2febb75 100644
--- a/pit/test/test3.lisp
+++ b/pit/test/test3.pit
diff --git a/pit/test/test5.pit b/pit/test/test5.pit
index 3ea3fc7..2ad3675 100644
--- a/pit/test/test5.pit
+++ b/pit/test/test5.pit
@@ -1,5 +1,6 @@
(defun! foo (x)
- (print! x)
+ (if (equal? 0 (% x 10000))
+ (print! x))
(foo (+ x 1)))
(foo 0) \ No newline at end of file
diff --git a/pit/test/thebug.lisp b/pit/test/thebug.pit
index ad87bd7..ad87bd7 100644
--- a/pit/test/thebug.lisp
+++ b/pit/test/thebug.pit
diff --git a/pit/test/thebug2.lisp b/pit/test/thebug2.pit
index 2376ff8..2376ff8 100644
--- a/pit/test/thebug2.lisp
+++ b/pit/test/thebug2.pit
diff --git a/pit/test/y.lisp b/pit/test/y.pit
index 5e9218b..5e9218b 100644
--- a/pit/test/y.lisp
+++ b/pit/test/y.pit