blueloveTH 3 лет назад
Родитель
Сommit
dcc899a884
6 измененных файлов с 47 добавлено и 7 удалено
  1. 27 3
      src/compiler.h
  2. 1 1
      src/obj.h
  3. 1 0
      src/opcodes.h
  4. 6 1
      src/parser.h
  5. 5 1
      src/str.h
  6. 7 1
      src/vm.h

+ 27 - 3
src/compiler.h

@@ -93,6 +93,11 @@ public:
         rules[TK("/=")] =       { nullptr,               METHOD(exprAssign),         PREC_ASSIGNMENT };
         rules[TK("//=")] =      { nullptr,               METHOD(exprAssign),         PREC_ASSIGNMENT };
         rules[TK(",")] =        { nullptr,               METHOD(exprComma),          PREC_COMMA };
+        rules[TK("<<")] =       { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_SHIFT };
+        rules[TK(">>")] =       { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_SHIFT };
+        rules[TK("&")] =        { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_AND };
+        rules[TK("|")] =        { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_OR };
+        rules[TK("^")] =        { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_XOR };
 #undef METHOD
 #undef NO_INFIX
 
@@ -180,11 +185,24 @@ public:
                 case '[': parser->setNextToken(TK("[")); return;
                 case ']': parser->setNextToken(TK("]")); return;
                 case '%': parser->setNextToken(TK("%")); return;
-                case '.': parser->setNextToken(TK(".")); return;                
+                case '.': parser->setNextToken(TK(".")); return;
+                case '&': parser->setNextToken(TK("&")); return;
+                case '|': parser->setNextToken(TK("|")); return;
+                case '^': parser->setNextToken(TK("^")); return;
                 case '=': parser->setNextTwoCharToken('=', TK("="), TK("==")); return;
-                case '>': parser->setNextTwoCharToken('=', TK(">"), TK(">=")); return;
-                case '<': parser->setNextTwoCharToken('=', TK("<"), TK("<=")); return;
                 case '+': parser->setNextTwoCharToken('=', TK("+"), TK("+=")); return;
+                case '>': {
+                    if(parser->matchChar('=')) parser->setNextToken(TK(">="));
+                    else if(parser->matchChar('>')) parser->setNextToken(TK(">>"));
+                    else parser->setNextToken(TK(">"));
+                    return;
+                }
+                case '<': {
+                    if(parser->matchChar('=')) parser->setNextToken(TK("<="));
+                    else if(parser->matchChar('<')) parser->setNextToken(TK("<<"));
+                    else parser->setNextToken(TK("<"));
+                    return;
+                }
                 case '-': {
                     parser->setNextTwoCharToken('=', TK("-"), TK("-="));
                     return;
@@ -397,6 +415,12 @@ public:
             case TK("not in"):  emitCode(OP_CONTAINS_OP, 1);   break;
             case TK("is"):      emitCode(OP_IS_OP, 0);         break;
             case TK("is not"):  emitCode(OP_IS_OP, 1);         break;
+
+            case TK("<<"):  emitCode(OP_BITWISE_OP, 0);    break;
+            case TK(">>"):  emitCode(OP_BITWISE_OP, 1);    break;
+            case TK("&"):   emitCode(OP_BITWISE_OP, 2);    break;
+            case TK("|"):   emitCode(OP_BITWISE_OP, 3);    break;
+            case TK("^"):   emitCode(OP_BITWISE_OP, 4);    break;
             default: UNREACHABLE();
         }
     }

+ 1 - 1
src/obj.h

@@ -11,7 +11,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
 const _Float _FLOAT_INF_POS = INFINITY;
 const _Float _FLOAT_INF_NEG = -INFINITY;
 
-#define PK_VERSION "0.2.2"
+#define PK_VERSION "0.2.3"
 
 class PyObject;
 class CodeObject;

+ 1 - 0
src/opcodes.h

@@ -10,6 +10,7 @@ OPCODE(RETURN_VALUE)
 
 OPCODE(BINARY_OP)
 OPCODE(COMPARE_OP)
+OPCODE(BITWISE_OP)
 OPCODE(IS_OP)
 OPCODE(CONTAINS_OP)
 

+ 6 - 1
src/parser.h

@@ -8,6 +8,7 @@ constexpr const char* __TOKENS[] = {
     "@error", "@eof", "@eol", "@sof",
     ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%",
     "+", "-", "*", "/", "//", "**", "=", ">", "<",
+    "<<", ">>", "&", "|", "^",
     "==", "!=", ">=", "<=",
     "+=", "-=", "*=", "/=", "//=",
     /** KW_BEGIN **/
@@ -76,8 +77,12 @@ enum Precedence {
   PREC_EQUALITY,      // == !=
   PREC_TEST,          // in is
   PREC_COMPARISION,   // < > <= >=
+  PREC_BITWISE_OR,    // |
+  PREC_BITWISE_XOR,   // ^
+  PREC_BITWISE_AND,   // &
+  PREC_BITWISE_SHIFT, // << >>
   PREC_TERM,          // + -
-  PREC_FACTOR,        // * / %
+  PREC_FACTOR,        // * / % //
   PREC_UNARY,         // - not
   PREC_EXPONENT,      // **
   PREC_CALL,          // ()

+ 5 - 1
src/str.h

@@ -193,6 +193,10 @@ const _Str CMP_SPECIAL_METHODS[] = {
     "__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__"
 };  // __ne__ should not be used
 
-const _Str BIN_SPECIAL_METHODS[] = {
+const _Str BINARY_SPECIAL_METHODS[] = {
     "__add__", "__sub__", "__mul__", "__truediv__", "__floordiv__", "__mod__", "__pow__"
+};
+
+const _Str BITWISE_SPECIAL_METHODS[] = {
+    "__lshift__", "__rshift__", "__and__", "__or__", "__xor__"
 };

+ 7 - 1
src/vm.h

@@ -162,7 +162,13 @@ private:
                 {
                     PyVar rhs = frame->popValue(this);
                     PyVar lhs = frame->popValue(this);
-                    frame->push(fastCall(lhs, BIN_SPECIAL_METHODS[byte.arg], {lhs,rhs}));
+                    frame->push(fastCall(lhs, BINARY_SPECIAL_METHODS[byte.arg], {lhs,rhs}));
+                } break;
+            case OP_BITWISE_OP:
+                {
+                    PyVar rhs = frame->popValue(this);
+                    PyVar lhs = frame->popValue(this);
+                    frame->push(fastCall(lhs, BITWISE_SPECIAL_METHODS[byte.arg], {lhs,rhs}));
                 } break;
             case OP_COMPARE_OP:
                 {