summaryrefslogtreecommitdiff
path: root/uscript/vm.c
diff options
context:
space:
mode:
authoriamcheeseman <[email protected]>2026-04-07 10:46:07 -0400
committeriamcheeseman <[email protected]>2026-04-07 10:46:07 -0400
commit6d30c64216cd4d0b1b2a20a167d85c7fc6534378 (patch)
tree67d0600f9be759c2c76b3e017b286354b57ab00a /uscript/vm.c
parentd39f7a08461b64c7378f007761d51208c226f4a4 (diff)
microscript: add arrays
Diffstat (limited to 'uscript/vm.c')
-rw-r--r--uscript/vm.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/uscript/vm.c b/uscript/vm.c
index f9f1fe6..7a617dd 100644
--- a/uscript/vm.c
+++ b/uscript/vm.c
@@ -132,6 +132,22 @@ void us_exec(struct us_func *func)
case BC_FALSE: vm_push(create_bool(false)); break;
case BC_TRUE: vm_push(create_bool(true)); break;
case BC_ZILCH: vm_push(create_zilch()); break;
+ case BC_ARR: {
+ struct us_arr *arr = create_arr();
+ u8 arr_len = read_byte();
+ // elements are in reverse order, so we add them in the
+ // correct order, and pop them all off at the end
+ for (u8 i = 0; i < arr_len; i++) {
+ da_append(
+ struct us_val,
+ &arr->e,
+ *(vm.stacktop - arr_len + i)
+ );
+ }
+ vm.stacktop -= arr_len;
+ vm_push(wrap_arr(arr));
+ break;
+ }
case BC_SET_LOCAL:
vm.cf->stackbot[read_byte()] = vm_peek();
break;
@@ -144,6 +160,52 @@ void us_exec(struct us_func *func)
case BC_SET_UPVAL:
*func->upvals[read_byte()]->loc = vm_peek();
break;
+ case BC_SET_INDEX: {
+ struct us_val set_val = vm_pop();
+ struct us_val idx_val = vm_pop();
+ struct us_val arr_val = vm_pop();
+ if (idx_val.type != VAL_NUM)
+ log_fatal(1, "index type must be number");
+ if (arr_val.type != VAL_ARR)
+ log_fatal(1, "only arrays can be indexed");
+ int idx = (int)get_num(idx_val);
+ struct us_arr *arr = get_arr(arr_val);
+ if (idx < 0)
+ idx += da_len(arr->e);
+ if (idx < 0 || idx >= da_len(arr->e)) {
+ log_fatal(
+ 1,
+ "index out of range (%d/%d)",
+ idx,
+ da_len(arr->e) - 1
+ );
+ }
+ arr->e[idx] = set_val;
+ vm_push(set_val);
+ break;
+ }
+ case BC_GET_INDEX: {
+ struct us_val idx_val = vm_pop();
+ struct us_val arr_val = vm_pop();
+ if (idx_val.type != VAL_NUM)
+ log_fatal(1, "index type must be number");
+ if (arr_val.type != VAL_ARR)
+ log_fatal(1, "only arrays can be indexed");
+ int idx = (int)get_num(idx_val);
+ struct us_arr *arr = get_arr(arr_val);
+ if (idx < 0)
+ idx += da_len(arr->e);
+ if (idx < 0 || idx >= da_len(arr->e)) {
+ log_fatal(
+ 1,
+ "index out of range (%d/%d)",
+ idx,
+ da_len(arr->e) - 1
+ );
+ }
+ vm_push(arr->e[idx]);
+ break;
+ }
case BC_POP_UPVAL:
close_upvals(vm.stacktop - 1);
vm_pop();