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(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();
}
}

View File

@ -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;

View File

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

View File

@ -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, // ()

View File

@ -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__"
};

View File

@ -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:
{