allow values also in lib tables (to add global modules)
authorcassowarii <2374677+cassowarii@users.noreply.github.com>
Thu, 9 Jul 2026 17:50:38 +0000 (10:50 -0700)
committercassowarii <2374677+cassowarii@users.noreply.github.com>
Thu, 9 Jul 2026 17:50:38 +0000 (10:50 -0700)
src/data/data.c
src/lib/lib.c
src/lib/method/integer.c
src/lib/method/list.c
src/lib/method/string.c
src/lib/methodtable.c [deleted file]
src/lib/methodtable.h [deleted file]
src/lib/table.c [new file with mode: 0644]
src/lib/table.h [new file with mode: 0644]
src/vm/exec.c

index 936860b..f0c54a2 100644 (file)
@@ -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;
 
index 12c467b..d40252b 100644 (file)
@@ -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 {
index dbd3780..adeac1e 100644 (file)
@@ -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);
 }
index b3d9e45..f830f75 100644 (file)
@@ -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);
 }
 
 /* --- */
index 4a6d712..91beb69 100644 (file)
@@ -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 (file)
index aaab7f9..0000000
+++ /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 (file)
index 5839664..0000000
+++ /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 (file)
index 0000000..dcca74e
--- /dev/null
@@ -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 (file)
index 0000000..2b73355
--- /dev/null
@@ -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);
index d56c182..7d5c54b 100644 (file)
@@ -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);