#include "data/reference.h"
#include "data/closure.h"
-#include "lib/methodtable.h"
+#include "lib/lib.h"
extern sbPool g_closure_pool;
#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();
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();
}
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) {
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;
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 {
-#include "lib/methodtable.h"
+#include "common.h"
+#include "lib/table.h"
#include "data/list.h"
#include "data/string.h"
#include "vm/exec.h"
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 */
}
void sbInteger_create_methods(void) {
- LIB_REGISTER(&g_integer_methods, "to_string", to_string);
+ REGISTER_METHOD(&g_integer_methods, "to_string", to_string);
}
-#include "lib/methodtable.h"
+#include "common.h"
+#include "lib/table.h"
#include "data/list.h"
#include "data/string.h"
#include "vm/exec.h"
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) {
}
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);
}
/* --- */
-#include "lib/methodtable.h"
+#include "common.h"
+#include "lib/table.h"
#include "data/list.h"
#include "data/string.h"
#include "vm/exec.h"
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 */
}
void sbString_create_methods(void) {
- LIB_REGISTER(&g_string_methods, "split", split);
+ REGISTER_METHOD(&g_string_methods, "split", split);
}
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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);
--- /dev/null
+#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;
+ }
+}
--- /dev/null
+#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);
#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);