From: cassowarii <2374677+cassowarii@users.noreply.github.com> Date: Thu, 9 Jul 2026 17:50:38 +0000 (-0700) Subject: allow values also in lib tables (to add global modules) X-Git-Url: https://www.git.cassowary.me/gitweb.cgi?a=commitdiff_plain;h=149f53537393081cbd0c1f79285815a53c0cd907;p=sarabande.git allow values also in lib tables (to add global modules) --- diff --git a/src/data/data.c b/src/data/data.c index 936860b..f0c54a2 100644 --- a/src/data/data.c +++ b/src/data/data.c @@ -7,7 +7,7 @@ #include "data/reference.h" #include "data/closure.h" -#include "lib/methodtable.h" +#include "lib/lib.h" extern sbPool g_closure_pool; diff --git a/src/lib/lib.c b/src/lib/lib.c index 12c467b..d40252b 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -1,6 +1,6 @@ #include "common.h" -#include "lib/lib.h" -#include "lib/methodtable.h" +#include "lib/table.h" +#include "data/symbol.h" #include "vm/exec.h" extern void sbList_create_methods(); @@ -8,9 +8,9 @@ extern void sbString_create_methods(); extern void sbInteger_create_methods(); void sbLib_sys_init() { - sbMethodTable_initialize(&g_list_methods, 16); - sbMethodTable_initialize(&g_string_methods, 16); - sbMethodTable_initialize(&g_integer_methods, 16); + sbLibTable_initialize(&g_list_methods, 16, TRUE); + sbLibTable_initialize(&g_string_methods, 16, TRUE); + sbLibTable_initialize(&g_integer_methods, 16, TRUE); sbList_create_methods(); sbString_create_methods(); @@ -18,9 +18,9 @@ void sbLib_sys_init() { } void sbLib_sys_deinit() { - sbMethodTable_deinitialize(&g_list_methods); - sbMethodTable_deinitialize(&g_string_methods); - sbMethodTable_deinitialize(&g_integer_methods); + sbLibTable_deinitialize(&g_list_methods); + sbLibTable_deinitialize(&g_string_methods); + sbLibTable_deinitialize(&g_integer_methods); } void sbLib_resolve_method(hVm vm) { @@ -37,7 +37,7 @@ void sbLib_resolve_method(hVm vm) { PANIC("method name must be symbol!"); } - hMethodTable table_to_use = NULL; + hLibTable table_to_use = NULL; switch(target->type) { case IT_LIST: table_to_use = &g_list_methods; @@ -52,7 +52,7 @@ void sbLib_resolve_method(hVm vm) { PANIC("Have not implemented this method table yet!"); } - sbLibMethod f = sbMethodTable_find(table_to_use, method_name_val->symbol); + sbLibMethod f = sbLibTable_find_method(table_to_use, method_name_val->symbol); if (f) { f(vm, target, num_params); } else { diff --git a/src/lib/method/integer.c b/src/lib/method/integer.c index dbd3780..adeac1e 100644 --- a/src/lib/method/integer.c +++ b/src/lib/method/integer.c @@ -1,5 +1,6 @@ -#include "lib/methodtable.h" +#include "common.h" +#include "lib/table.h" #include "data/list.h" #include "data/string.h" #include "vm/exec.h" @@ -10,7 +11,7 @@ void list_filter_cfunc(hVm vm, flag init); void list_any_cfunc(hVm vm, flag init); void list_all_cfunc(hVm vm, flag init); -sbMethodTable g_integer_methods; +sbLibTable g_integer_methods; static void to_string(hVm vm, hV *target, usize num_params) { sbVm_pop(vm); /* remove method name */ @@ -28,5 +29,5 @@ static void to_string(hVm vm, hV *target, usize num_params) { } void sbInteger_create_methods(void) { - LIB_REGISTER(&g_integer_methods, "to_string", to_string); + REGISTER_METHOD(&g_integer_methods, "to_string", to_string); } diff --git a/src/lib/method/list.c b/src/lib/method/list.c index b3d9e45..f830f75 100644 --- a/src/lib/method/list.c +++ b/src/lib/method/list.c @@ -1,5 +1,6 @@ -#include "lib/methodtable.h" +#include "common.h" +#include "lib/table.h" #include "data/list.h" #include "data/string.h" #include "vm/exec.h" @@ -10,7 +11,7 @@ void list_filter_cfunc(hVm vm, flag init); void list_any_cfunc(hVm vm, flag init); void list_all_cfunc(hVm vm, flag init); -sbMethodTable g_list_methods; +sbLibTable g_list_methods; static void length(hVm vm, hV *list, usize num_params) { if (num_params != 0) { @@ -120,15 +121,15 @@ static void all_p(hVm vm, hV *list, usize num_params) { } void sbList_create_methods(void) { - LIB_REGISTER(&g_list_methods, "length", length); - LIB_REGISTER(&g_list_methods, "push", push); - LIB_REGISTER(&g_list_methods, "reverse", reverse); - LIB_REGISTER(&g_list_methods, "join", join); - LIB_REGISTER(&g_list_methods, "each", each); - LIB_REGISTER(&g_list_methods, "map", map); - LIB_REGISTER(&g_list_methods, "filter", filter); - LIB_REGISTER(&g_list_methods, "any?", any_p); - LIB_REGISTER(&g_list_methods, "all?", all_p); + REGISTER_METHOD(&g_list_methods, "length", length); + REGISTER_METHOD(&g_list_methods, "push", push); + REGISTER_METHOD(&g_list_methods, "reverse", reverse); + REGISTER_METHOD(&g_list_methods, "join", join); + REGISTER_METHOD(&g_list_methods, "each", each); + REGISTER_METHOD(&g_list_methods, "map", map); + REGISTER_METHOD(&g_list_methods, "filter", filter); + REGISTER_METHOD(&g_list_methods, "any?", any_p); + REGISTER_METHOD(&g_list_methods, "all?", all_p); } /* --- */ diff --git a/src/lib/method/string.c b/src/lib/method/string.c index 4a6d712..91beb69 100644 --- a/src/lib/method/string.c +++ b/src/lib/method/string.c @@ -1,5 +1,6 @@ -#include "lib/methodtable.h" +#include "common.h" +#include "lib/table.h" #include "data/list.h" #include "data/string.h" #include "vm/exec.h" @@ -10,7 +11,7 @@ void list_filter_cfunc(hVm vm, flag init); void list_any_cfunc(hVm vm, flag init); void list_all_cfunc(hVm vm, flag init); -sbMethodTable g_string_methods; +sbLibTable g_string_methods; static void split(hVm vm, hV *target, usize num_params) { sbVm_pop(vm); /* remove method name */ @@ -25,5 +26,5 @@ static void split(hVm vm, hV *target, usize num_params) { } void sbString_create_methods(void) { - LIB_REGISTER(&g_string_methods, "split", split); + REGISTER_METHOD(&g_string_methods, "split", split); } diff --git a/src/lib/methodtable.c b/src/lib/methodtable.c deleted file mode 100644 index aaab7f9..0000000 --- a/src/lib/methodtable.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "lib/methodtable.h" - -#include "data/hashtable.h" -#include "vm/exec.h" -#include "mem/debug.h" - -/* -typedef sbMethodTable { - usize used; - usize capacity; - hSymbol *keys; - sbLibMethod *funcs; -} sbMethodTable; -*/ - -static void insert_func(hSymbol *keys, sbLibMethod *funcs, usize capacity, hSymbol key, sbLibMethod func); - -void sbMethodTable_initialize(hMethodTable t, usize capacity) { - *t = (sbMethodTable) {0}; - if (capacity < 16) { - capacity = 16; - } - t->keys = calloc(capacity, sizeof(hSymbol)); - t->funcs = calloc(capacity, sizeof(sbLibMethod)); - t->capacity = capacity; -} - -void sbMethodTable_deinitialize(hMethodTable t) { - free(t->keys); - free(t->funcs); - *t = (sbMethodTable) {0}; -} - -sbLibMethod sbMethodTable_find(hMethodTable t, hSymbol key) { - sbHashValue hash = sbHash_hash_bytes((const char*)&key, sizeof(hSymbol)); - usize index = hash % t->capacity; - while (t->keys[index] && t->keys[index] != key) { - index ++; - index %= t->capacity; - } - - if (t->keys[index]) { - return t->funcs[index]; - } else { - return NULL; - } -} - -void sbMethodTable_register(hMethodTable t, const char *method_name, usize method_name_length, sbLibMethod behavior) { - if (t->used > t->capacity / 4 * 3) { - /* grow table and rehash */ - usize new_capacity = t->capacity * 2; - hSymbol *new_keys = calloc(new_capacity, sizeof(hSymbol)); - sbLibMethod *new_funcs = calloc(new_capacity, sizeof(sbLibMethod)); - - for (usize i = 0; i < t->capacity; i++) { - if (t->keys[i] != 0) { - insert_func(new_keys, new_funcs, new_capacity, t->keys[i], t->funcs[i]); - } - } - - free(t->keys); - free(t->funcs); - t->keys = new_keys; - t->funcs = new_funcs; - t->capacity = new_capacity; - } - - hSymbol sym = sbSymbol_from_bytes(method_name, method_name_length); - insert_func(t->keys, t->funcs, t->capacity, sym, behavior); - t->used ++; -} - -/* --- */ - -static void insert_func(hSymbol *keys, sbLibMethod *funcs, usize capacity, hSymbol key, sbLibMethod func) { - sbHashValue hash = sbHash_hash_bytes((const char*)&key, sizeof(hSymbol)); - usize index = hash % capacity; - - while (keys[index] != 0) { - index ++; - index %= capacity; - } - - keys[index] = key; - funcs[index] = func; -} diff --git a/src/lib/methodtable.h b/src/lib/methodtable.h deleted file mode 100644 index 5839664..0000000 --- a/src/lib/methodtable.h +++ /dev/null @@ -1,26 +0,0 @@ -#include "common.h" - -#include "data/symbol.h" - -#define LIB_REGISTER(t, n, b) (sbMethodTable_register(t, n, sizeof(n) - 1, b)) - -typedef struct sbMethodTable { - usize used; - usize capacity; - hSymbol *keys; - sbLibMethod *funcs; -} sbMethodTable; - -extern sbMethodTable g_list_methods; -extern sbMethodTable g_string_methods; -extern sbMethodTable g_integer_methods; - -typedef sbMethodTable *hMethodTable; - -void sbMethodTable_initialize(hMethodTable t, usize capacity); - -void sbMethodTable_deinitialize(hMethodTable t); - -sbLibMethod sbMethodTable_find(hMethodTable t, hSymbol key); - -void sbMethodTable_register(hMethodTable t, const char *method_name, usize method_name_length, sbLibMethod behavior); diff --git a/src/lib/table.c b/src/lib/table.c new file mode 100644 index 0000000..dcca74e --- /dev/null +++ b/src/lib/table.c @@ -0,0 +1,165 @@ +#include "lib/table.h" + +#include "data/hashtable.h" +#include "data/symbol.h" +#include "vm/exec.h" +#include "mem/debug.h" + +/* +typedef sbLibTable { + usize used; + usize capacity; + hSymbol *keys; + union { + sbLibMethod *methods; + hV *values; + }; +} sbLibTable; +*/ + +static void insert_method(hSymbol *keys, sbLibMethod *methods, usize capacity, hSymbol key, sbLibMethod method); +static void insert_value(hSymbol *keys, hV *values, usize capacity, hSymbol key, hV *value); +static void check_grow_table(hLibTable t); + +void sbLibTable_initialize(hLibTable t, usize capacity, flag method_table) { + *t = (sbLibTable) {0}; + if (capacity < 16) { + capacity = 16; + } + t->keys = calloc(capacity, sizeof(hSymbol)); + if (method_table) { + t->method_table = TRUE; + t->methods = calloc(capacity, sizeof(sbLibMethod)); + } else { + t->values = calloc(capacity, sizeof(hV)); + } + t->capacity = capacity; +} + +void sbLibTable_deinitialize(hLibTable t) { + free(t->keys); + if (t->method_table) { + free(t->methods); + } else { + free(t->values); + } + *t = (sbLibTable) {0}; +} + +sbLibMethod sbLibTable_find_method(hLibTable t, hSymbol key) { + if (!t->method_table) CHECK("cannot find method in non-method table"); + + sbHashValue hash = sbHash_hash_bytes((const char*)&key, sizeof(hSymbol)); + usize index = hash % t->capacity; + while (t->keys[index] && t->keys[index] != key) { + index ++; + index %= t->capacity; + } + + if (t->keys[index]) { + return t->methods[index]; + } else { + return NULL; + } +} + +hV *sbLibTable_find_value(hLibTable t, hSymbol key) { + if (t->method_table) CHECK("cannot find value in method table"); + + sbHashValue hash = sbHash_hash_bytes((const char*)&key, sizeof(hSymbol)); + usize index = hash % t->capacity; + while (t->keys[index] && t->keys[index] != key) { + index ++; + index %= t->capacity; + } + + if (t->keys[index]) { + return &t->values[index]; + } else { + return NULL; + } +} + +void sbLibTable_register_method(hLibTable t, const char *method_name, usize method_name_length, sbLibMethod method) { + if (!t->method_table) CHECK("cannot put method in non-method table"); + + check_grow_table(t); + + hSymbol sym = sbSymbol_from_bytes(method_name, method_name_length); + insert_method(t->keys, t->methods, t->capacity, sym, method); + t->used ++; +} + +void sbLibTable_register_value(hLibTable t, const char *value_name, usize value_name_length, hV *value) { + if (t->method_table) CHECK("cannot put value in method table"); + + check_grow_table(t); + + hSymbol sym = sbSymbol_from_bytes(value_name, value_name_length); + insert_value(t->keys, t->values, t->capacity, sym, value); + t->used ++; +} + +/* --- */ + +static void insert_method(hSymbol *keys, sbLibMethod *methods, usize capacity, hSymbol key, sbLibMethod method) { + sbHashValue hash = sbHash_hash_bytes((const char*)&key, sizeof(hSymbol)); + usize index = hash % capacity; + + while (keys[index] != 0) { + index ++; + index %= capacity; + } + + keys[index] = key; + methods[index] = method; +} + +static void insert_value(hSymbol *keys, hV *values, usize capacity, hSymbol key, hV *value) { + sbHashValue hash = sbHash_hash_bytes((const char*)&key, sizeof(hSymbol)); + usize index = hash % capacity; + + while (keys[index] != 0) { + index ++; + index %= capacity; + } + + keys[index] = key; + values[index] = *value; +} + +static void check_grow_table(hLibTable t) { + if (t->used > t->capacity / 4 * 3) { + /* grow table and rehash */ + usize new_capacity = t->capacity * 2; + hSymbol *new_keys = calloc(new_capacity, sizeof(hSymbol)); + + if (t->method_table) { + sbLibMethod *new_methods = calloc(new_capacity, sizeof(sbLibMethod)); + + for (usize i = 0; i < t->capacity; i++) { + if (t->keys[i] != 0) { + insert_method(new_keys, new_methods, new_capacity, t->keys[i], t->methods[i]); + } + } + + free(t->methods); + t->methods = new_methods; + } else { + hV *new_values = calloc(new_capacity, sizeof(hV)); + + for (usize i = 0; i < t->capacity; i++) { + if (t->keys[i] != 0) { + insert_value(new_keys, new_values, new_capacity, t->keys[i], &t->values[i]); + } + } + + free(t->values); + t->values = new_values; + } + + free(t->keys); + t->capacity = new_capacity; + t->keys = new_keys; + } +} diff --git a/src/lib/table.h b/src/lib/table.h new file mode 100644 index 0000000..2b73355 --- /dev/null +++ b/src/lib/table.h @@ -0,0 +1,33 @@ +#include "common.h" + +#define REGISTER_METHOD(t, n, m) (sbLibTable_register_method(t, n, sizeof(n) - 1, m)) +#define REGISTER_VALUE(t, n, v) (sbLibTable_register_value(t, n, sizeof(n) - 1, v)) + +typedef struct sbLibTable { + usize used; + usize capacity; + hSymbol *keys; + flag method_table; + union { + sbLibMethod *methods; + hV *values; + }; +} sbLibTable; + +typedef sbLibTable *hLibTable; + +extern sbLibTable g_list_methods; +extern sbLibTable g_string_methods; +extern sbLibTable g_integer_methods; + +void sbLibTable_initialize(hLibTable t, usize capacity, flag method_table); + +void sbLibTable_deinitialize(hLibTable t); + +sbLibMethod sbLibTable_find_method(hLibTable t, hSymbol key); + +hV *sbLibTable_find_value(hLibTable t, hSymbol key); + +void sbLibTable_register_method(hLibTable t, const char *method_name, usize method_name_length, sbLibMethod method); + +void sbLibTable_register_value(hLibTable t, const char *value_name, usize value_name_length, hV *value); diff --git a/src/vm/exec.c b/src/vm/exec.c index d56c182..7d5c54b 100644 --- a/src/vm/exec.c +++ b/src/vm/exec.c @@ -4,7 +4,7 @@ #include "data/list.h" #include "data/reference.h" #include "data/closure.h" -#include "lib/methodtable.h" +#include "lib/lib.h" void call_block(hVm vm, usize block_id, hClosure closure); void return_from_block(hVm vm);