some general cleanup / restructuring of a bunch of method code
authorcassowarii <2374677+cassowarii@users.noreply.github.com>
Thu, 9 Jul 2026 16:44:53 +0000 (09:44 -0700)
committercassowarii <2374677+cassowarii@users.noreply.github.com>
Thu, 9 Jul 2026 16:44:53 +0000 (09:44 -0700)
16 files changed:
src/common.h
src/data/data.c
src/data/value.c
src/data/value.h
src/lib/lib.c [new file with mode: 0644]
src/lib/lib.h [new file with mode: 0644]
src/lib/libtable.c [deleted file]
src/lib/libtable.h [deleted file]
src/lib/method/integer.c [moved from src/lib/integer.c with 93% similarity]
src/lib/method/list.c [moved from src/lib/list.c with 99% similarity]
src/lib/method/string.c [moved from src/lib/string.c with 92% similarity]
src/lib/methodtable.c [new file with mode: 0644]
src/lib/methodtable.h [new file with mode: 0644]
src/mem/cstrutil.c
src/mem/cstrutil.h
src/vm/exec.c

index 9855724..0eb9186 100644 (file)
@@ -5,6 +5,7 @@
 #include "mem/mem.h"
 #include "data/data.h"
 #include "vm/vm.h"
+#include "lib/lib.h"
 #include <string.h> // for memcpy/memset
 
 #endif
index f274e2d..936860b 100644 (file)
@@ -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;
 
index 3563e1d..45298b5 100644 (file)
@@ -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,
index 46bfc03..236024e 100644 (file)
@@ -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, // <hashtable_tombstone>
+  IT_BUILTIN = -12,    // c function
+  ITX_TOMBSTONE = -13, // <hashtable_tombstone>
 };
 
 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 (file)
index 0000000..12c467b
--- /dev/null
@@ -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 (file)
index 0000000..15ffdba
--- /dev/null
@@ -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 (file)
index 94ab7e1..0000000
+++ /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 (file)
index 3f11410..0000000
+++ /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);
similarity index 93%
rename from src/lib/integer.c
rename to src/lib/method/integer.c
index 76045b7..dbd3780 100644 (file)
@@ -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 */
similarity index 99%
rename from src/lib/list.c
rename to src/lib/method/list.c
index ba9ba38..b3d9e45 100644 (file)
@@ -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) {
similarity index 92%
rename from src/lib/string.c
rename to src/lib/method/string.c
index e90c98f..4a6d712 100644 (file)
@@ -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 (file)
index 0000000..aaab7f9
--- /dev/null
@@ -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 (file)
index 0000000..5839664
--- /dev/null
@@ -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);
index 88d940d..f786690 100644 (file)
@@ -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;
 
index 5d6711b..176bf2b 100644 (file)
@@ -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);
index 34c49a4..d56c182 100644 (file)
@@ -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);