summaryrefslogtreecommitdiff
path: root/uscript/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'uscript/parser.c')
-rw-r--r--uscript/parser.c65
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