diff options
Diffstat (limited to 'uscript/parser.c')
| -rw-r--r-- | uscript/parser.c | 65 |
1 files changed, 55 insertions, 10 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 |
