|
@@ -1049,6 +1049,8 @@ struct _node_t {
|
|
|
|
|
|
N_INC,
|
|
|
N_DEC,
|
|
|
+ N_PINC,
|
|
|
+ N_PDEC,
|
|
|
|
|
|
N_IFEXPR,
|
|
|
N_FUNCEXPR,
|
|
@@ -1701,6 +1703,14 @@ node_t *parse_unary(list_t *tokens, size_t *pos) {
|
|
|
node_t *a = parse_unary(tokens, pos);
|
|
|
|
|
|
return NODE1(BNOT, a);
|
|
|
+ } else if (MATCH(PLUSPLUS)) {
|
|
|
+ node_t *a = parse_postfix(tokens, pos);
|
|
|
+
|
|
|
+ return NODE1(PINC, a);
|
|
|
+ } else if (MATCH(MINUSMINUS)) {
|
|
|
+ node_t *a = parse_postfix(tokens, pos);
|
|
|
+
|
|
|
+ return NODE1(PDEC, a);
|
|
|
}
|
|
|
|
|
|
return parse_postfix(tokens, pos);
|
|
@@ -2971,14 +2981,14 @@ node_t *parse(char *source) {
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->a); \
|
|
|
EMIT(")"); \
|
|
|
}
|
|
|
-#define ASSIGNIN(buf, lhs, rhs) \
|
|
|
+#define ASSIGNIN(buf, lhs, rhs, prefix) \
|
|
|
{ \
|
|
|
if ((lhs)->tag == N_LITERAL && (lhs)->t->tag == T_NAME) { \
|
|
|
- buffer_fmt(buf, "qi_set(state, false, \"%s\", ", (lhs)->t->text); \
|
|
|
+ buffer_fmt(buf, "qi_set(state, " #prefix ", \"%s\", ", (lhs)->t->text); \
|
|
|
rhs; \
|
|
|
buffer_fmt(buf, ")"); \
|
|
|
} else if ((lhs)->tag == N_INDEX) { \
|
|
|
- buffer_fmt(buf, "qi_index_set(state, false, "); \
|
|
|
+ buffer_fmt(buf, "qi_index_set(state, " #prefix ", "); \
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, (lhs)->a); \
|
|
|
buffer_fmt(buf, ", "); \
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, (lhs)->b); \
|
|
@@ -2986,7 +2996,7 @@ node_t *parse(char *source) {
|
|
|
rhs; \
|
|
|
buffer_fmt(buf, ")"); \
|
|
|
} else if ((lhs)->tag == N_MEMBER) { \
|
|
|
- buffer_fmt(buf, "qi_index_set(state, false, "); \
|
|
|
+ buffer_fmt(buf, "qi_index_set(state, " #prefix ", "); \
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, (lhs)->a); \
|
|
|
buffer_fmt(buf, ", qi_make_string(state, \"%s\"), ", (lhs)->t->text); \
|
|
|
rhs; \
|
|
@@ -2994,7 +3004,7 @@ node_t *parse(char *source) {
|
|
|
} else \
|
|
|
COMPILE_ERROR("illegal assignment left-hand side"); \
|
|
|
}
|
|
|
-#define ASSIGN(lhs, rhs) ASSIGNIN(buf, lhs, rhs)
|
|
|
+#define ASSIGN(lhs, rhs) ASSIGNIN(buf, lhs, rhs, false)
|
|
|
#define COMPASSIGN(lhs, s, rhs) \
|
|
|
{ \
|
|
|
ASSIGN(node->a, { \
|
|
@@ -3005,6 +3015,16 @@ node_t *parse(char *source) {
|
|
|
EMIT(")"); \
|
|
|
}); \
|
|
|
}
|
|
|
+#define COMPASSIGNP(lhs, s, rhs) \
|
|
|
+ { \
|
|
|
+ ASSIGNIN(buf, node->a, { \
|
|
|
+ EMIT("qi_%s(state, ", s); \
|
|
|
+ compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, (lhs)); \
|
|
|
+ EMIT(", "); \
|
|
|
+ rhs; \
|
|
|
+ EMIT(")"); \
|
|
|
+ }, true); \
|
|
|
+ }
|
|
|
#define COMPILE_ERROR(fmt, ...) \
|
|
|
{ \
|
|
|
format_error(GETFNAME(node->fi), GETSRC(node->fi), node->pos, fmt, \
|
|
@@ -4611,7 +4631,7 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
|
|
|
}
|
|
|
|
|
|
return node;
|
|
|
- } else if (node->tag == N_INC || node->tag == N_DEC) {
|
|
|
+ } else if (node->tag == N_INC || node->tag == N_DEC || node->tag == N_PINC || node->tag == N_PDEC) {
|
|
|
node = node_copy(node);
|
|
|
|
|
|
node->a = _expand_mvars(node->a, 1, err);
|
|
@@ -5086,7 +5106,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
|
ASSIGNIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
buffer_fmt(tbuf,
|
|
|
"qi_index(state, %s, qi_make_number(state, %d))",
|
|
|
- varname, i));
|
|
|
+ varname, i), falss);
|
|
|
buffer_fmt(tbuf, ";\n");
|
|
|
}
|
|
|
|
|
@@ -5128,7 +5148,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
|
char *varname = vals->data[i];
|
|
|
|
|
|
ASSIGNIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
- buffer_fmt(tbuf, "%s", varname));
|
|
|
+ buffer_fmt(tbuf, "%s", varname), false);
|
|
|
buffer_fmt(tbuf, ";\n");
|
|
|
}
|
|
|
|
|
@@ -5202,6 +5222,14 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
|
COMPASSIGN(node->a, "sub", EMIT("state->one"));
|
|
|
break;
|
|
|
|
|
|
+ case N_PINC:
|
|
|
+ COMPASSIGNP(node->a, "add", EMIT("state->one"));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case N_PDEC:
|
|
|
+ COMPASSIGNP(node->a, "sub", EMIT("state->one"));
|
|
|
+ break;
|
|
|
+
|
|
|
case N_VAR:
|
|
|
case N_LET:
|
|
|
table_iterate(node->h, {
|