diff options
| author | iamcheeseman <[email protected]> | 2026-04-07 10:46:07 -0400 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-04-07 10:46:07 -0400 |
| commit | 6d30c64216cd4d0b1b2a20a167d85c7fc6534378 (patch) | |
| tree | 67d0600f9be759c2c76b3e017b286354b57ab00a /uscript/vm.c | |
| parent | d39f7a08461b64c7378f007761d51208c226f4a4 (diff) | |
microscript: add arrays
Diffstat (limited to 'uscript/vm.c')
| -rw-r--r-- | uscript/vm.c | 62 |
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(); |
