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);
#include "data/value.h"
+#define SENTINEL(str) (sbSymbol_sentinel(str, sizeof(str)-1))
+
void sbSymbol_sys_init();
void sbSymbol_sys_deinit();
hSymbol sbSymbol_from_bytes(const char *text, usize length);
+hSymbol sbSymbol_sentinel(const char *text, usize length);
+
char *sbSymbol_name(hSymbol sym);
#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();
#include "common.h"
#include "lib/table.h"
+#include "lib/sentinel.h"
#include "data/list.h"
#include "data/string.h"
#include "vm/exec.h"
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);
}
#include "common.h"
#include "lib/table.h"
+#include "lib/sentinel.h"
#include "data/list.h"
#include "data/string.h"
#include "data/integer.h"
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);
}
#include "common.h"
#include "lib/table.h"
+#include "lib/sentinel.h"
#include "data/list.h"
#include "data/string.h"
#include "vm/exec.h"
#include "common.h"
#include "lib/table.h"
+#include "lib/sentinel.h"
#include "data/list.h"
#include "data/string.h"
#include "vm/exec.h"
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);
}
#include "lib/table.h"
#include "lib/module.h"
+#include "lib/sentinel.h"
#include "data/list.h"
#include "data/string.h"
#include "data/symbol.h"
sbLibTable g_global_module;
+sbLibTable g_string_namespace;
+
extern sbLibTable g_math_module;
static void print(hVm vm, usize argc) {
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));
}
* 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];
}
}
- /* 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);
--- /dev/null
+#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("<op::add>");
+ S_OP_SUB = SENTINEL("<op::sub>");
+ S_OP_MUL = SENTINEL("<op::mul>");
+ S_OP_DIV = SENTINEL("<op::div>");
+ S_OP_FLDIV = SENTINEL("<op::intdiv>");
+ S_OP_MOD = SENTINEL("<op::mod>");
+ S_OP_EQ = SENTINEL("<op::eq>");
+ S_OP_LT = SENTINEL("<op::lt>");
+ S_OP_LE = SENTINEL("<op::le>");
+ S_OP_CALL = SENTINEL("<op::call>");
+ S_OP_SET = SENTINEL("<op::set>");
+ S_OP_INDEX = SENTINEL("<op::index>");
+ S_OP_INDEX_SET = SENTINEL("<op::set_index>");
+ S_OP_TO_STRING = SENTINEL("<string::convert>");
+ S_OP_TO_INT = SENTINEL("<integer::convert>");
+ S_OP_TO_FLOAT = SENTINEL("<float::convert>");
+ S_OP_TO_LIST = SENTINEL("<list::convert>");
+ S_OP_TO_HASH = SENTINEL("<hash::convert>");
+}
--- /dev/null
+#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();
}
}
-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) {
#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;
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);