|
@@ -1035,6 +1035,7 @@ struct _node_t {
|
|
N_LITERAL,
|
|
N_LITERAL,
|
|
N_LIST,
|
|
N_LIST,
|
|
N_LISTGEN,
|
|
N_LISTGEN,
|
|
|
|
+ N_TABLEGEN,
|
|
N_TUPLE,
|
|
N_TUPLE,
|
|
N_NILTUPLE,
|
|
N_NILTUPLE,
|
|
N_TABLE,
|
|
N_TABLE,
|
|
@@ -1570,29 +1571,64 @@ node_t *parse_primary(list_t *tokens, size_t *pos) {
|
|
|
|
|
|
return NODEL(LIST, a);
|
|
return NODEL(LIST, a);
|
|
} else if (MATCH(LCB)) {
|
|
} else if (MATCH(LCB)) {
|
|
- table_t *table = table_new();
|
|
|
|
|
|
+ list_t *pairs = list_new();
|
|
|
|
|
|
do {
|
|
do {
|
|
if (AT(RCB))
|
|
if (AT(RCB))
|
|
break;
|
|
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, ":");
|
|
EXPECT(COLON, ":");
|
|
|
|
|
|
node_t *val = parse_expr(tokens, pos);
|
|
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));
|
|
} 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, "}");
|
|
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) ||
|
|
} else if (MATCH(NUMBER) || MATCH(STRING) || MATCH(FSTRING) ||
|
|
MATCH(USTRING) || MATCH(NAME) || MATCH(TRUE) || MATCH(FALSE) ||
|
|
MATCH(USTRING) || MATCH(NAME) || MATCH(TRUE) || MATCH(FALSE) ||
|
|
MATCH(NIL))
|
|
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);
|
|
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 CTXPUSH(s) list_push(ctx, (s))
|
|
#define CTXPOP() list_pop(ctx)
|
|
#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);
|
|
EMIT("__%s%d(state)", PREFIX, gid);
|
|
} break;
|
|
} 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:
|
|
case N_TUPLE:
|
|
EMIT("qi_make_tuple(state, ");
|
|
EMIT("qi_make_tuple(state, ");
|
|
compile_list(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l);
|
|
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:
|
|
case N_TABLE:
|
|
EMIT("qi_make_table(state, ");
|
|
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(")");
|
|
EMIT(")");
|
|
break;
|
|
break;
|
|
|
|
|