From: cassowarii <2374677+cassowarii@users.noreply.github.com> Date: Thu, 9 Jul 2026 16:44:53 +0000 (-0700) Subject: some general cleanup / restructuring of a bunch of method code X-Git-Url: https://www.git.cassowary.me/gitweb.cgi?a=commitdiff_plain;h=75d7e522c46fdc939a7dc88e15af6dad562b9426;p=sarabande.git some general cleanup / restructuring of a bunch of method code --- diff --git a/src/common.h b/src/common.h index 9855724..0eb9186 100644 --- a/src/common.h +++ b/src/common.h @@ -5,6 +5,7 @@ #include "mem/mem.h" #include "data/data.h" #include "vm/vm.h" +#include "lib/lib.h" #include // for memcpy/memset #endif diff --git a/src/data/data.c b/src/data/data.c index f274e2d..936860b 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/libtable.h" +#include "lib/methodtable.h" extern sbPool g_closure_pool; diff --git a/src/data/value.c b/src/data/value.c index 3563e1d..45298b5 100644 --- a/src/data/value.c +++ b/src/data/value.c @@ -52,13 +52,6 @@ hV sbV_int(hInteger i) { }; } -hV sbV_function(u64 id) { - return (hV) { - .type = IT_FUNCTION, - .data = id, - }; -} - hV sbV_empty_list(usize capacity) { return (hV) { .type = IT_LIST, diff --git a/src/data/value.h b/src/data/value.h index 46bfc03..236024e 100644 --- a/src/data/value.h +++ b/src/data/value.h @@ -1,7 +1,7 @@ #ifndef __SARABANDE_HANDLE_H__ #define __SARABANDE_HANDLE_H__ -#include "common.h" +#include "global.h" #define FLAG_SQUIGGLY (1ULL << 62) @@ -36,8 +36,8 @@ enum intrinsic_type { IT_REF = -8, // pointer \abc IT_LIST = -9, // list [1, 3, 5, 7] IT_HASH = -10, // hash {a: 1, b: 2} - IT_FUNCTION = -11, // function => a, b { a + b } - ITX_TOMBSTONE = -12, // + IT_BUILTIN = -12, // c function + ITX_TOMBSTONE = -13, // }; typedef struct hV { @@ -63,7 +63,6 @@ hV sbV_float(double fl); hV sbV_hash(hHash hash); hV sbV_int(hInteger i); hV sbV_boolean(flag b); -hV sbV_function(u64 id); hV sbV_empty_list(usize capacity); hV sbV_empty_hash(usize capacity); diff --git a/src/lib/lib.c b/src/lib/lib.c new file mode 100644 index 0000000..12c467b --- /dev/null +++ b/src/lib/lib.c @@ -0,0 +1,61 @@ +#include "common.h" +#include "lib/lib.h" +#include "lib/methodtable.h" +#include "vm/exec.h" + +extern void sbList_create_methods(); +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); + + sbList_create_methods(); + sbString_create_methods(); + sbInteger_create_methods(); +} + +void sbLib_sys_deinit() { + sbMethodTable_deinitialize(&g_list_methods); + sbMethodTable_deinitialize(&g_string_methods); + sbMethodTable_deinitialize(&g_integer_methods); +} + +void sbLib_resolve_method(hVm vm) { + hV *target = sbVm_pop(vm); + hV *argc = sbVm_pop(vm); + if (argc->type != IT_INTEGER) { + CHECK("argc of send should be integer!"); + } + /* subtract 1 because the method name is itself a param */ + usize num_params = argc->integer - 1; + hV *method_name_val = sbVm_peek(vm, num_params); + if (method_name_val->type != IT_SYMBOL) { + /* TODO this may become not true */ + PANIC("method name must be symbol!"); + } + + hMethodTable table_to_use = NULL; + switch(target->type) { + case IT_LIST: + table_to_use = &g_list_methods; + break; + case IT_STRING: + table_to_use = &g_string_methods; + break; + case IT_INTEGER: + table_to_use = &g_integer_methods; + break; + default: + PANIC("Have not implemented this method table yet!"); + } + + sbLibMethod f = sbMethodTable_find(table_to_use, method_name_val->symbol); + if (f) { + f(vm, target, num_params); + } else { + PANIC("invalid method name for type %lld: %s", (long long)target->type, sbSymbol_name(method_name_val->symbol)); + } +} diff --git a/src/lib/lib.h b/src/lib/lib.h new file mode 100644 index 0000000..15ffdba --- /dev/null +++ b/src/lib/lib.h @@ -0,0 +1,12 @@ +#ifndef __SARABANDE_LIB_H__ +#define __SARABANDE_LIB_H__ + +typedef void (*sbLibMethod)(hVm, hV*, usize); + +void sbLib_resolve_method(hVm vm); + +void sbLib_sys_init(); + +void sbLib_sys_deinit(); + +#endif diff --git a/src/lib/libtable.c b/src/lib/libtable.c deleted file mode 100644 index 94ab7e1..0000000 --- a/src/lib/libtable.c +++ /dev/null @@ -1,144 +0,0 @@ -#include "lib/libtable.h" - -#include "data/hashtable.h" -#include "vm/exec.h" -#include "mem/debug.h" - -/* -typedef sbLibTable { - usize used; - usize capacity; - hSymbol *keys; - sbLibFunc *funcs; -} sbLibTable; -*/ - -extern void sbList_create_methods(); -extern void sbString_create_methods(); -extern void sbInteger_create_methods(); - -static void insert_func(hSymbol *keys, sbLibFunc *funcs, usize capacity, hSymbol key, sbLibFunc func); - -void sbLibTable_initialize(hLibTable t, usize capacity) { - *t = (sbLibTable) {0}; - if (capacity < 16) { - capacity = 16; - } - t->keys = calloc(capacity, sizeof(hSymbol)); - t->funcs = calloc(capacity, sizeof(sbLibFunc)); - t->capacity = capacity; -} - -void sbLibTable_deinitialize(hLibTable t) { - free(t->keys); - free(t->funcs); - *t = (sbLibTable) {0}; -} - -void sbLib_sys_init() { - sbLibTable_initialize(&g_list_methods, 16); - sbLibTable_initialize(&g_string_methods, 16); - sbLibTable_initialize(&g_integer_methods, 16); - - sbList_create_methods(); - sbString_create_methods(); - sbInteger_create_methods(); -} - -void sbLib_sys_deinit() { - sbLibTable_deinitialize(&g_list_methods); - sbLibTable_deinitialize(&g_string_methods); - sbLibTable_deinitialize(&g_integer_methods); -} - -void sbLib_resolve_method(hVm vm) { - hV *target = sbVm_pop(vm); - hV *argc = sbVm_pop(vm); - if (argc->type != IT_INTEGER) { - CHECK("argc of send should be integer!"); - } - /* subtract 1 because the method name is itself a param */ - usize num_params = argc->integer - 1; - hV *method_name_val = sbVm_peek(vm, num_params); - if (method_name_val->type != IT_SYMBOL) { - /* TODO this may become not true */ - PANIC("method name must be symbol!"); - } - - hLibTable table_to_use = NULL; - switch(target->type) { - case IT_LIST: - table_to_use = &g_list_methods; - break; - case IT_STRING: - table_to_use = &g_string_methods; - break; - case IT_INTEGER: - table_to_use = &g_integer_methods; - break; - default: - PANIC("Have not implemented this method table yet!"); - } - - sbLibFunc f = sbLibTable_find(table_to_use, method_name_val->symbol); - if (f) { - f(vm, target, num_params); - } else { - PANIC("invalid method name for type %lld: %s", (long long)target->type, sbSymbol_name(method_name_val->symbol)); - } -} - -sbLibFunc sbLibTable_find(hLibTable 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 sbLibTable_register(hLibTable t, const char *method_name, usize method_name_length, sbLibFunc 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)); - sbLibFunc *new_funcs = calloc(new_capacity, sizeof(sbLibFunc)); - - 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, sbLibFunc *funcs, usize capacity, hSymbol key, sbLibFunc 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/libtable.h b/src/lib/libtable.h deleted file mode 100644 index 3f11410..0000000 --- a/src/lib/libtable.h +++ /dev/null @@ -1,36 +0,0 @@ -#include "common.h" - -#include "data/symbol.h" - -#define LIB_REGISTER(t, n, b) (sbLibTable_register(t, n, sizeof(n) - 1, b)) - -typedef void (*sbLibFunc)(hVm, hV*, usize); - -typedef struct sbLibTable { - usize used; - usize capacity; - hSymbol *keys; - sbLibFunc *funcs; -} sbLibTable; - -extern sbLibTable g_list_methods; -extern sbLibTable g_string_methods; -extern sbLibTable g_integer_methods; - -typedef sbLibTable *hLibTable; - -void sbLibTable_initialize(hLibTable t, usize capacity); - -void sbLibTable_deinitialize(hLibTable t); - -sbLibFunc sbLibTable_find(hLibTable t, hSymbol key); - -void sbLibTable_register(hLibTable t, const char *method_name, usize method_name_length, sbLibFunc behavior); - -void sbLib_resolve_method(hVm vm); - -void sbLib_sys_init(); - -void sbLib_sys_deinit(); - -void sbList_method(hVm vm); diff --git a/src/lib/integer.c b/src/lib/method/integer.c similarity index 93% rename from src/lib/integer.c rename to src/lib/method/integer.c index 76045b7..dbd3780 100644 --- a/src/lib/integer.c +++ b/src/lib/method/integer.c @@ -1,4 +1,4 @@ -#include "lib/libtable.h" +#include "lib/methodtable.h" #include "data/list.h" #include "data/string.h" @@ -10,7 +10,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); -sbLibTable g_integer_methods; +sbMethodTable g_integer_methods; static void to_string(hVm vm, hV *target, usize num_params) { sbVm_pop(vm); /* remove method name */ diff --git a/src/lib/list.c b/src/lib/method/list.c similarity index 99% rename from src/lib/list.c rename to src/lib/method/list.c index ba9ba38..b3d9e45 100644 --- a/src/lib/list.c +++ b/src/lib/method/list.c @@ -1,4 +1,4 @@ -#include "lib/libtable.h" +#include "lib/methodtable.h" #include "data/list.h" #include "data/string.h" @@ -10,7 +10,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); -sbLibTable g_list_methods; +sbMethodTable g_list_methods; static void length(hVm vm, hV *list, usize num_params) { if (num_params != 0) { diff --git a/src/lib/string.c b/src/lib/method/string.c similarity index 92% rename from src/lib/string.c rename to src/lib/method/string.c index e90c98f..4a6d712 100644 --- a/src/lib/string.c +++ b/src/lib/method/string.c @@ -1,4 +1,4 @@ -#include "lib/libtable.h" +#include "lib/methodtable.h" #include "data/list.h" #include "data/string.h" @@ -10,7 +10,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); -sbLibTable g_string_methods; +sbMethodTable g_string_methods; static void split(hVm vm, hV *target, usize num_params) { sbVm_pop(vm); /* remove method name */ diff --git a/src/lib/methodtable.c b/src/lib/methodtable.c new file mode 100644 index 0000000..aaab7f9 --- /dev/null +++ b/src/lib/methodtable.c @@ -0,0 +1,87 @@ +#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 new file mode 100644 index 0000000..5839664 --- /dev/null +++ b/src/lib/methodtable.h @@ -0,0 +1,26 @@ +#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/mem/cstrutil.c b/src/mem/cstrutil.c index 88d940d..f786690 100644 --- a/src/mem/cstrutil.c +++ b/src/mem/cstrutil.c @@ -1,20 +1,5 @@ #include "cstrutil.h" -usize sbstrncpy(char *dst, const char *src, usize limit) { - usize count = 0; - char ch = 0; - - do { - ch = dst[count] = src[count]; - count ++; - } while (ch && count < limit); - - count --; - if (dst[count] != 0) dst[count] = 0; - - return count; -} - int sbstrncmp(const char *a, const char *b, usize limit) { usize count = 0; diff --git a/src/mem/cstrutil.h b/src/mem/cstrutil.h index 5d6711b..176bf2b 100644 --- a/src/mem/cstrutil.h +++ b/src/mem/cstrutil.h @@ -1,5 +1,3 @@ #include "global.h" -usize sbstrncpy(char *dst, const char *src, usize limit); - int sbstrncmp(const char *a, const char *b, usize limit); diff --git a/src/vm/exec.c b/src/vm/exec.c index 34c49a4..d56c182 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/libtable.h" +#include "lib/methodtable.h" void call_block(hVm vm, usize block_id, hClosure closure); void return_from_block(hVm vm); @@ -433,12 +433,14 @@ void execute_instruction(hVm vm) { break; case BC_CALL: v = pop_stack(vm); - if (v->type <= 0) { + if (v->type == IT_BUILTIN) { + } else if (v->type <= 0) { /* We need to figure out exception support or some such. * User error should not panic. */ PANIC("attempt to call a non-function value"); + } else { + call_block(vm, v->type, v->closure); } - call_block(vm, v->type, v->closure); break; case BC_SEND: sbLib_resolve_method(vm);