From: cassowarii Date: Fri, 10 Jul 2026 18:41:10 +0000 (-0700) Subject: add concept of sentinel values for unique message names X-Git-Url: https://www.git.cassowary.me/gitweb.cgi?a=commitdiff_plain;h=60ee8825317e1ab323fa0a040532981daee7be9e;p=sarabande.git add concept of sentinel values for unique message names --- diff --git a/src/data/symbol.c b/src/data/symbol.c index 7c8c452..567cd17 100644 --- a/src/data/symbol.c +++ b/src/data/symbol.c @@ -44,6 +44,10 @@ hSymbol sbSymbol_from_string(hString str) { return sbSymbol_from_bytes(data, length); } +hSymbol sbSymbol_sentinel(const char *text, usize length) { + return new_symbol(text, length); +} + void sbSymbol_sys_init() { symbol_table = sbHash_create(256); sbArena_initialize(&symbol_text_arena, NAME_BLOCK_SIZE); diff --git a/src/data/symbol.h b/src/data/symbol.h index c341687..fa37149 100644 --- a/src/data/symbol.h +++ b/src/data/symbol.h @@ -2,6 +2,8 @@ #include "data/value.h" +#define SENTINEL(str) (sbSymbol_sentinel(str, sizeof(str)-1)) + void sbSymbol_sys_init(); void sbSymbol_sys_deinit(); @@ -9,4 +11,6 @@ hSymbol sbSymbol_from_string(hString str); hSymbol sbSymbol_from_bytes(const char *text, usize length); +hSymbol sbSymbol_sentinel(const char *text, usize length); + char *sbSymbol_name(hSymbol sym); diff --git a/src/lib/lib.c b/src/lib/lib.c index 9c919ec..b79a25e 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -3,10 +3,13 @@ #include "vm/exec.h" #include "lib/table.h" +#include "lib/sentinel.h" #include "lib/method.h" #include "lib/module.h" void sbLib_sys_init() { + sbLib_create_sentinels(); + sbLib_loadmodule_global(); sbList_create_methods(); diff --git a/src/lib/method/float.c b/src/lib/method/float.c index 9accacb..a7304cb 100644 --- a/src/lib/method/float.c +++ b/src/lib/method/float.c @@ -1,6 +1,7 @@ #include "common.h" #include "lib/table.h" +#include "lib/sentinel.h" #include "data/list.h" #include "data/string.h" #include "vm/exec.h" @@ -23,5 +24,5 @@ static void to_string(hVm vm, hV *target, usize num_params) { void sbFloat_create_methods(void) { sbLibTable_initialize(&g_float_methods, 16, TRUE); - REGISTER_METHOD(&g_float_methods, "to_string", to_string); + REGISTER_METHOD_SYM(&g_float_methods, S_OP_TO_STRING, to_string); } diff --git a/src/lib/method/integer.c b/src/lib/method/integer.c index bb9d9e1..6b94af7 100644 --- a/src/lib/method/integer.c +++ b/src/lib/method/integer.c @@ -1,6 +1,7 @@ #include "common.h" #include "lib/table.h" +#include "lib/sentinel.h" #include "data/list.h" #include "data/string.h" #include "data/integer.h" @@ -24,5 +25,5 @@ static void to_string(hVm vm, hV *target, usize num_params) { void sbInteger_create_methods(void) { sbLibTable_initialize(&g_integer_methods, 16, TRUE); - REGISTER_METHOD(&g_integer_methods, "to_string", to_string); + REGISTER_METHOD_SYM(&g_integer_methods, S_OP_TO_STRING, to_string); } diff --git a/src/lib/method/list.c b/src/lib/method/list.c index 839a87a..b9197a6 100644 --- a/src/lib/method/list.c +++ b/src/lib/method/list.c @@ -1,6 +1,7 @@ #include "common.h" #include "lib/table.h" +#include "lib/sentinel.h" #include "data/list.h" #include "data/string.h" #include "vm/exec.h" diff --git a/src/lib/method/string.c b/src/lib/method/string.c index 1e9e966..614156d 100644 --- a/src/lib/method/string.c +++ b/src/lib/method/string.c @@ -1,6 +1,7 @@ #include "common.h" #include "lib/table.h" +#include "lib/sentinel.h" #include "data/list.h" #include "data/string.h" #include "vm/exec.h" @@ -36,5 +37,5 @@ static void to_string(hVm vm, hV *target, usize num_params) { void sbString_create_methods(void) { sbLibTable_initialize(&g_string_methods, 16, TRUE); REGISTER_METHOD(&g_string_methods, "split", split); - REGISTER_METHOD(&g_string_methods, "to_string", to_string); + REGISTER_METHOD_SYM(&g_string_methods, S_OP_TO_STRING, to_string); } diff --git a/src/lib/module/global.c b/src/lib/module/global.c index a99645a..2b4f986 100644 --- a/src/lib/module/global.c +++ b/src/lib/module/global.c @@ -2,6 +2,7 @@ #include "lib/table.h" #include "lib/module.h" +#include "lib/sentinel.h" #include "data/list.h" #include "data/string.h" #include "data/symbol.h" @@ -12,6 +13,8 @@ sbCFuncStatus println_cfunc(hVm vm, flag init); sbLibTable g_global_module; +sbLibTable g_string_namespace; + extern sbLibTable g_math_module; static void print(hVm vm, usize argc) { @@ -29,6 +32,10 @@ void sbLib_loadmodule_global() { REGISTER_VALUE(&g_global_module, "print", &HVBUILTIN(print)); REGISTER_VALUE(&g_global_module, "println", &HVBUILTIN(println)); + sbLibTable_initialize(&g_string_namespace, 16, FALSE); + REGISTER_VALUE(&g_string_namespace, "convert", &HVSYM(S_OP_TO_STRING)); + REGISTER_VALUE(&g_global_module, "string", &HVMODULE(&g_string_namespace)); + sbLib_loadmodule_math(); REGISTER_VALUE(&g_global_module, "math", &HVMODULE(&g_math_module)); } @@ -45,7 +52,7 @@ sbCFuncStatus print_cfunc(hVm vm, flag init) { * thing that checks that it's really a string and throws if not, that we * can call from multiple places */ if (value->type != IT_STRING) { - PANIC("to_string needs to return a string"); + PANIC("string::convert needs to return a string"); } char scratch[8]; @@ -59,17 +66,15 @@ sbCFuncStatus print_cfunc(hVm vm, flag init) { } } - /* TODO: Built-in symbols like 'to_string' should be saved globally, so we don't have to do this - * hashing at runtime. */ if (args_left->integer > 0) { args_left->integer --; - sbVm_push_immediate(vm, args_left); /* ... param args_left */ - sbVm_swap(vm); /* ... args_left param */ - sbVm_push_immediate(vm, &HVSYM(sbSymbol_from_bytes("to_string", 9))); /* ... args_left param :to_string */ - sbVm_swap(vm); /* ... args_left :to_string param */ - sbVm_push_immediate(vm, &HVINT(1)); /* ... args_left :to_string param 1 */ - sbVm_swap(vm); /* ... args_left :to_string 1 param */ - sbLib_resolve_method(vm); /* call method */ + sbVm_push_immediate(vm, args_left); /* ... param args_left */ + sbVm_swap(vm); /* ... args_left param */ + sbVm_push_immediate(vm, &HVSYM(S_OP_TO_STRING)); /* ... args_left param string::convert*/ + sbVm_swap(vm); /* ... args_left string::convert param */ + sbVm_push_immediate(vm, &HVINT(1)); /* ... args_left string::convert param 1 */ + sbVm_swap(vm); /* ... args_left string::convert 1 param */ + sbLib_resolve_method(vm); /* call method */ return CFUNC_NEXT; } else { sbVm_push_immediate(vm, &HVNIL); diff --git a/src/lib/sentinel.c b/src/lib/sentinel.c new file mode 100644 index 0000000..dab8ba5 --- /dev/null +++ b/src/lib/sentinel.c @@ -0,0 +1,29 @@ +#include "lib/sentinel.h" + +#include "data/symbol.h" + +hSymbol S_OP_ADD, S_OP_SUB, S_OP_MUL, S_OP_DIV, S_OP_FLDIV, S_OP_MOD; +hSymbol S_OP_EQ, S_OP_LT, S_OP_LE; +hSymbol S_OP_CALL, S_OP_SET, S_OP_INDEX, S_OP_INDEX_SET; +hSymbol S_OP_TO_STRING, S_OP_TO_INT, S_OP_TO_FLOAT, S_OP_TO_LIST, S_OP_TO_HASH; + +void sbLib_create_sentinels() { + S_OP_ADD = SENTINEL(""); + S_OP_SUB = SENTINEL(""); + S_OP_MUL = SENTINEL(""); + S_OP_DIV = SENTINEL(""); + S_OP_FLDIV = SENTINEL(""); + S_OP_MOD = SENTINEL(""); + S_OP_EQ = SENTINEL(""); + S_OP_LT = SENTINEL(""); + S_OP_LE = SENTINEL(""); + S_OP_CALL = SENTINEL(""); + S_OP_SET = SENTINEL(""); + S_OP_INDEX = SENTINEL(""); + S_OP_INDEX_SET = SENTINEL(""); + S_OP_TO_STRING = SENTINEL(""); + S_OP_TO_INT = SENTINEL(""); + S_OP_TO_FLOAT = SENTINEL(""); + S_OP_TO_LIST = SENTINEL(""); + S_OP_TO_HASH = SENTINEL(""); +} diff --git a/src/lib/sentinel.h b/src/lib/sentinel.h new file mode 100644 index 0000000..fca6174 --- /dev/null +++ b/src/lib/sentinel.h @@ -0,0 +1,8 @@ +#include "common.h" + +extern hSymbol S_OP_ADD, S_OP_SUB, S_OP_MUL, S_OP_DIV, S_OP_FLDIV, S_OP_MOD; +extern hSymbol S_OP_EQ, S_OP_LT, S_OP_LE; +extern hSymbol S_OP_CALL, S_OP_SET, S_OP_INDEX, S_OP_INDEX_SET; +extern hSymbol S_OP_TO_STRING, S_OP_TO_INT, S_OP_TO_FLOAT, S_OP_TO_LIST, S_OP_TO_HASH; + +void sbLib_create_sentinels(); diff --git a/src/lib/table.c b/src/lib/table.c index dcca74e..f266116 100644 --- a/src/lib/table.c +++ b/src/lib/table.c @@ -80,26 +80,34 @@ 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_method_sym(hLibTable t, hSymbol key, 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); + insert_method(t->keys, t->methods, t->capacity, key, method); t->used ++; } -void sbLibTable_register_value(hLibTable t, const char *value_name, usize value_name_length, hV *value) { +void sbLibTable_register_method(hLibTable t, const char *method_name, usize method_name_length, sbLibMethod method) { + hSymbol sym = sbSymbol_from_bytes(method_name, method_name_length); + sbLibTable_register_method_sym(t, sym, method); +} + +void sbLibTable_register_value_sym(hLibTable t, hSymbol key, 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); + insert_value(t->keys, t->values, t->capacity, key, value); t->used ++; } +void sbLibTable_register_value(hLibTable t, const char *value_name, usize value_name_length, hV *value) { + hSymbol sym = sbSymbol_from_bytes(value_name, value_name_length); + sbLibTable_register_value_sym(t, sym, value); +} + /* --- */ static void insert_method(hSymbol *keys, sbLibMethod *methods, usize capacity, hSymbol key, sbLibMethod method) { diff --git a/src/lib/table.h b/src/lib/table.h index bde35ae..46cb685 100644 --- a/src/lib/table.h +++ b/src/lib/table.h @@ -1,7 +1,10 @@ #include "common.h" #define REGISTER_METHOD(t, n, m) (sbLibTable_register_method(t, n, sizeof(n) - 1, m)) +#define REGISTER_METHOD_SYM(t, s, m) (sbLibTable_register_method_sym(t, s, m)) + #define REGISTER_VALUE(t, n, v) (sbLibTable_register_value(t, n, sizeof(n) - 1, v)) +#define REGISTER_VALUE_SYM(t, s, v) (sbLibTable_register_value_sym(t, s, v)) typedef struct sbLibTable { usize used; @@ -26,4 +29,8 @@ 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_method_sym(hLibTable t, hSymbol key, sbLibMethod method); + void sbLibTable_register_value(hLibTable t, const char *value_name, usize value_name_length, hV *value); + +void sbLibTable_register_value_sym(hLibTable t, hSymbol key, hV *value);