|
@@ -989,6 +989,8 @@ struct _node_t {
|
|
|
|
|
|
N_EXPRS_BEGIN,
|
|
|
|
|
|
+ N_COMMA,
|
|
|
+
|
|
|
N_NOT,
|
|
|
N_NEGATE,
|
|
|
N_UNARY_PLUS,
|
|
@@ -2036,6 +2038,23 @@ node_t *parse_expr(list_t *tokens, size_t *pos) {
|
|
|
return parse_assignment(tokens, pos);
|
|
|
}
|
|
|
|
|
|
+node_t *parse_comma_expr(list_t *tokens, size_t *pos) {
|
|
|
+ node_t *a = parse_expr(tokens, pos);
|
|
|
+
|
|
|
+ if (MATCH(COMMA)) {
|
|
|
+ list_t *exprs = list_new();
|
|
|
+ list_push(exprs, a);
|
|
|
+
|
|
|
+ do {
|
|
|
+ list_push(exprs, parse_expr(tokens, pos));
|
|
|
+ } while (MATCH(COMMA));
|
|
|
+
|
|
|
+ a = NODEL(COMMA, exprs);
|
|
|
+ }
|
|
|
+
|
|
|
+ return a;
|
|
|
+}
|
|
|
+
|
|
|
node_t *parse_block(list_t *tokens, size_t *pos) {
|
|
|
EXPECT(LCB, "{");
|
|
|
|
|
@@ -2398,11 +2417,20 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
|
|
|
|
|
|
a = parse_var(tokens, pos, 0);
|
|
|
EXPECT(SEMI, ";");
|
|
|
- b = parse_expr(tokens, pos);
|
|
|
- EXPECT(SEMI, ";");
|
|
|
- c = parse_expr(tokens, pos);
|
|
|
- } else
|
|
|
- a = parse_expr(tokens, pos);
|
|
|
+ b = parse_comma_expr(tokens, pos);
|
|
|
+
|
|
|
+ if (MATCH(SEMI))
|
|
|
+ c = parse_comma_expr(tokens, pos);
|
|
|
+ } else {
|
|
|
+ a = parse_comma_expr(tokens, pos);
|
|
|
+
|
|
|
+ if (MATCH(SEMI)) {
|
|
|
+ b = parse_comma_expr(tokens, pos);
|
|
|
+
|
|
|
+ if (MATCH(SEMI))
|
|
|
+ c = parse_comma_expr(tokens, pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
node_t *d = BLOCK();
|
|
@@ -2563,7 +2591,7 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
|
|
|
return NODET(INLINE, t);
|
|
|
}
|
|
|
|
|
|
- return NODE1(EXPRSTMT, parse_expr(tokens, pos));
|
|
|
+ return NODE1(EXPRSTMT, parse_comma_expr(tokens, pos));
|
|
|
}
|
|
|
|
|
|
#define ATM(t) \
|
|
@@ -4013,6 +4041,23 @@ node_t *mexpr_eval(node_t *n) {
|
|
|
return mexpr_eval(n->c);
|
|
|
}
|
|
|
|
|
|
+ case N_TUPLE: case N_LIST: {
|
|
|
+ list_t *l = list_new();
|
|
|
+
|
|
|
+ for (size_t i = 0; i < n->l->length; i++) {
|
|
|
+ node_t *a = mexpr_eval(n->l->data[i]);
|
|
|
+
|
|
|
+ if (!IS_EXPR(a)) return NULL;
|
|
|
+
|
|
|
+ list_push(l, a);
|
|
|
+ }
|
|
|
+
|
|
|
+ return nodel(n->tag, l);
|
|
|
+ }
|
|
|
+
|
|
|
+ case N_COMMA:
|
|
|
+ return mexpr_eval(list_index(n->l, -1));
|
|
|
+
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
@@ -4502,13 +4547,12 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
|
|
|
|
|
|
return node;
|
|
|
} else if (node->tag == N_PROGRAM || node->tag == N_BLOCK ||
|
|
|
- node->tag == N_LIST || node->tag == N_TUPLE) {
|
|
|
+ node->tag == N_LIST || node->tag == N_TUPLE || node->tag == N_COMMA) {
|
|
|
node = node_copy(node);
|
|
|
node->l = list_copy(node->l);
|
|
|
|
|
|
for (size_t i = 0; i < node->l->length; i++) {
|
|
|
- node_t *n = _expand_mvars(
|
|
|
- node->l->data[i], node->tag == N_LIST || node->tag == N_TUPLE, err);
|
|
|
+ node_t *n = _expand_mvars(node->l->data[i], 1, err);
|
|
|
if (err->code != 0)
|
|
|
return NULL;
|
|
|
|
|
@@ -4516,7 +4560,7 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
|
|
|
}
|
|
|
|
|
|
return node;
|
|
|
- } else if (node->tag == N_IF) {
|
|
|
+ } else if (node->tag == N_IF || node->tag == N_IFEXPR) {
|
|
|
node = node_copy(node);
|
|
|
|
|
|
node->a = _expand_mvars(node->a, 1, err);
|
|
@@ -4860,6 +4904,19 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
+ case N_COMMA:
|
|
|
+ EMIT("(");
|
|
|
+
|
|
|
+ for (size_t i = 0; i < node->l->length; i++) {
|
|
|
+ if (i != 0)
|
|
|
+ EMIT(", ");
|
|
|
+
|
|
|
+ compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l->data[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ EMIT(")");
|
|
|
+ break;
|
|
|
+
|
|
|
case N_LIST:
|
|
|
EMIT("qi_make_list(state, ");
|
|
|
compile_list(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l);
|
|
@@ -5278,7 +5335,12 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->a);
|
|
|
EMIT(")) {\n");
|
|
|
} else {
|
|
|
- compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->a);
|
|
|
+ node_t *a = node->a;
|
|
|
+ if (IS_EXPR(a))
|
|
|
+ a = node1(N_EXPRSTMT, a);
|
|
|
+
|
|
|
+ compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, a);
|
|
|
+
|
|
|
EMIT("while (_qi_truthy(state, ");
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->b);
|
|
|
EMIT(")) {\n");
|