add a couple more methods to lists
authorcassowarii <cassowary@cassowary.me>
Mon, 6 Jul 2026 20:29:21 +0000 (13:29 -0700)
committercassowarii <cassowary@cassowary.me>
Mon, 6 Jul 2026 20:29:21 +0000 (13:29 -0700)
src/compile/emit.c
src/compile/ir.c
src/compile/ir.h
src/compile/print_ir.c
src/data/list.c
src/data/methods.c
src/vm/exec.c
src/vm/exec.h
src/vm/operations.c

index d558711..7da4848 100644 (file)
@@ -208,7 +208,7 @@ void compile_list(sbVmCompiler *cm, sbIrExpr *expr) {
   sbIrExpr *considering = expr;
   usize count = 0;
   flag was_splat = FALSE;
-  while (considering) {
+  while (considering != IR_EMPTY_LIST) {
     sbIrExpr *elem = considering->list.this;
     if (elem->type == IR_E_OP && elem->op.type == AST_OP_SPLAT) {
       if (!was_splat) {
index fb20c2d..d30c345 100644 (file)
@@ -61,9 +61,11 @@ static sbIrExpr SENTINEL_NIL_EXPR = {
 };
 static sbIrStmt SENTINEL_NO_STMT = {0};
 static sbIrVariable SENTINEL_NO_VAR = {0};
+static sbIrExpr SENTINEL_EMPTY_LIST = { .type = IR_E_LIST };
 static sbIrExpr *NIL_EXPR = &SENTINEL_NIL_EXPR;
 static sbIrStmt *NO_STMT = &SENTINEL_NO_STMT;
 static sbIrVariable *NO_VAR = &SENTINEL_NO_VAR;
+sbIrExpr *IR_EMPTY_LIST = &SENTINEL_EMPTY_LIST;
 
 static void vprogram_error(hIrProgram ir, const char *error, va_list args) {
   ir->error_count ++;
@@ -365,6 +367,7 @@ static sbIrExpr *expr_list(hIrChunk ck, sbIrExpr *value) {
   return new_expr(ck, &(sbIrExpr) {
     .type = IR_E_LIST,
     .list.this = value,
+    .list.next = IR_EMPTY_LIST,
   });
 }
 
@@ -849,7 +852,7 @@ static sbIrVariable *compile_ast_var(hIrChunk ck, sbAst node) {
 
 static sbIrExpr *compile_ast_list(hIrChunk ck, sbAst node) {
   sbAst considering = node;
-  sbIrExpr *list = NULL;
+  sbIrExpr *list = IR_EMPTY_LIST;
   sbIrExpr **place_here = &list;
   while (considering != NO_NODE) {
     *place_here = expr_list(ck, compile_ast_expr(ck, considering->seq.left, TRUE));
index 99bb029..e044b20 100644 (file)
@@ -157,6 +157,8 @@ typedef struct sbIrProgram {
   i32 error_count;
 } sbIrProgram;
 
+extern sbIrExpr *IR_EMPTY_LIST;
+
 typedef struct sbIrProgram *hIrProgram;
 
 typedef struct sbIrChunk *hIrChunk;
index 9a86a62..a6102fa 100644 (file)
@@ -88,7 +88,9 @@ static void print_expr(sbIrExpr *e) {
       debug(" )");
       break;
     case IR_E_LIST:
-      print_expr(e->list.this);
+      if (e->list.this) {
+        print_expr(e->list.this);
+      }
       if (e->list.next) {
         debug(", ");
         print_expr(e->list.next);
index bebb5a2..1c7cb02 100644 (file)
@@ -26,6 +26,7 @@ void sbList_sys_deinit() {
 hList sbList_new(usize capacity) {
   usize index;
   sbList *l = sbPool_alloc(&g_list_pool, &index);
+  if (capacity < 4) capacity = 4;
   sbBuffer_initialize(&l->items, capacity * sizeof(hV));
   return index;
 }
index a8011f1..dbd57e4 100644 (file)
@@ -29,6 +29,24 @@ void sbList_method(hVm vm) {
       }
       sbVm_push_immediate(vm, list);
       sbVm_call_c_func(vm, list_each_cfunc);
+    } else {
+      if (METHOD_IS("length")) {
+        if (num_params != 0) {
+          PANIC("list#length takes no arguments!");
+        }
+        sbVm_pop(vm); /* remove method name */
+        usize length;
+        sbList_get_value(list->list, &length);
+        sbVm_push_immediate(vm, &HVINT(length));
+      } else if (METHOD_IS("push")) {
+        if (num_params != 1) {
+          PANIC("list#push expects 1 argument!");
+        }
+        hV *to_append = sbVm_pop(vm);
+        sbVm_pop(vm); /* remove method name */
+        sbList_append(list->list, to_append);
+        sbVm_push_immediate(vm, &HVNIL);
+      }
     }
   } else {
     PANIC("method name to list is not symbol! (%lld)", (long long)method_name_val->type);
index ee48f62..648ca74 100644 (file)
@@ -104,6 +104,10 @@ void sbVm_request_var_space(hVm vm, usize amount) {
   vm->fp->num_locals += amount;
 }
 
+void sbVm_print_stack(hVm vm) {
+  print_stack(vm);
+}
+
 /* --- */
 
 void print_stack(hVm vm) {
index 5e49dc3..dadcc37 100644 (file)
@@ -98,3 +98,5 @@ void sbVm_call_func(hVm vm, hV *func);
 void sbVm_call_c_func(hVm vm, sbRuntimeCFunc func);
 
 void sbVm_request_var_space(hVm vm, usize amount);
+
+void sbVm_print_stack(hVm vm);
index 5d7fde1..83c4765 100644 (file)
@@ -31,7 +31,7 @@ hV sbV_add(const hV *a, const hV *b) {
   if (a->type == IT_INTEGER && b->type == IT_INTEGER) {
     return sbV_int(sbInteger_sum(a->integer, b->integer));
   } else {
-    PANIC("todo (add type %llu and type %llu)", (long long)a->type, (long long)b->type);
+    PANIC("todo (add type %lld and type %lld)", (long long)a->type, (long long)b->type);
   }
 }