add bitwise op

This commit is contained in:
blueloveTH 2022-11-13 18:30:13 +08:00
parent 32f0525484
commit dcc899a884
6 changed files with 47 additions and 7 deletions

View File

@ -93,6 +93,11 @@ public:
rules[TK("/=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT }; rules[TK("/=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
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(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 METHOD
#undef NO_INFIX #undef NO_INFIX
@ -181,10 +186,23 @@ 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->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 '+': 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 '-': { case '-': {
parser->setNextTwoCharToken('=', TK("-"), TK("-=")); parser->setNextTwoCharToken('=', TK("-"), TK("-="));
return; return;
@ -397,6 +415,12 @@ public:
case TK("not in"): emitCode(OP_CONTAINS_OP, 1); break; case TK("not in"): emitCode(OP_CONTAINS_OP, 1); break;
case TK("is"): emitCode(OP_IS_OP, 0); break; case TK("is"): emitCode(OP_IS_OP, 0); break;
case TK("is not"): emitCode(OP_IS_OP, 1); 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(); default: UNREACHABLE();
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -162,7 +162,13 @@ private:
{ {
PyVar rhs = frame->popValue(this); PyVar rhs = frame->popValue(this);
PyVar lhs = 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; } break;
case OP_COMPARE_OP: case OP_COMPARE_OP:
{ {