From: cassowarii <2374677+cassowarii@users.noreply.github.com> Date: Sun, 19 Jul 2026 02:21:38 +0000 (-0700) Subject: vm/compiler changes for this (still doesn't work) X-Git-Url: https://git.cassowary.me/gitweb.cgi?a=commitdiff_plain;h=c51761c093dacd4178bef4709c94d136198c960d;p=sarabande.git vm/compiler changes for this (still doesn't work) --- diff --git a/src/compile/emit.c b/src/compile/emit.c index 37638ba..84b5377 100644 --- a/src/compile/emit.c +++ b/src/compile/emit.c @@ -176,8 +176,6 @@ void compile_stmt(sbVmCompiler *cm, sbIrStmt *stmt) { compile_expr(cm, stmt->assign.expr); if (stmt->assign.var->is_upvalue) { EMIT(BC_ST_UPVAL); - } else if (stmt->assign.var->closed_over) { - EMIT(BC_ST_IND); } else { EMIT(BC_ST_VAR); } @@ -289,11 +287,7 @@ void compile_bind_list(sbVmCompiler *cm, sbIrBindList *list) { * we don't actually check that it's a variable that the "..." is * attached to, and we may fail in weird cases like "...2". but we * need to restructure the BindList data structure. */ - if (elem->op.left->var->closed_over) { - EMIT(BC_ST_IND); - } else { - EMIT(BC_ST_VAR); - } + EMIT(BC_ST_VAR); EARG(elem->op.left->var->slot_id); if (list->pre_splat_count > 0) { /* put pre splat count back if we need it, to bind the rest of @@ -304,11 +298,7 @@ void compile_bind_list(sbVmCompiler *cm, sbIrBindList *list) { } else if (elem->type == IR_E_VAR) { /* normal sequence, no splat (so far): top thing goes in this * variable using ST_ARG */ - if (elem->var->closed_over) { - EMIT(BC_ST_ARG_IND); - } else { - EMIT(BC_ST_ARG); - } + EMIT(BC_ST_ARG); EARG(elem->var->slot_id); } else { PANIC("bind todo!"); @@ -344,8 +334,6 @@ void compile_expr(sbVmCompiler *cm, sbIrExpr *expr) { case IR_E_VAR: if (expr->var->is_upvalue) { EMIT(BC_LD_UPVAL); - } else if (expr->var->closed_over) { - EMIT(BC_LD_IND); } else { EMIT(BC_LD_VAR); } @@ -355,25 +343,13 @@ void compile_expr(sbVmCompiler *cm, sbIrExpr *expr) { if (expr->func.bound.size > 0) { BUFFER_ITER(expr->func.bound, sbIrVariable*, var) { if ((*var)->is_upvalue) { - /* the closure-generator expects a series of values - * of type reference to close over. BC_LD_UPVAL normally - * pushes whatever is *behind* the reference, which we - * don't want. UPREF will push the reference value - * itself from the closure so we can close over it - * a second time */ + /* BC_LD_UPREF: closed over variables are always on + * the heap, so all upval refs are rrefs */ EMIT(BC_LD_UPREF); } else if ((*var)->closed_over) { - /* note: BC_LD_REF here, not BC_LD_IND! this will push - * the pointer value, not the variable itself, because - * we want to put the pointer (well, the sbRef) inside - * the closure, not the value */ - /* BC_LD_REF is actually almost the same as BC_LD_VAR, - * except that if a variable hasn't been initialized - * it will create a new reference to nil. (this is - * necessary for mutually calling functions, who want to - * close over each other before all of them have been - * defined.) */ - EMIT(BC_LD_REF); + /* BC_LD_RREF: everything we are closing over from the + * current scope needs to move to the heap */ + EMIT(BC_LD_RREF); } else { PANIC("cannot have a direct variable in closure!"); } @@ -434,7 +410,7 @@ void compile_op(sbVmCompiler *cm, sbAstOp op) { case AST_OP_NOT: EMIT(BC_OP_NOT); break; case AST_OP_AND: EMIT(BC_OP_AND); break; case AST_OP_OR: EMIT(BC_OP_OR); break; - case AST_OP_INDEX: EMIT(BC_OP_INDEX); break; + case AST_OP_INDEX: EMIT(BC_OP_INDEXVAL); break; case AST_OP_RANGEINDEX: EMIT(BC_OP_RANGEINDEX); break; /* op range is currently only used in rangeindex; just pass them to it directly */ case AST_OP_RANGE: break; diff --git a/src/data/hashtable.c b/src/data/hashtable.c index 602ddf1..7d5fa49 100644 --- a/src/data/hashtable.c +++ b/src/data/hashtable.c @@ -89,16 +89,16 @@ void sbHash_insert(hHash h, hVal *key, hVal *value) { set_key(t, key, value); } -hVal sbHash_find_value(hHash h, hVal *key) { +hVal *sbHash_find_value(hHash h, hVal *key) { hashtbl *t = find_tbl_for_handle(h); usize index = find_index_by_key(t, key); hVal *keys; sbVar *values; get_ptrs_for_tbl(t, &keys, &values); if (keys[index].type == IT_NOTHING) { - return HVNOTHING; + return NULL; } else { - return sbVar_get_value(&values[index]); + return sbVar_get_value_ptr(&values[index]); } } diff --git a/src/data/hashtable.h b/src/data/hashtable.h index f60f3bc..4734018 100644 --- a/src/data/hashtable.h +++ b/src/data/hashtable.h @@ -16,7 +16,11 @@ sbHashValue sbHash_hash_obj(hVal *obj); hHash sbHash_create(usize initial_size); -hVal *sbHash_find(hHash h, hVal *key); +hVal *sbHash_find_value(hHash h, hVal *key); + +hVal sbHash_find_lvalue_ref(hHash h, hVal *key); + +hVal sbHash_find_rvalue_ref(hHash h, hVal *key); void sbHash_insert(hHash h, hVal *key, hVal *value); diff --git a/src/data/symbol.c b/src/data/symbol.c index 252ce2c..f54bfb4 100644 --- a/src/data/symbol.c +++ b/src/data/symbol.c @@ -18,7 +18,7 @@ hSymbol sbSymbol_from_bytes(const char *text, usize length) { .string = sbString_new(text, length), }; - hVal *result = sbHash_find(symbol_table, &symkey); + hVal *result = sbHash_find_value(symbol_table, &symkey); if (result == NULL) { /* add new symbol */ diff --git a/src/lib/method/hash.c b/src/lib/method/hash.c index 431cc09..42e8cd4 100644 --- a/src/lib/method/hash.c +++ b/src/lib/method/hash.c @@ -20,8 +20,8 @@ static void length(hVm vm, hVal *target, usize num_params) { static void get_index(hVm vm, hVal *target, usize num_params) { hVal *key = sbVm_pop(vm); - hVal *result = sbHash_find(target->hash, key); - if (result == IT_NOTHING) { + hVal *result = sbHash_find_value(target->hash, key); + if (result == NULL) { sbVm_push_immediate(vm, &HVNIL); } else { sbVm_push(vm, result); diff --git a/src/vm/bytecode.h b/src/vm/bytecode.h index 8bf019e..bff3a32 100644 --- a/src/vm/bytecode.h +++ b/src/vm/bytecode.h @@ -9,8 +9,8 @@ typedef enum sbOpcode { BC_LD_CONST, // push constants[index] to stack BC_LD_CTX, // look up key in context object and push result BC_LD_VAR, // push value onto stack from variable - BC_LD_LREF, // push lvalue reference onto stack from variable - BC_LD_RREF, // push rvalue reference onto stack from variable + BC_LD_LREF, // push lref to variable onto stack + BC_LD_RREF, // push rref to variable onto stack BC_LD_UPVAL, // push value onto stack from closure BC_LD_UPREF, // push pointer to closure value onto stack (to close over again) BC_LD_BLK, // push reference to function onto stack @@ -48,7 +48,9 @@ typedef enum sbOpcode { BC_OP_LE, // less than or equal to BC_OP_AND, // logical and BC_OP_OR, // logical or - BC_OP_INDEX, // index [] or :: + BC_OP_INDEXVAL, // a[...] + BC_OP_INDEXLREF, // a[...] = ... + BC_OP_INDEXRREF, // &a[...] BC_OP_RANGEINDEX, // index [a..b] BC_ALLOC_VARS, // create space in rstack for local variables BC_CLOSURE, // create closure from top elements of stack diff --git a/src/vm/exec.c b/src/vm/exec.c index 14df61f..c20ffd0 100644 --- a/src/vm/exec.c +++ b/src/vm/exec.c @@ -558,8 +558,8 @@ void execute_instruction(hVm vm) { v = peek_stack(vm, 0); sbV_decr(v); break; - case BC_OP_INDEX: - sbV_index(vm); + case BC_OP_INDEXVAL: + sbV_index_value(vm); break; case BC_OP_RANGEINDEX: v = peek_stack(vm, 2); diff --git a/src/vm/operations.h b/src/vm/operations.h index 3b1df1d..c8b9c00 100644 --- a/src/vm/operations.h +++ b/src/vm/operations.h @@ -24,7 +24,7 @@ hVal sbV_le(const hVal *a, const hVal *b); hVal sbV_append(hVal *a, hVal *b); -void sbV_index(hVm vm); +void sbV_index_value(hVm vm); hVal sbV_rangeindex(hVal *a, hVal *b, hVal *c);