txlyre 1 giorno fa
parent
commit
d460fd8afb
1 ha cambiato i file con 47 aggiunte e 14 eliminazioni
  1. 47 14
      qic.c

+ 47 - 14
qic.c

@@ -771,6 +771,7 @@ struct _node_t {
     N_TABLE,
 
     N_CALL,
+    N_STAR,
     N_MEMBER,
     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)
       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));
 
   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);
 
+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) {
   if (!seq || seq->length < 1) {
     EMIT("NULL");
@@ -2125,19 +2138,48 @@ void compile_list(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
     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();
 
   NEWGID();
 
   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++) {
-    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");
@@ -2240,15 +2282,6 @@ size_t count_ctxs(list_t *ctx, char *s) {
 #define LBPUSH() list_push(lbl, table_new())
 #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) {
   NEWGID();