txlyre 2 天之前
父節點
當前提交
7904371451
共有 1 個文件被更改,包括 73 次插入11 次删除
  1. 73 11
      qic.c

+ 73 - 11
qic.c

@@ -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");