txlyre 1 месяц назад
Родитель
Сommit
26c655ae86
1 измененных файлов с 128 добавлено и 0 удалено
  1. 128 0
      qic.c

+ 128 - 0
qic.c

@@ -295,6 +295,8 @@ typedef struct {
     T_CATCH,
     T_THROW,
     T_GOTO,
+    T_IS,
+    T_IN,
 
     T_LPAR,
     T_RPAR,
@@ -304,6 +306,7 @@ typedef struct {
     T_RCB,
 
     T_EQUALS,
+    T_NOTEQUALS,
     T_PLUSASSIGN,
     T_BARBAR,
     T_ANDAND,
@@ -325,8 +328,10 @@ typedef struct {
     T_GTGT,
     T_STAR,
     T_SLASH,
+    T_PERCENT,
     T_COMMA,
     T_DOT,
+    T_BANG,
 
     T_ASSIGN,
     T_SEMI
@@ -553,10 +558,16 @@ token_t *next_token(char *source, size_t *pos) {
       return TK(THROW);
     else if (strcmp(name, "goto") == 0)
       return TK(GOTO);
+    else if (strcmp(name, "is") == 0)
+      return TK(IS);
+    else if (strcmp(name, "in") == 0)
+      return TK(IN);
 
     return token(T_NAME, name);
   } else if (strncmp(&source[*pos], "==", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(EQUALS);
+  else if (strncmp(&source[*pos], "!=", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(NOTEQUALS);
   else if (strncmp(&source[*pos], "+=", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(PLUSASSIGN);
   else if (strncmp(&source[*pos], "||", 2) == 0 && ++(*pos) && ++(*pos))
@@ -571,6 +582,10 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(SLASHSLASH);
   else if (strncmp(&source[*pos], "**", 2) == 0 && ++(*pos) && ++(*pos))
     return TK(STARSTAR);
+  else if (strncmp(&source[*pos], "<<", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(LTLT);
+  else if (strncmp(&source[*pos], ">>", 2) == 0 && ++(*pos) && ++(*pos))
+    return TK(GTGT);
   else if (source[*pos] == '(' && ++(*pos))
     return TK(LPAR);
   else if (source[*pos] == ')' && ++(*pos))
@@ -591,6 +606,8 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(STAR);
   else if (source[*pos] == '/' && ++(*pos))
     return TK(SLASH);
+  else if (source[*pos] == '%' && ++(*pos))
+    return TK(PERCENT);
   else if (source[*pos] == '?' && ++(*pos))
     return TK(QM);
   else if (source[*pos] == ':' && ++(*pos))
@@ -607,6 +624,8 @@ token_t *next_token(char *source, size_t *pos) {
     return TK(LT);
   else if (source[*pos] == '>' && ++(*pos))
     return TK(GT);
+  else if (source[*pos] == '!' && ++(*pos))
+    return TK(BANG);
 
   LEX_ERROR("unexpected input")
 }
@@ -640,6 +659,7 @@ struct _node_t {
 
     N_BLOCK,
 
+    N_NOT,
     N_NEGATE,
 
     N_LITERAL,
@@ -657,12 +677,21 @@ struct _node_t {
     N_MUL,
     N_DIV,
     N_IDIV,
+    N_MOD,
     N_POW,
+    N_SHL,
+    N_SHR,
 
     N_ASSIGN,
     N_ASSIGN_ADD,
 
     N_EQUALS,
+    N_NOTEQUALS,
+    N_IS,
+    N_IN,
+    N_NOTIS,
+    N_NOTIN,
+
     N_LT,
     N_GT,
 
@@ -1011,6 +1040,10 @@ node_t *parse_unary(list_t *tokens, size_t *pos) {
     node_t *a = parse_unary(tokens, pos);
 
     return NODE1(NEGATE, a);
+  } else if (MATCH(BANG)) {
+    node_t *a = parse_unary(tokens, pos);
+
+    return NODE1(NOT, a);
   }
 
   return parse_postfix(tokens, pos);
@@ -1055,6 +1088,12 @@ node_t *parse_mul(list_t *tokens, size_t *pos) {
 
       a = NODE2(IDIV, a, b);
 
+      continue;
+    } else if (MATCH(PERCENT)) {
+      node_t *b = parse_pow(tokens, pos);
+
+      a = NODE2(MOD, a, b);
+
       continue;
     }
 
@@ -1091,6 +1130,23 @@ node_t *parse_add(list_t *tokens, size_t *pos) {
 node_t *parse_shift(list_t *tokens, size_t *pos) {
   node_t *a = parse_add(tokens, pos);
 
+  do {
+    if (MATCH(LTLT)) {
+      node_t *b = parse_add(tokens, pos);
+
+      a = NODE2(SHL, a, b);
+
+      continue;
+    } else if (MATCH(GTGT)) {
+      node_t *b = parse_add(tokens, pos);
+
+      a = NODE2(SHR, a, b);
+
+      continue;
+    }
+    break;
+  } while (1);
+
   return a;
 }
 
@@ -1127,6 +1183,42 @@ node_t *parse_equality(list_t *tokens, size_t *pos) {
 
       a = NODE2(EQUALS, a, b);
 
+      continue;
+    } else if (MATCH(NOTEQUALS)) {
+      node_t *b = parse_relation(tokens, pos);
+
+      a = NODE2(NOTEQUALS, a, b);
+
+      continue;
+    } else if (MATCH(IS)) {
+      node_t *b = parse_relation(tokens, pos);
+
+      a = NODE2(IS, a, b);
+
+      continue;
+    } else if (AT(BANG) && ATP(IS, 1)) {
+      EXPECT(BANG, "!");
+      EXPECT(IS, "is");
+
+      node_t *b = parse_relation(tokens, pos);
+
+      a = NODE2(NOTIS, a, b);
+
+      continue;
+    } else if (MATCH(IN)) {
+      node_t *b = parse_relation(tokens, pos);
+
+      a = NODE2(IN, a, b);
+
+      continue;
+    } else if (AT(BANG) && ATP(IN, 1)) {
+      EXPECT(BANG, "!");
+      EXPECT(IN, "in");
+
+      node_t *b = parse_relation(tokens, pos);
+
+      a = NODE2(NOTIN, a, b);
+
       continue;
     }
 
@@ -2073,6 +2165,26 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       BINOP("equals");
       break;
 
+    case N_NOTEQUALS:
+      BINOP("not_equals");
+      break;
+
+    case N_IS:
+      BINOP("is");
+      break;
+
+    case N_NOTIS:
+      BINOP("not_is");
+      break;
+
+    case N_IN:
+      BINOP("in");
+      break;
+
+    case N_NOTIN:
+      BINOP("not_in");
+      break;
+
     case N_LT:
       BINOP("lt");
       break;
@@ -2101,14 +2213,30 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
       BINOP("idiv");
       break;
 
+    case N_MOD:
+      BINOP("mod");
+      break;
+
     case N_POW:
       BINOP("pow");
       break;
 
+    case N_SHL:
+      BINOP("shl");
+      break;
+
+    case N_SHR:
+      BINOP("shr");
+      break;
+
     case N_NEGATE:
       UNOP("negate");
       break;
 
+    case N_NOT:
+      UNOP("not");
+      break;
+
     default:
       COMPILE_ERROR("not yet implemented");
   }