diff options
| author | LLLL Colonq <llll@colonq> | 2026-09-06 17:40:51 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-09-06 17:40:51 -0400 |
| commit | 71bfa9094a4a25f762d681bb07f79f92a95dbb87 (patch) | |
| tree | 1b7ff31dad86e072a37e4270e762a5e0f12f87ac /pit/src/runtime/symtab.c | |
| parent | 843ea34efc2c5ea10edc4d534304f8287f97fbbc (diff) | |
pit: Fix evaluator bug
Diffstat (limited to 'pit/src/runtime/symtab.c')
| -rw-r--r-- | pit/src/runtime/symtab.c | 16 |
1 files changed, 9 insertions, 7 deletions
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; } |
