From d3e896c593cac442bea3b137b345999b099c9269 Mon Sep 17 00:00:00 2001 From: cassowarii Date: Mon, 6 Jul 2026 13:29:21 -0700 Subject: [PATCH] add a couple more methods to lists --- src/compile/emit.c | 2 +- src/compile/ir.c | 5 ++++- src/compile/ir.h | 2 ++ src/compile/print_ir.c | 4 +++- src/data/list.c | 1 + src/data/methods.c | 18 ++++++++++++++++++ src/vm/exec.c | 4 ++++ src/vm/exec.h | 2 ++ src/vm/operations.c | 2 +- 9 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/compile/emit.c b/src/compile/emit.c index d558711..7da4848 100644 --- a/src/compile/emit.c +++ b/src/compile/emit.c @@ -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) { diff --git a/src/compile/ir.c b/src/compile/ir.c index fb20c2d..d30c345 100644 --- a/src/compile/ir.c +++ b/src/compile/ir.c @@ -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)); diff --git a/src/compile/ir.h b/src/compile/ir.h index 99bb029..e044b20 100644 --- a/src/compile/ir.h +++ b/src/compile/ir.h @@ -157,6 +157,8 @@ typedef struct sbIrProgram { i32 error_count; } sbIrProgram; +extern sbIrExpr *IR_EMPTY_LIST; + typedef struct sbIrProgram *hIrProgram; typedef struct sbIrChunk *hIrChunk; diff --git a/src/compile/print_ir.c b/src/compile/print_ir.c index 9a86a62..a6102fa 100644 --- a/src/compile/print_ir.c +++ b/src/compile/print_ir.c @@ -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); diff --git a/src/data/list.c b/src/data/list.c index bebb5a2..1c7cb02 100644 --- a/src/data/list.c +++ b/src/data/list.c @@ -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; } diff --git a/src/data/methods.c b/src/data/methods.c index a8011f1..dbd57e4 100644 --- a/src/data/methods.c +++ b/src/data/methods.c @@ -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); diff --git a/src/vm/exec.c b/src/vm/exec.c index ee48f62..648ca74 100644 --- a/src/vm/exec.c +++ b/src/vm/exec.c @@ -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) { diff --git a/src/vm/exec.h b/src/vm/exec.h index 5e49dc3..dadcc37 100644 --- a/src/vm/exec.h +++ b/src/vm/exec.h @@ -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); diff --git a/src/vm/operations.c b/src/vm/operations.c index 5d7fde1..83c4765 100644 --- a/src/vm/operations.c +++ b/src/vm/operations.c @@ -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); } } -- 1.8.3.1