diff options
| author | iamcheeseman <[email protected]> | 2026-04-14 21:15:38 -0400 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-04-14 21:15:38 -0400 |
| commit | 7752d0b775c4df0de6fec688107e904ad20e1de6 (patch) | |
| tree | 4255de168db8a527b7e99217021dd052bd2024e2 /uscript | |
| parent | a2ebe62cdbbe12e75e3b5c79de3dce9fbeb1ca20 (diff) | |
microengine: compound operators
Diffstat (limited to 'uscript')
| -rw-r--r-- | uscript/parser.c | 65 | ||||
| -rw-r--r-- | uscript/us_debug.c | 1 | ||||
| -rw-r--r-- | uscript/uscript.c | 6 | ||||
| -rw-r--r-- | uscript/vm.c | 14 | ||||
| -rw-r--r-- | uscript/vm.h | 2 | ||||
| -rw-r--r-- | uscript/xbytecode.h | 1 |
6 files changed, 71 insertions, 18 deletions
diff --git a/uscript/parser.c b/uscript/parser.c index 5740474..f2c601a 100644 --- a/uscript/parser.c +++ b/uscript/parser.c @@ -399,6 +399,18 @@ void parse_arr(struct parser *p) } static +void parser_add_var_access(struct parser *p, u8 acc, int var) +{ + parser_add_byte(p, acc); + if (acc == BC_SET_GLOBAL || acc == BC_GET_GLOBAL) { + parser_add_byte(p, (var >> 8) & 0xFF); + parser_add_byte(p, var & 0xFF); + } else { + parser_add_byte(p, (u8)var); + } +} + +static void parse_ident(struct parser *p) { struct token ident = p->prev; @@ -423,19 +435,31 @@ void parse_ident(struct parser *p) return; } +#define compound_op(op) \ + do { \ + parser_add_var_access(p, getter, var); \ + expr(p); \ + parser_add_byte(p, op); \ + parser_add_var_access(p, setter, var); \ + } while (false) + if (p->can_assign && consume(p, '=')) { expr(p); - parser_add_byte(p, setter); + parser_add_var_access(p, setter, var); + } else if (p->can_assign && consume(p, TOKEN_PLUS_EQL)) { + compound_op(BC_ADD); + } else if (p->can_assign && consume(p, TOKEN_MINUS_EQL)) { + compound_op(BC_SUB); + } else if (p->can_assign && consume(p, TOKEN_MULT_EQL)) { + compound_op(BC_MULT); + } else if (p->can_assign && consume(p, TOKEN_DIV_EQL)) { + compound_op(BC_DIV); + } else if (p->can_assign && consume(p, TOKEN_MOD_EQL)) { + compound_op(BC_MOD); } else { - parser_add_byte(p, getter); - } - - if (setter == BC_SET_GLOBAL) { - parser_add_byte(p, (var >> 8) & 0xFF); - parser_add_byte(p, var & 0xFF); - } else { - parser_add_byte(p, (u8)var); + parser_add_var_access(p, getter, var); } +#undef compound_op } static @@ -503,15 +527,36 @@ void parse_call(struct parser *p) static void parse_index(struct parser *p) { + bool can_assign = p->can_assign; + expr(p); expect(p, ']', "expected ']'"); - if (consume(p, '=')) { +#define compound_op(op) \ + do { \ + parser_add_byte(p, BC_PUSH_INDEX); \ + expr(p); \ + parser_add_byte(p, op); \ + parser_add_byte(p, BC_SET_INDEX); \ + } while (false) + + if (can_assign && consume(p, '=')) { expr(p); parser_add_byte(p, BC_SET_INDEX); + } else if (can_assign && consume(p, TOKEN_PLUS_EQL)) { + compound_op(BC_ADD); + } else if (can_assign && consume(p, TOKEN_MINUS_EQL)) { + compound_op(BC_SUB); + } else if (can_assign && consume(p, TOKEN_MULT_EQL)) { + compound_op(BC_MULT); + } else if (can_assign && consume(p, TOKEN_DIV_EQL)) { + compound_op(BC_DIV); + } else if (can_assign && consume(p, TOKEN_MOD_EQL)) { + compound_op(BC_MOD); } else { parser_add_byte(p, BC_GET_INDEX); } +#undef compound_op } static diff --git a/uscript/us_debug.c b/uscript/us_debug.c index 18be587..8898211 100644 --- a/uscript/us_debug.c +++ b/uscript/us_debug.c @@ -80,6 +80,7 @@ int print_instruction(struct us_proto *proto, int idx) case BC_FALSE: case BC_TRUE: case BC_ZILCH: + case BC_PUSH_INDEX: case BC_GET_INDEX: case BC_SET_INDEX: case BC_POP: diff --git a/uscript/uscript.c b/uscript/uscript.c index 0e6fc4b..d82ce35 100644 --- a/uscript/uscript.c +++ b/uscript/uscript.c @@ -12,7 +12,7 @@ void core_print(int argc) { (void)argc; - char *str = val_to_str(vm_peek(), NULL); + char *str = val_to_str(vm_peek(0), NULL); olog(str); mem_free(str); @@ -23,7 +23,7 @@ void core_len(int argc) { (void)argc; - struct us_val val = vm_peek(); + struct us_val val = vm_peek(0); switch (val.type) { case VAL_ARR: vm_push(create_num(da_len(get_arr(val)->e))); @@ -43,6 +43,7 @@ void core_range_next(int argc) struct us_cfunc *cfunc = get_cfunc(vm_get(-1)); double min = get_num(cfunc_get_upval(cfunc, 0)); double max = get_num(cfunc_get_upval(cfunc, 1)); + double inc = get_num(cfunc_get_upval(cfunc, 2)); if (min == max) { vm_push(create_zilch()); @@ -51,7 +52,6 @@ void core_range_next(int argc) vm_push(create_num(min)); - int inc = max > min ? 1 : -1; cfunc_set_upval(cfunc, 0, create_num(min + inc)); } diff --git a/uscript/vm.c b/uscript/vm.c index 4064e12..9fbd8c0 100644 --- a/uscript/vm.c +++ b/uscript/vm.c @@ -245,20 +245,26 @@ void us_exec(struct us_func *func) vm_push(vm.cf->stackbot[read_byte()]); break; case BC_SET_LOCAL: - vm.cf->stackbot[read_byte()] = vm_peek(); + vm.cf->stackbot[read_byte()] = vm_peek(0); break; case BC_GET_GLOBAL: vm_push(get_global(read_short())); break; case BC_SET_GLOBAL: - set_global(read_short(), vm_peek()); + set_global(read_short(), vm_peek(0)); break; case BC_GET_UPVAL: vm_push(*func->upvals[read_byte()]->loc); break; case BC_SET_UPVAL: - *func->upvals[read_byte()]->loc = vm_peek(); + *func->upvals[read_byte()]->loc = vm_peek(0); break; + case BC_PUSH_INDEX: { + struct us_val idx_val = vm_peek(0); + struct us_val idxee_val = vm_peek(1); + index_val(idx_val, idxee_val); + break; + } case BC_GET_INDEX: { struct us_val idx_val = vm_pop(); struct us_val idxee_val = vm_pop(); @@ -403,7 +409,7 @@ void us_exec(struct us_func *func) } case BC_FALSEY_JMP: { u16 jmp = read_short(); - if (as_bool(vm_peek())) + if (as_bool(vm_peek(0))) break; i += jmp; break; diff --git a/uscript/vm.h b/uscript/vm.h index 9ab1407..a20aa61 100644 --- a/uscript/vm.h +++ b/uscript/vm.h @@ -8,7 +8,7 @@ #define STACK_SIZE (MAX_CALL_FRAMES * 256) #define vm_pop() (*(--vm.stacktop)) -#define vm_peek() (vm.stacktop[-1]) +#define vm_peek(i) (vm.stacktop[-1 - i]) #define vm_push(v) (*vm.stacktop++ = (v)) #define vm_get(i) (vm.cf->stackbot[i]) diff --git a/uscript/xbytecode.h b/uscript/xbytecode.h index 34f7f43..1a7f359 100644 --- a/uscript/xbytecode.h +++ b/uscript/xbytecode.h @@ -11,6 +11,7 @@ BC(GET_GLOBAL) BC(SET_GLOBAL) BC(GET_UPVAL) BC(SET_UPVAL) +BC(PUSH_INDEX) BC(GET_INDEX) BC(SET_INDEX) BC(POP) |
