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) {
};
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 ++;
return new_expr(ck, &(sbIrExpr) {
.type = IR_E_LIST,
.list.this = value,
+ .list.next = IR_EMPTY_LIST,
});
}
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));
i32 error_count;
} sbIrProgram;
+extern sbIrExpr *IR_EMPTY_LIST;
+
typedef struct sbIrProgram *hIrProgram;
typedef struct sbIrChunk *hIrChunk;
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);
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;
}
}
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);
vm->fp->num_locals += amount;
}
+void sbVm_print_stack(hVm vm) {
+ print_stack(vm);
+}
+
/* --- */
void print_stack(hVm vm) {
void sbVm_call_c_func(hVm vm, sbRuntimeCFunc func);
void sbVm_request_var_space(hVm vm, usize amount);
+
+void sbVm_print_stack(hVm vm);
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);
}
}