|
@@ -771,6 +771,7 @@ struct _node_t {
|
|
N_TABLE,
|
|
N_TABLE,
|
|
|
|
|
|
N_CALL,
|
|
N_CALL,
|
|
|
|
+ N_STAR,
|
|
N_MEMBER,
|
|
N_MEMBER,
|
|
N_INDEX,
|
|
N_INDEX,
|
|
|
|
|
|
@@ -1061,7 +1062,10 @@ list_t *parse_sequence(list_t *tokens, size_t *pos, int term) {
|
|
if (term != -1 && *pos < tokens->length && ((token_t *)tokens->data[*pos])->tag == term)
|
|
if (term != -1 && *pos < tokens->length && ((token_t *)tokens->data[*pos])->tag == term)
|
|
break;
|
|
break;
|
|
|
|
|
|
- list_push(seq, parse_expr(tokens, pos));
|
|
|
|
|
|
+ if (MATCH(STAR))
|
|
|
|
+ list_push(seq, NODE1(STAR, parse_expr(tokens, pos)));
|
|
|
|
+ else
|
|
|
|
+ list_push(seq, parse_expr(tokens, pos));
|
|
} while (MATCH(COMMA));
|
|
} while (MATCH(COMMA));
|
|
|
|
|
|
return seq;
|
|
return seq;
|
|
@@ -2118,6 +2122,15 @@ node_t *parse(char *source) {
|
|
|
|
|
|
void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, node_t *node);
|
|
void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, node_t *node);
|
|
|
|
|
|
|
|
+char *tempvar() {
|
|
|
|
+ NEWGID();
|
|
|
|
+
|
|
|
|
+ char *s = malloc(sizeof(char) * 64);
|
|
|
|
+ snprintf(s, 64, "__temp%zu", gid);
|
|
|
|
+
|
|
|
|
+ return s;
|
|
|
|
+}
|
|
|
|
+
|
|
void compile_list(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, list_t *seq) {
|
|
void compile_list(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, list_t *seq) {
|
|
if (!seq || seq->length < 1) {
|
|
if (!seq || seq->length < 1) {
|
|
EMIT("NULL");
|
|
EMIT("NULL");
|
|
@@ -2125,19 +2138,48 @@ void compile_list(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ int has_star = 0;
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < seq->length; i++)
|
|
|
|
+ if (((node_t *)seq->data[i])->tag == N_STAR) {
|
|
|
|
+ has_star = 1; break;
|
|
|
|
+ }
|
|
|
|
+
|
|
buffer_t *tbuf = buffer_new();
|
|
buffer_t *tbuf = buffer_new();
|
|
|
|
|
|
NEWGID();
|
|
NEWGID();
|
|
|
|
|
|
buffer_fmt(tbuf, "inline static qi_list_t *__list%d(qi_state_t *state) {\n", gid);
|
|
buffer_fmt(tbuf, "inline static qi_list_t *__list%d(qi_state_t *state) {\n", gid);
|
|
- buffer_fmt(tbuf, "qi_list_t *list = qi_list_make_n(%d);\n", seq->length);
|
|
|
|
|
|
+ if (has_star)
|
|
|
|
+ buffer_fmt(tbuf, "qi_list_t *list = qi_list_make();\n");
|
|
|
|
+ else
|
|
|
|
+ buffer_fmt(tbuf, "qi_list_t *list = qi_list_make_n(%d);\n", seq->length);
|
|
|
|
|
|
for (size_t i = 0; i < seq->length; i++) {
|
|
for (size_t i = 0; i < seq->length; i++) {
|
|
- buffer_fmt(tbuf, "qi_list_data(list, %d) = ", i);
|
|
|
|
|
|
+ node_t *node = seq->data[i];
|
|
|
|
+
|
|
|
|
+ if (!has_star) {
|
|
|
|
+ buffer_fmt(tbuf, "qi_list_data(list, %d) = ", i);
|
|
|
|
+ compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, node);
|
|
|
|
+ buffer_fmt(tbuf, ";\n");
|
|
|
|
|
|
- compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, seq->data[i]);
|
|
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (node->tag == N_STAR) {
|
|
|
|
+ char *varname = tempvar();
|
|
|
|
|
|
- buffer_fmt(tbuf, ";\n");
|
|
|
|
|
|
+ buffer_fmt(tbuf, "qi_value_t *%s = qi_iter(state, ", varname);
|
|
|
|
+ compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, node->a);
|
|
|
|
+ buffer_fmt(tbuf, ");\n");
|
|
|
|
+
|
|
|
|
+ buffer_fmt(tbuf, "for (qi_size_t i = 0; i < %s->value.list->length; i++)\n", varname);
|
|
|
|
+ buffer_fmt(tbuf, "qi_list_push(list, qi_index(state, %s, qi_make_number(state, i)));\n", varname);
|
|
|
|
+ } else {
|
|
|
|
+ buffer_fmt(tbuf, "qi_list_push(list, ");
|
|
|
|
+ compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, node);
|
|
|
|
+ buffer_fmt(tbuf, ");\n");
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
buffer_fmt(tbuf, "return list;\n");
|
|
buffer_fmt(tbuf, "return list;\n");
|
|
@@ -2240,15 +2282,6 @@ size_t count_ctxs(list_t *ctx, char *s) {
|
|
#define LBPUSH() list_push(lbl, table_new())
|
|
#define LBPUSH() list_push(lbl, table_new())
|
|
#define LBPOP() list_pop(lbl)
|
|
#define LBPOP() list_pop(lbl)
|
|
|
|
|
|
-char *tempvar() {
|
|
|
|
- NEWGID();
|
|
|
|
-
|
|
|
|
- char *s = malloc(sizeof(char) * 64);
|
|
|
|
- snprintf(s, 64, "__temp%zu", gid);
|
|
|
|
-
|
|
|
|
- return s;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, node_t *node, char *name) {
|
|
void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, node_t *node, char *name) {
|
|
NEWGID();
|
|
NEWGID();
|
|
|
|
|