diff options
| author | LLLL Colonq <llll@colonq> | 2026-06-30 14:30:19 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-06-30 14:30:19 -0400 |
| commit | 1c028e3a2250a56eface56ebbb1835d77e4e2579 (patch) | |
| tree | 98ea5da9d75e87f44bb3eb2e153810a6a820f9b6 /src/runtime/symtab.c | |
| parent | 1d4447bcd888dd0bd20cf4b6dd7f9192145debf0 (diff) | |
Diffstat (limited to 'src/runtime/symtab.c')
| -rw-r--r-- | src/runtime/symtab.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/runtime/symtab.c b/src/runtime/symtab.c new file mode 100644 index 0000000..d2bc51e --- /dev/null +++ b/src/runtime/symtab.c @@ -0,0 +1,118 @@ +#include <lcq/pit/runtime/symtab.h> + +pit_symtab_entry *pit_symtab_lookup(pit_runtime *rt, pit_value sym) { + pit_symbol s = pit_value_as_symbol(rt, sym); + return pit_vec_get(pit_symtab_entry)(rt->symtab, s); +} +pit_value pit_symtab_intern(pit_runtime *rt, u8 *nm, i64 len) { + if (rt->error != PIT_NIL) return PIT_NIL; + for (i64 sidx = 0; sidx < rt->symtab->next; ++sidx) { + pit_symtab_entry *sent = pit_vec_get(pit_symtab_entry)(rt->symtab, sidx); + if (sent == NULL) { pit_error(rt, "corrupted symbol table"); return PIT_NIL; } + if (pit_value_bytes_match(rt, sent->name, nm, len)) return pit_value_symbol_new(rt, sidx); + } + pit_symtab_entry ent; + ent.name = pit_value_bytes_new(rt, nm, len); + ent.value = PIT_NIL; + ent.function = PIT_NIL; + ent.is_macro = false; + ent.is_special_form = false; + ent.is_keyword = len >= 1 && nm[0] == ':'; + i64 idx = pit_vec_push(pit_symtab_entry)(rt->symtab, ent); + if (idx < 0) { pit_error(rt, "failed to allocate symtab entry"); return PIT_NIL; } + return pit_value_symbol_new(rt, idx); +} +pit_value pit_symtab_intern_cstr(pit_runtime *rt, char *nm) { + return pit_symtab_intern(rt, (u8 *) nm, (i64) pit_libc_string_strlen(nm)); +} +pit_value pit_symtab_symbol_name(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return PIT_NIL; } + return ent->name; +} +bool pit_symtab_symbol_name_match(pit_runtime *rt, pit_value sym, u8 *buf, i64 len) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return PIT_NIL; } + return pit_value_bytes_match(rt, ent->name, buf, len); +} +bool pit_symtab_symbol_name_match_cstr(pit_runtime *rt, pit_value sym, char *s) { + return pit_symtab_symbol_name_match(rt, sym, (u8 *) s, (i64) pit_libc_string_strlen(s)); +} +pit_value pit_symtab_get_value_cell(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return PIT_NIL; } + return ent->value; +} +pit_value pit_symtab_get_function_cell(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return PIT_NIL; } + return ent->function; +} +pit_value pit_symtab_get(pit_runtime *rt, pit_value sym) { + return pit_value_cell_get(rt, pit_symtab_get_value_cell(rt, sym), sym); +} +void pit_symtab_set(pit_runtime *rt, pit_value sym, pit_value v) { + pit_symbol idx = pit_value_as_symbol(rt, sym); + if (idx < rt->frozen_symtab) { pit_error(rt, "attempted to modify frozen symbol"); return; } + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return; } + if (pit_value_sort(ent->value) != PIT_VALUE_SORT_REF) { + ent->value = pit_value_cell_new(rt, PIT_NIL); + } + pit_value_cell_set(rt, ent->value, v, sym); +} +pit_value pit_symtab_fget(pit_runtime *rt, pit_value sym) { + return pit_value_cell_get(rt, pit_symtab_get_function_cell(rt, sym), sym); +} +void pit_symtab_fset(pit_runtime *rt, pit_value sym, pit_value v) { + pit_symbol idx = pit_value_as_symbol(rt, sym); + if (idx < rt->frozen_symtab) { pit_error(rt, "attempted to modify frozen symbol"); return; } + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return; } + if (pit_value_sort(ent->function) != PIT_VALUE_SORT_REF) { + ent->function = pit_value_cell_new(rt, PIT_NIL); + } + pit_value_cell_set(rt, ent->function, v, sym); +} +bool pit_symtab_is_symbol_macro(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return false; } + return ent->is_macro; +} +void pit_symtab_symbol_mark_macro(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return; } + ent->is_macro = true; +} +void pit_symtab_mset(pit_runtime *rt, pit_value sym, pit_value v) { + pit_symtab_fset(rt, sym, v); + pit_symtab_symbol_mark_macro(rt, sym); +} +bool pit_symtab_is_symbol_special_form(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return false; } + return ent->is_special_form; +} +void pit_symtab_symbol_mark_special_form(pit_runtime *rt, pit_value sym) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return; } + ent->is_special_form = true; +} +void pit_symtab_sfset(pit_runtime *rt, pit_value sym, pit_value v) { + pit_symtab_fset(rt, sym, v); + pit_symtab_symbol_mark_special_form(rt, sym); +} +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 */ + 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) { + pit_symtab_entry *ent = pit_symtab_lookup(rt, sym); + if (!ent) { pit_error(rt, "bad symbol"); return PIT_NIL; } + pit_value old = ent->value; + if (pit_vec_pop(pit_value)(rt->saved_bindings, &ent->value) < 0) pit_error(rt, "binding stack underflow"); + return old; +} |
