From 7752d0b775c4df0de6fec688107e904ad20e1de6 Mon Sep 17 00:00:00 2001 From: iamcheeseman Date: Tue, 14 Apr 2026 21:15:38 -0400 Subject: microengine: compound operators --- uscript/parser.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'uscript/parser.c') diff --git a/uscript/parser.c b/uscript/parser.c index 5740474..f2c601a 100644 --- a/uscript/parser.c +++ b/uscript/parser.c @@ -398,6 +398,18 @@ void parse_arr(struct parser *p) parser_add_byte(p, (u8)arr_len); } +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) { @@ -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 -- cgit v1.3-2-g0d8e