txlyre 7 цаг өмнө
parent
commit
d9a64ebbc9
1 өөрчлөгдсөн 46 нэмэгдсэн , 10 устгасан
  1. 46 10
      qic.c

+ 46 - 10
qic.c

@@ -416,6 +416,7 @@ typedef struct {
     T_PLUSPLUS,
     T_MINUSMINUS,
     T_SLASHSLASH,
+    T_COLONASSIGN,
 
     T_PLUS,
     T_MINUS,
@@ -929,6 +930,8 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(LE);
   else if (strncmp(&source[*pos], ">=", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(GE);
+  else if (strncmp(&source[*pos], ":=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(COLONASSIGN);
   else if (source[*pos] == '(' && ++(*pos))
     return TK(LPAR);
   else if (source[*pos] == ')' && ++(*pos))
@@ -1067,6 +1070,7 @@ struct _node_t {
     N_ASSIGN_XOR,
     N_ASSIGN_SHL,
     N_ASSIGN_SHR,
+    N_DECL,
 
     N_EQUALS,
     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 *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);
 
     return NODE2(ASSIGN, a, b);
@@ -2132,7 +2140,7 @@ node_t *parse_block(list_t *tokens, size_t *pos) {
                 : parse_stmt(tokens, 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 *c = NULL;
 
@@ -3074,6 +3082,16 @@ node_t *parse(char *source) {
       COMPILE_ERROR("illegal assignment left-hand side");                      \
   }
 #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)                                                \
   {                                                                            \
     ASSIGN(node->a, {                                                          \
@@ -4901,7 +4919,7 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
 
     return node;
   } 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->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);
   } break;
 
+  case N_DECL:
   case N_ASSIGN:
     if (node->a->tag == N_LIST) {
       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");
 
       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,
                             "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");
       }
 
@@ -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++) {
         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");
       }
 
@@ -5524,8 +5557,11 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
       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;
 
   case N_ASSIGN_ADD: