txlyre 1 dag geleden
bovenliggende
commit
ecc17b6590
1 gewijzigde bestanden met toevoegingen van 122 en 10 verwijderingen
  1. 122 10
      qic.c

+ 122 - 10
qic.c

@@ -1035,6 +1035,7 @@ struct _node_t {
     N_LITERAL,
     N_LIST,
     N_LISTGEN,
+    N_TABLEGEN,
     N_TUPLE,
     N_NILTUPLE,
     N_TABLE,
@@ -1570,29 +1571,64 @@ node_t *parse_primary(list_t *tokens, size_t *pos) {
 
     return NODEL(LIST, a);
   } else if (MATCH(LCB)) {
-    table_t *table = table_new();
+    list_t *pairs = list_new();
 
     do {
       if (AT(RCB))
         break;
 
-      if (!AT(NAME) && !AT(STRING))
-        PARSE_ERROR("expected identifier or string");
-
-      int is_str = AT(STRING);
-
-      char *key = ((token_t *)tokens->data[(*pos)++])->text;
+      node_t *key = parse_expr(tokens, pos);
 
       EXPECT(COLON, ":");
 
       node_t *val = parse_expr(tokens, pos);
 
-      table_set(table, is_str ? unescape(key) : key, val);
+      list_t *pair = list_new();
+      list_push(pair, key);
+      list_push(pair, val);
+
+      list_push(pairs, pair);
     } while (MATCH(COMMA));
 
+    node_t *loop = NULL;
+    node_t *cond = NULL;
+
+    if (MATCH(FOR)) {
+      if (MATCH(LSB)) {
+        list_t *l = list_new();
+
+        do {
+          if (!AT(NAME))
+            PARSE_ERROR("expected identifier");
+
+          list_push(l, ((token_t *)tokens->data[(*pos)++])->text);
+        } while (MATCH(COMMA));
+
+        EXPECT(RSB, "]");
+        EXPECT(OF, "of");
+
+        loop = NODE2l(FOROFUNPACK, parse_expr(tokens, pos), NODEL(LIST, pairs), l);
+      } else {
+        if (!AT(NAME))
+          PARSE_ERROR("expected identifier");
+
+        token_t *t = tokens->data[(*pos)++];
+
+        EXPECT(OF, "of");
+
+        loop = NODE2t(FOROF, parse_expr(tokens, pos), NODEL(LIST, pairs), t);
+      }
+
+      if (MATCH(IF))
+        cond = parse_expr(tokens, pos);
+    }
+
     EXPECT(RCB, "}");
 
-    return NODEH(TABLE, table);
+    if (loop)
+      return NODE2(TABLEGEN, loop, cond);
+
+    return NODEL(TABLE, pairs);
   } else if (MATCH(NUMBER) || MATCH(STRING) || MATCH(FSTRING) ||
              MATCH(USTRING) || MATCH(NAME) || MATCH(TRUE) || MATCH(FALSE) ||
              MATCH(NIL))
@@ -3238,6 +3274,40 @@ void compile_table(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
   EMIT("__%s%d(state)", PREFIX, gid);
 }
 
+void compile_pairs(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
+                   list_t *lstk, list_t *sstk, list_t *lbl, list_t *pairs) {
+  if (!pairs || pairs->length < 1) {
+    EMIT("NULL");
+
+    return;
+  }
+
+  buffer_t *tbuf = buffer_new();
+
+  NEWGID();
+
+  buffer_fmt(tbuf, "inline static qi_table_t *__%s%d(qi_state_t *state) {\n",
+             PREFIX, gid);
+  buffer_fmt(tbuf, "qi_table_t *table = qi_table_make();\n");
+
+  for (size_t i = 0; i < pairs->length; i++) {
+    list_t *pair = pairs->data[i];
+
+    buffer_fmt(tbuf, "qi_table_set(table, qi_to_string(state, ");   
+    compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, pair->data[0]);
+    buffer_fmt(tbuf, ")->value.string, ");
+    compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, pair->data[1]);
+    buffer_fmt(tbuf, ");\n");
+  }
+
+  buffer_fmt(tbuf, "return table;\n");
+  buffer_fmt(tbuf, "}\n");
+
+  buffer_appendb(gbuf, tbuf);
+
+  EMIT("__%s%d(state)", PREFIX, gid);
+}
+
 #define CTXPUSH(s) list_push(ctx, (s))
 #define CTXPOP() list_pop(ctx)
 
@@ -5369,6 +5439,48 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
     EMIT("__%s%d(state)", PREFIX, gid);
   } break;
 
+  case N_TABLEGEN: {
+    NEWGID();
+
+    buffer_t *tbuf = buffer_new();
+
+    buffer_fmt(tbuf, "inline static qi_value_t *__%s%d(qi_state_t *state) {\n",
+               PREFIX, gid);
+    buffer_fmt(tbuf, "qi_table_t *table = qi_table_make();\n");
+
+    buffer_t *bbuf = buffer_new();
+
+    if (node->b) {
+      buffer_fmt(bbuf, "if (_qi_truthy(state, ");
+      compile_node(gbuf, bbuf, ctx, ltab, lstk, sstk, lbl, node->b);
+      buffer_fmt(bbuf, ")) {\n");
+    }
+
+    for (size_t i = 0; i < node->a->b->l->length; i++) {
+      list_t *pair = node->a->b->l->data[i];
+
+      buffer_fmt(bbuf, "qi_table_set(table, qi_to_string(state, ");   
+      compile_node(gbuf, bbuf, ctx, ltab, lstk, sstk, lbl, pair->data[0]);
+      buffer_fmt(bbuf, ")->value.string, ");
+      compile_node(gbuf, bbuf, ctx, ltab, lstk, sstk, lbl, pair->data[1]);
+      buffer_fmt(bbuf, ");\n");
+    }
+
+    if (node->b)
+      buffer_fmt(bbuf, "}\n");
+
+    node->a->b = nodeb(bbuf);
+    node->a->t2 = NULL;
+
+    compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, node->a);
+
+    buffer_fmt(tbuf, "return qi_make_table(state, table);\n}\n");
+
+    buffer_appendb(gbuf, tbuf);
+
+    EMIT("__%s%d(state)", PREFIX, gid);
+  } break;
+
   case N_TUPLE:
     EMIT("qi_make_tuple(state, ");
     compile_list(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l);
@@ -5381,7 +5493,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
 
   case N_TABLE:
     EMIT("qi_make_table(state, ");
-    compile_table(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->h);
+    compile_pairs(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l);
     EMIT(")");
     break;