txlyre 1 kuukausi sitten
vanhempi
commit
1f1ba1ad13
1 muutettua tiedostoa jossa 67 lisäystä ja 7 poistoa
  1. 67 7
      qic.c

+ 67 - 7
qic.c

@@ -571,6 +571,10 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(COMMA);
   else if (source[*pos] == '.' && ++(*pos))
     return TK(DOT);
+  else if (source[*pos] == '<' && ++(*pos))
+    return TK(LT);
+  else if (source[*pos] == '>' && ++(*pos))
+    return TK(GT);
 
   LEX_ERROR("unexpected input")
 }
@@ -625,6 +629,8 @@ struct _node_t {
     N_ASSIGN_ADD,
 
     N_EQUALS,
+    N_LT,
+    N_GT,
 
     N_INC,
     N_DEC,
@@ -1019,6 +1025,24 @@ node_t *parse_shift(list_t *tokens, size_t *pos) {
 node_t *parse_relation(list_t *tokens, size_t *pos) {
   node_t *a = parse_shift(tokens, pos);
 
+  do {
+    if (MATCH(LT)) {
+      node_t *b = parse_shift(tokens, pos);
+
+      a = NODE2(LT, a, b);
+
+      continue;
+    } else if (MATCH(GT)) {
+      node_t *b = parse_shift(tokens, pos);
+
+      a = NODE2(GT, a, b);
+
+      continue;
+    }
+
+    break;
+  } while (1);
+
   return a;
 }
 
@@ -1447,7 +1471,24 @@ int in_context(list_t *ctx, char *s) {
   return 0;
 }
 
+size_t scopes_count(list_t *ctx) {
+  if (!ctx->length)
+    return 0;
+
+  size_t k = 0;
+
+  for (ssize_t i = ctx->length - 1; i >= 0; i--) {
+    if (strcmp(ctx->data[i], "gap") == 0)
+      break;
+    else if (strcmp(ctx->data[i], "scope") == 0)
+      k++;
+  }
+
+  return k;
+}
+
 #define INCTX(s) (in_context(ctx, (s)))
+#define SCOPESK (scopes_count(ctx))
 
 #define LPUSH(i) stack_push(lstk, (i))
 #define LPOP() stack_pop(lstk)
@@ -1474,11 +1515,11 @@ void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
       if (pair->data[1]) {
         optargc++;
 
-        buffer_fmt(tbuf, "qi_set(state, false, false, \"%s\", pargc >= %d? qi_list_index(pargs, %d): ", entry.key, argc+1, argc);
+        buffer_fmt(tbuf, "qi_set(state, false, \"%s\", pargc >= %d? qi_list_index(pargs, %d): ", entry.key, argc+1, argc);
         compile_node(gbuf, tbuf, ctx, lstk, pair->data[1]);
         buffer_fmt(tbuf, ");\n");
       } else
-        buffer_fmt(tbuf, "qi_set(state, false, false, \"%s\", qi_list_index(pargs, %d));\n", entry.key, argc);
+        buffer_fmt(tbuf, "qi_set(state, false, \"%s\", qi_list_index(pargs, %d));\n", entry.key, argc);
 
       argc++;
     });
@@ -1506,7 +1547,7 @@ void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
     return;
   }
 
-  EMIT("qi_set(state, false, false, \"%s\", ", node->t->text);
+  EMIT("qi_set(state, false, \"%s\", ", node->t->text);
   buffer_appendb(buf, tbuf);
   EMIT(");");
 }
@@ -1552,9 +1593,11 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
       break;
 
     case N_BLOCK:
+      CTXPUSH("scope");
       EMIT("qi_new_scope(state);\n");
       compile_block(gbuf, buf, ctx, lstk, node->l);
       EMIT("qi_old_scope(state);");
+      CTXPOP();
       break;
 
     case N_LITERAL:
@@ -1639,15 +1682,19 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
     case N_IF:
       EMIT("if (_qi_truthy(state, ");
       compile_node(gbuf, buf, ctx, lstk, node->a);
-      EMIT(") {\n");
-      EMIT("qi_new_subscope(state);\n");
+      EMIT(")) {\n");
+      CTXPUSH("scope");
+      EMIT("qi_new_scope(state);\n");
       compile_node(gbuf, buf, ctx, lstk, node->b);
       EMIT("qi_old_scope(state);\n");
+      CTXPOP();
       if (node->c) {
         EMIT("} else {\n");
-        EMIT("qi_new_subscope(state);\n");
+        CTXPUSH("scope");
+        EMIT("qi_new_scope(state);\n");
         compile_node(gbuf, buf, ctx, lstk, node->c);
         EMIT("qi_old_scope(state);\n");
+        CTXPOP();
       }
       EMIT("}");
       break;
@@ -1655,7 +1702,8 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
     case N_FOR: {
       NEWGID();
 
-      EMIT("qi_new_subscope(state);\n");
+      CTXPUSH("scope");
+      EMIT("qi_new_scope(state);\n");
 
       if (!node->a) {
         EMIT("for (;;) {\n");
@@ -1686,6 +1734,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
       EMIT("__break%d:;\n", gid);
 
       EMIT("qi_old_scope(state);\n");
+      CTXPOP();
       } break;
 
     case N_BREAK:
@@ -1725,6 +1774,9 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
       if (!INCTX("func"))
         COMPILE_ERROR("return outside of a function");
 
+      for (size_t i = 0; i < SCOPESK; i++)
+        EMIT("qi_old_scope(state);\n");
+
       EMIT("return ");
 
       if (node->a)
@@ -1754,6 +1806,14 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, nod
       BINOP("equals");
       break;
 
+    case N_LT:
+      BINOP("lt");
+      break;
+
+    case N_GT:
+      BINOP("gt");
+      break;
+
     case N_ADD:
       BINOP("add");
       break;