diff --git a/src/compiler.h b/src/compiler.h index 4ac15993..956d2b3c 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -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(exprComma), PREC_COMMA }; 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->setNextTwoCharToken('=', TK("&"), TK("&=")); return; + case '|': parser->setNextTwoCharToken('=', TK("|"), TK("|=")); return; + case '^': parser->setNextTwoCharToken('=', TK("^"), TK("^=")); return; case '?': parser->setNextToken(TK("?")); return; case '.': { if(parser->matchChar('.')) { @@ -405,6 +409,11 @@ public: case TK("*="): emitCode(OP_BINARY_OP, 2); break; case TK("/="): emitCode(OP_BINARY_OP, 3); 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(); } emitCode(OP_STORE_REF); @@ -549,17 +558,25 @@ __LISTCOMP: } void exprMap() { + bool parsing_dict = false; int size = 0; do { matchNewLines(mode()==SINGLE_MODE); if (peek() == TK("}")) break; - EXPR();consume(TK(":"));EXPR(); + EXPR(); + if(peek() == TK(":")) parsing_dict = true; + if(parsing_dict){ + consume(TK(":")); + EXPR(); + } size++; matchNewLines(mode()==SINGLE_MODE); } while (match(TK(","))); matchNewLines(); consume(TK("}")); - emitCode(OP_BUILD_MAP, size); + + if(parsing_dict) emitCode(OP_BUILD_MAP, size); + else emitCode(OP_BUILD_SET, size); } void exprCall() { diff --git a/src/main.cpp b/src/main.cpp index 511a7670..e8d29d87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,8 +3,8 @@ #include "pocketpy.h" -#define PK_DEBUG_TIME -//#define PK_DEBUG_THREADED +//#define PK_DEBUG_TIME +#define PK_DEBUG_THREADED struct Timer{ const char* title; diff --git a/src/opcodes.h b/src/opcodes.h index be1bc1dc..c2ea39f9 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -22,6 +22,7 @@ OPCODE(DUP_TOP) OPCODE(BUILD_LIST) OPCODE(BUILD_MAP) +OPCODE(BUILD_SET) OPCODE(BUILD_SLICE) OPCODE(LIST_APPEND) diff --git a/src/parser.h b/src/parser.h index 269de0bd..48b92d06 100644 --- a/src/parser.h +++ b/src/parser.h @@ -10,7 +10,7 @@ constexpr const char* __TOKENS[] = { "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", "<<", ">>", "&", "|", "^", "?", "==", "!=", ">=", "<=", - "+=", "-=", "*=", "/=", "//=", + "+=", "-=", "*=", "/=", "//=", "%=", "&=", "|=", "^=", /** KW_BEGIN **/ "class", "import", "as", "def", "lambda", "pass", "del", "from", "with", "None", "in", "is", "and", "or", "not", "True", "False", "global", diff --git a/src/vm.h b/src/vm.h index 6a8c6125..4ebceeae 100644 --- a/src/vm.h +++ b/src/vm.h @@ -249,6 +249,13 @@ protected: } frame->push(obj); } 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_CALL: { diff --git a/tests/_assign.py b/tests/_assign.py new file mode 100644 index 00000000..3776a487 --- /dev/null +++ b/tests/_assign.py @@ -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 \ No newline at end of file