From dcc899a88411193a3a3df02fb5dbaa2ae7f41110 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 13 Nov 2022 18:30:13 +0800 Subject: [PATCH] add bitwise op --- src/compiler.h | 30 +++++++++++++++++++++++++++--- src/obj.h | 2 +- src/opcodes.h | 1 + src/parser.h | 7 ++++++- src/str.h | 6 +++++- src/vm.h | 8 +++++++- 6 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index 36e13cc9..42e6078f 100644 --- a/src/compiler.h +++ b/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(); } } diff --git a/src/obj.h b/src/obj.h index 3bf8c2b4..6a60ac73 100644 --- a/src/obj.h +++ b/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; diff --git a/src/opcodes.h b/src/opcodes.h index 76959db0..db6677cd 100644 --- a/src/opcodes.h +++ b/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) diff --git a/src/parser.h b/src/parser.h index 130d8cb6..38ff8ca4 100644 --- a/src/parser.h +++ b/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, // () diff --git a/src/str.h b/src/str.h index 4cd1b9e8..b05cfc28 100644 --- a/src/str.h +++ b/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__" }; \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index 12876569..f6365567 100644 --- a/src/vm.h +++ b/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: {