add %= &= |= ^=

This commit is contained in:
blueloveTH 2022-12-12 20:29:21 +08:00
parent 6f33639fbd
commit a72e413034
6 changed files with 61 additions and 9 deletions

View File

@ -95,6 +95,10 @@ 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(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(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_SHIFT }; rules[TK(">>")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_SHIFT };
@ -199,10 +203,10 @@ 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->setNextTwoCharToken('=', TK("%"), TK("%=")); return;
case '&': parser->setNextToken(TK("&")); return; case '&': parser->setNextTwoCharToken('=', TK("&"), TK("&=")); return;
case '|': parser->setNextToken(TK("|")); return; case '|': parser->setNextTwoCharToken('=', TK("|"), TK("|=")); return;
case '^': parser->setNextToken(TK("^")); return; case '^': parser->setNextTwoCharToken('=', TK("^"), TK("^=")); return;
case '?': parser->setNextToken(TK("?")); return; case '?': parser->setNextToken(TK("?")); return;
case '.': { case '.': {
if(parser->matchChar('.')) { if(parser->matchChar('.')) {
@ -405,6 +409,11 @@ public:
case TK("*="): emitCode(OP_BINARY_OP, 2); break; case TK("*="): emitCode(OP_BINARY_OP, 2); break;
case TK("/="): emitCode(OP_BINARY_OP, 3); break; case TK("/="): emitCode(OP_BINARY_OP, 3); break;
case TK("//="): emitCode(OP_BINARY_OP, 4); break; case TK("//="): emitCode(OP_BINARY_OP, 4); break;
case TK("%="): emitCode(OP_BINARY_OP, 5); 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();
} }
emitCode(OP_STORE_REF); emitCode(OP_STORE_REF);
@ -549,17 +558,25 @@ __LISTCOMP:
} }
void exprMap() { void exprMap() {
bool parsing_dict = false;
int size = 0; int size = 0;
do { do {
matchNewLines(mode()==SINGLE_MODE); matchNewLines(mode()==SINGLE_MODE);
if (peek() == TK("}")) break; if (peek() == TK("}")) break;
EXPR();consume(TK(":"));EXPR(); EXPR();
if(peek() == TK(":")) parsing_dict = true;
if(parsing_dict){
consume(TK(":"));
EXPR();
}
size++; size++;
matchNewLines(mode()==SINGLE_MODE); matchNewLines(mode()==SINGLE_MODE);
} while (match(TK(","))); } while (match(TK(",")));
matchNewLines(); matchNewLines();
consume(TK("}")); consume(TK("}"));
emitCode(OP_BUILD_MAP, size);
if(parsing_dict) emitCode(OP_BUILD_MAP, size);
else emitCode(OP_BUILD_SET, size);
} }
void exprCall() { void exprCall() {

View File

@ -3,8 +3,8 @@
#include "pocketpy.h" #include "pocketpy.h"
#define PK_DEBUG_TIME //#define PK_DEBUG_TIME
//#define PK_DEBUG_THREADED #define PK_DEBUG_THREADED
struct Timer{ struct Timer{
const char* title; const char* title;

View File

@ -22,6 +22,7 @@ OPCODE(DUP_TOP)
OPCODE(BUILD_LIST) OPCODE(BUILD_LIST)
OPCODE(BUILD_MAP) OPCODE(BUILD_MAP)
OPCODE(BUILD_SET)
OPCODE(BUILD_SLICE) OPCODE(BUILD_SLICE)
OPCODE(LIST_APPEND) OPCODE(LIST_APPEND)

View File

@ -10,7 +10,7 @@ constexpr const char* __TOKENS[] = {
"+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->",
"<<", ">>", "&", "|", "^", "?", "<<", ">>", "&", "|", "^", "?",
"==", "!=", ">=", "<=", "==", "!=", ">=", "<=",
"+=", "-=", "*=", "/=", "//=", "+=", "-=", "*=", "/=", "//=", "%=", "&=", "|=", "^=",
/** KW_BEGIN **/ /** KW_BEGIN **/
"class", "import", "as", "def", "lambda", "pass", "del", "from", "with", "class", "import", "as", "def", "lambda", "pass", "del", "from", "with",
"None", "in", "is", "and", "or", "not", "True", "False", "global", "None", "in", "is", "and", "or", "not", "True", "False", "global",

View File

@ -249,6 +249,13 @@ protected:
} }
frame->push(obj); frame->push(obj);
} break; } break;
case OP_BUILD_SET:
{
pkpy::ArgList items = frame->popNValuesReversed(this, byte.arg);
PyVar list = PyList(items.toList());
PyVar obj = call(builtins->attribs["set"], pkpy::oneArg(list));
frame->push(obj);
} break;
case OP_DUP_TOP: frame->push(frame->topValue(this)); break; case OP_DUP_TOP: frame->push(frame->topValue(this)); break;
case OP_CALL: case OP_CALL:
{ {

27
tests/_assign.py Normal file
View File

@ -0,0 +1,27 @@
a = 0
a += 2
assert a == 2
a -= 1
assert a == 1
a *= 2
assert a == 2
a //= 2
assert a == 1
a |= 0xff
assert a == 0xff
a &= 0x0f
assert a == 0x0f
a = 8
a %= 3
assert a == 2
a ^= 0xf0
assert a == 242