|
@@ -416,6 +416,7 @@ typedef struct {
|
|
T_PLUSPLUS,
|
|
T_PLUSPLUS,
|
|
T_MINUSMINUS,
|
|
T_MINUSMINUS,
|
|
T_SLASHSLASH,
|
|
T_SLASHSLASH,
|
|
|
|
+ T_COLONASSIGN,
|
|
|
|
|
|
T_PLUS,
|
|
T_PLUS,
|
|
T_MINUS,
|
|
T_MINUS,
|
|
@@ -929,6 +930,8 @@ token_t *next_token(char *source, size_t *pos) {
|
|
return TK(LE);
|
|
return TK(LE);
|
|
else if (strncmp(&source[*pos], ">=", 2) == 0 && ++(*pos) && ++(*pos))
|
|
else if (strncmp(&source[*pos], ">=", 2) == 0 && ++(*pos) && ++(*pos))
|
|
return TK(GE);
|
|
return TK(GE);
|
|
|
|
+ else if (strncmp(&source[*pos], ":=", 2) == 0 && ++(*pos) && ++(*pos))
|
|
|
|
+ return TK(COLONASSIGN);
|
|
else if (source[*pos] == '(' && ++(*pos))
|
|
else if (source[*pos] == '(' && ++(*pos))
|
|
return TK(LPAR);
|
|
return TK(LPAR);
|
|
else if (source[*pos] == ')' && ++(*pos))
|
|
else if (source[*pos] == ')' && ++(*pos))
|
|
@@ -1067,6 +1070,7 @@ struct _node_t {
|
|
N_ASSIGN_XOR,
|
|
N_ASSIGN_XOR,
|
|
N_ASSIGN_SHL,
|
|
N_ASSIGN_SHL,
|
|
N_ASSIGN_SHR,
|
|
N_ASSIGN_SHR,
|
|
|
|
+ N_DECL,
|
|
|
|
|
|
N_EQUALS,
|
|
N_EQUALS,
|
|
N_NOTEQUALS,
|
|
N_NOTEQUALS,
|
|
@@ -2031,7 +2035,11 @@ node_t *parse_conditional(list_t *tokens, size_t *pos) {
|
|
node_t *parse_assignment(list_t *tokens, size_t *pos) {
|
|
node_t *parse_assignment(list_t *tokens, size_t *pos) {
|
|
node_t *a = parse_conditional(tokens, pos);
|
|
node_t *a = parse_conditional(tokens, pos);
|
|
|
|
|
|
- if (MATCH(ASSIGN)) {
|
|
|
|
|
|
+ if (MATCH(COLONASSIGN)) {
|
|
|
|
+ node_t *b = parse_assignment(tokens, pos);
|
|
|
|
+
|
|
|
|
+ return NODE2(DECL, a, b);
|
|
|
|
+ } else if (MATCH(ASSIGN)) {
|
|
node_t *b = parse_assignment(tokens, pos);
|
|
node_t *b = parse_assignment(tokens, pos);
|
|
|
|
|
|
return NODE2(ASSIGN, a, b);
|
|
return NODE2(ASSIGN, a, b);
|
|
@@ -2132,7 +2140,7 @@ node_t *parse_block(list_t *tokens, size_t *pos) {
|
|
: parse_stmt(tokens, pos))
|
|
: parse_stmt(tokens, pos))
|
|
|
|
|
|
node_t *parse_if(list_t *tokens, size_t *pos) {
|
|
node_t *parse_if(list_t *tokens, size_t *pos) {
|
|
- node_t *a = parse_expr(tokens, pos);
|
|
|
|
|
|
+ node_t *a = parse_comma_expr(tokens, pos);
|
|
node_t *b = BLOCK();
|
|
node_t *b = BLOCK();
|
|
node_t *c = NULL;
|
|
node_t *c = NULL;
|
|
|
|
|
|
@@ -3074,6 +3082,16 @@ node_t *parse(char *source) {
|
|
COMPILE_ERROR("illegal assignment left-hand side"); \
|
|
COMPILE_ERROR("illegal assignment left-hand side"); \
|
|
}
|
|
}
|
|
#define ASSIGN(lhs, rhs) ASSIGNIN(buf, lhs, rhs, false)
|
|
#define ASSIGN(lhs, rhs) ASSIGNIN(buf, lhs, rhs, false)
|
|
|
|
+#define DECLIN(buf, lhs, rhs) \
|
|
|
|
+ { \
|
|
|
|
+ if ((lhs)->tag == N_LITERAL && (lhs)->t->tag == T_NAME) { \
|
|
|
|
+ buffer_fmt(buf, "qi_decl_expr(state, \"%s\", ", (lhs)->t->text); \
|
|
|
|
+ rhs; \
|
|
|
|
+ buffer_fmt(buf, ")"); \
|
|
|
|
+ } else \
|
|
|
|
+ COMPILE_ERROR("illegal declaration left-hand side"); \
|
|
|
|
+ }
|
|
|
|
+#define DECL(lhs, rhs) DECLIN(buf, lhs, rhs)
|
|
#define COMPASSIGN(lhs, s, rhs) \
|
|
#define COMPASSIGN(lhs, s, rhs) \
|
|
{ \
|
|
{ \
|
|
ASSIGN(node->a, { \
|
|
ASSIGN(node->a, { \
|
|
@@ -4901,7 +4919,7 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
|
|
|
|
|
|
return node;
|
|
return node;
|
|
} else if ((node->tag >= N_ADD && node->tag <= N_BAND) ||
|
|
} else if ((node->tag >= N_ADD && node->tag <= N_BAND) ||
|
|
- (node->tag >= N_ASSIGN && node->tag <= N_ASSIGN_SHR)) {
|
|
|
|
|
|
+ (node->tag >= N_ASSIGN && node->tag <= N_ASSIGN_SHR) || node->tag == N_DECL) {
|
|
node = node_copy(node);
|
|
node = node_copy(node);
|
|
|
|
|
|
node->a = _expand_mvars(node->a, 1, err);
|
|
node->a = _expand_mvars(node->a, 1, err);
|
|
@@ -5445,6 +5463,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
EMIT("__%s%d(state)", PREFIX, gid);
|
|
EMIT("__%s%d(state)", PREFIX, gid);
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
+ case N_DECL:
|
|
case N_ASSIGN:
|
|
case N_ASSIGN:
|
|
if (node->a->tag == N_LIST) {
|
|
if (node->a->tag == N_LIST) {
|
|
if (node->a->l->length < 2)
|
|
if (node->a->l->length < 2)
|
|
@@ -5465,11 +5484,19 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
buffer_fmt(tbuf, ";\n");
|
|
buffer_fmt(tbuf, ";\n");
|
|
|
|
|
|
for (size_t i = 0; i < node->a->l->length; i++) {
|
|
for (size_t i = 0; i < node->a->l->length; i++) {
|
|
- ASSIGNIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
|
|
|
+ if (node->tag == N_DECL) {
|
|
|
|
+ DECLIN(tbuf, (node_t *)node->a->l->data[i],
|
|
buffer_fmt(tbuf,
|
|
buffer_fmt(tbuf,
|
|
"qi_index(state, %s, qi_make_number(state, %d))",
|
|
"qi_index(state, %s, qi_make_number(state, %d))",
|
|
- varname, i),
|
|
|
|
- false);
|
|
|
|
|
|
+ varname, i));
|
|
|
|
+ } else {
|
|
|
|
+ ASSIGNIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
|
+ buffer_fmt(tbuf,
|
|
|
|
+ "qi_index(state, %s, qi_make_number(state, %d))",
|
|
|
|
+ varname, i),
|
|
|
|
+ false);
|
|
|
|
+ }
|
|
|
|
+
|
|
buffer_fmt(tbuf, ";\n");
|
|
buffer_fmt(tbuf, ";\n");
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5510,8 +5537,14 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
for (size_t i = 0; i < node->a->l->length; i++) {
|
|
for (size_t i = 0; i < node->a->l->length; i++) {
|
|
char *varname = vals->data[i];
|
|
char *varname = vals->data[i];
|
|
|
|
|
|
- ASSIGNIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
|
- buffer_fmt(tbuf, "%s", varname), false);
|
|
|
|
|
|
+ if (node->tag == N_DECL) {
|
|
|
|
+ DECLIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
|
+ buffer_fmt(tbuf, "%s", varname));
|
|
|
|
+ } else {
|
|
|
|
+ ASSIGNIN(tbuf, (node_t *)node->a->l->data[i],
|
|
|
|
+ buffer_fmt(tbuf, "%s", varname), false);
|
|
|
|
+ }
|
|
|
|
+
|
|
buffer_fmt(tbuf, ";\n");
|
|
buffer_fmt(tbuf, ";\n");
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5524,8 +5557,11 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- ASSIGN(node->a,
|
|
|
|
- compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->b));
|
|
|
|
|
|
+ if (node->tag == N_DECL) {
|
|
|
|
+ DECL(node->a, compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->b));
|
|
|
|
+ } else {
|
|
|
|
+ ASSIGN(node->a, compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->b));
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
|
|
|
|
case N_ASSIGN_ADD:
|
|
case N_ASSIGN_ADD:
|