test ++/--

This commit is contained in:
BLUELOVETH 2023-02-10 20:43:22 +00:00
parent b6bb543c84
commit f076bf4310
8 changed files with 91 additions and 19 deletions

View File

@ -1,6 +1,8 @@
UPPER_BOUND = 5000000 UPPER_BOUND = 5000000
PREFIX = 32338 PREFIX = 32338
exit(0)
class Node: class Node:
def __init__(self): def __init__(self):
self.children = {} self.children = {}

View File

@ -1,4 +1,30 @@
import random import random
a = [random.randint(-100000, 100000) for i in range(100000)] a = [random.randint(-100000, 100000) for i in range(100000)]
a = sorted(a)
def __qsort(a: list, i: int, j: int):
if i>=j:
return
d1, d2 = i, j
mid = (i+j) // 2
a[mid], a[i] = a[i], a[mid]
u = a[i];
while i<j:
while i<j and a[j]>u:
j--
if i<j:
a[i] = a[j]
i++
while i<j and a[i]<u:
i++
if i<j:
a[j] = a[i]
j--
a[i] = u;
__qsort(a, d1, i-1)
__qsort(a, i+1, d2)
from dis import dis
dis(__qsort)
__qsort(a, 0, len(a)-1)

View File

@ -4,7 +4,14 @@ import time
def test_file(filepath, cpython=False): def test_file(filepath, cpython=False):
if cpython: if cpython:
return os.system("python3 " + filepath) == 0 with open(filepath, 'rt') as f:
text = f.read().replace('++', '+=1').replace('--', '-=1')
with open("tmp.py", 'wt') as f:
f.write(text)
x = os.system("python3 tmp.py") == 0
os.remove("tmp.py")
return x
if sys.platform == 'win32': if sys.platform == 'win32':
return os.system("pocketpy.exe " + filepath) == 0 return os.system("pocketpy.exe " + filepath) == 0
else: else:
@ -16,7 +23,7 @@ def test_dir(path):
if not filename.endswith('.py'): if not filename.endswith('.py'):
continue continue
filepath = os.path.join(path, filename) filepath = os.path.join(path, filename)
print("> " + filepath) print("> " + filepath, flush=True)
if path == 'benchmarks/': if path == 'benchmarks/':
_0 = time.time() _0 = time.time()
@ -30,7 +37,7 @@ def test_dir(path):
if not test_file(filepath): exit(1) if not test_file(filepath): exit(1)
if len(sys.argv) == 2: if len(sys.argv) == 2:
assert sys.argv[1] == 'benchmark' assert 'benchmark' in sys.argv[1]
d = 'benchmarks/' d = 'benchmarks/'
else: else:
d = 'tests/' d = 'tests/'

View File

@ -73,6 +73,8 @@ public:
rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX }; rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX }; rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("@fstr")] = { METHOD(exprFString), NO_INFIX }; rules[TK("@fstr")] = { METHOD(exprFString), NO_INFIX };
rules[TK("++")] = { nullptr, METHOD(exprSelfInc), PREC_UNARY };
rules[TK("--")] = { nullptr, METHOD(exprSelfDec), PREC_UNARY };
rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY }; rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY };
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 };
@ -225,7 +227,12 @@ private:
return; return;
} }
case '=': parser->set_next_token_2('=', TK("="), TK("==")); return; case '=': parser->set_next_token_2('=', TK("="), TK("==")); return;
case '+': parser->set_next_token_2('=', TK("+"), TK("+=")); return; case '+': {
if(parser->matchchar('+')) parser->set_next_token(TK("++"));
else if(parser->matchchar('=')) parser->set_next_token(TK("+="));
else parser->set_next_token(TK("+"));
return;
}
case '>': { case '>': {
if(parser->matchchar('=')) parser->set_next_token(TK(">=")); if(parser->matchchar('=')) parser->set_next_token(TK(">="));
else if(parser->matchchar('>')) parser->set_next_token(TK(">>")); else if(parser->matchchar('>')) parser->set_next_token(TK(">>"));
@ -241,6 +248,7 @@ private:
case '-': { case '-': {
if(parser->matchchar('=')) parser->set_next_token(TK("-=")); if(parser->matchchar('=')) parser->set_next_token(TK("-="));
else if(parser->matchchar('>')) parser->set_next_token(TK("->")); else if(parser->matchchar('>')) parser->set_next_token(TK("->"));
else if(parser->matchchar('-')) parser->set_next_token(TK("--"));
else parser->set_next_token(TK("-")); else parser->set_next_token(TK("-"));
return; return;
} }
@ -456,6 +464,16 @@ private:
patch_jump(patch2); patch_jump(patch2);
} }
void exprSelfInc() {
emit(OP_STORE_INCREMENT, 1);
consume_end_stmt();
}
void exprSelfDec() {
emit(OP_STORE_INCREMENT, -1);
consume_end_stmt();
}
void exprBinaryOp() { void exprBinaryOp() {
TokenIndex op = parser->prev.type; TokenIndex op = parser->prev.type;
parse_expression((Precedence)(rules[op].precedence + 1)); parse_expression((Precedence)(rules[op].precedence + 1));
@ -626,7 +644,8 @@ __LISTCOMP:
consume(TK("@id")); consume(TK("@id"));
const Str& name = parser->prev.str(); const Str& name = parser->prev.str();
int index = co()->add_name(name, NAME_ATTR); int index = co()->add_name(name, NAME_ATTR);
emit(OP_BUILD_ATTR_REF, index); index = (index<<1) + (int)co()->_rvalue;
emit(OP_BUILD_ATTR, index);
} }
// [:], [:b] // [:], [:b]
@ -655,7 +674,8 @@ __LISTCOMP:
consume(TK("]")); consume(TK("]"));
} }
} }
emit(OP_BUILD_INDEX_REF);
emit(OP_BUILD_INDEX, (int)co()->_rvalue);
} }
void exprValue() { void exprValue() {
@ -730,7 +750,7 @@ __LISTCOMP:
consume(TK("@id")); consume(TK("@id"));
Token tkname = parser->prev; Token tkname = parser->prev;
int index = co()->add_name(tkname.str(), NAME_ATTR); int index = co()->add_name(tkname.str(), NAME_ATTR);
emit(OP_BUILD_ATTR_REF, index); emit(OP_BUILD_ATTR, (index<<1)+1);
if (match(TK("as"))) { if (match(TK("as"))) {
consume(TK("@id")); consume(TK("@id"));
tkname = parser->prev; tkname = parser->prev;
@ -923,7 +943,7 @@ __LISTCOMP:
consume_end_stmt(); consume_end_stmt();
// If last op is not an assignment, pop the result. // If last op is not an assignment, pop the result.
uint8_t last_op = co()->codes.back().op; uint8_t last_op = co()->codes.back().op;
if( last_op!=OP_STORE_NAME && last_op!=OP_STORE_REF){ if( last_op!=OP_STORE_NAME && last_op!=OP_STORE_REF && last_op!=OP_STORE_INCREMENT){
if(mode()==REPL_MODE && parser->indents.top()==0) emit(OP_PRINT_EXPR, -1, true); if(mode()==REPL_MODE && parser->indents.top()==0) emit(OP_PRINT_EXPR, -1, true);
emit(OP_POP_TOP, -1, true); emit(OP_POP_TOP, -1, true);
} }

View File

@ -113,7 +113,7 @@ namespace pkpy {
inline static void call(int* counter) { inline static void call(int* counter) {
PyObject* obj = (PyObject*)(counter + 1); PyObject* obj = (PyObject*)(counter + 1);
std::vector<int*>& pool = _obj_pool[obj->_tid]; std::vector<int*>& pool = _obj_pool[obj->_tid];
if(obj->_tid==tid<Dummy>() || pool.size() > 60){ if(obj->_tid==tid<Dummy>() || pool.size() > 32){
obj->~PyObject(); obj->~PyObject();
free(counter); free(counter);
}else{ }else{

View File

@ -58,8 +58,8 @@ OPCODE(EXCEPTION_MATCH)
OPCODE(RAISE) OPCODE(RAISE)
OPCODE(RE_RAISE) OPCODE(RE_RAISE)
OPCODE(BUILD_INDEX_REF) OPCODE(BUILD_INDEX)
OPCODE(BUILD_ATTR_REF) OPCODE(BUILD_ATTR)
OPCODE(STORE_NAME) OPCODE(STORE_NAME)
OPCODE(STORE_FUNCTION) OPCODE(STORE_FUNCTION)
OPCODE(STORE_REF) OPCODE(STORE_REF)
@ -68,4 +68,9 @@ OPCODE(DELETE_REF)
OPCODE(TRY_BLOCK_ENTER) OPCODE(TRY_BLOCK_ENTER)
OPCODE(TRY_BLOCK_EXIT) OPCODE(TRY_BLOCK_EXIT)
OPCODE(STORE_INCREMENT)
//OPCODE(FAST_INDEX_0) // a[0]
//OPCODE(FAST_INDEX_1) // a[i]
#endif #endif

View File

@ -10,7 +10,7 @@ constexpr const char* kTokens[] = {
"+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->",
"<<", ">>", "&", "|", "^", "?", "<<", ">>", "&", "|", "^", "?",
"==", "!=", ">=", "<=", "==", "!=", ">=", "<=",
"+=", "-=", "*=", "/=", "//=", "%=", "&=", "|=", "^=", "+=", "-=", "*=", "/=", "//=", "%=", "&=", "|=", "^=", "++", "--",
/** 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", "try", "except", "finally", "None", "in", "is", "and", "or", "not", "True", "False", "global", "try", "except", "finally",

View File

@ -27,6 +27,12 @@ class VM {
{ {
case OP_NO_OP: break; // do nothing case OP_NO_OP: break; // do nothing
case OP_LOAD_CONST: frame->push(frame->co->consts[byte.arg]); break; case OP_LOAD_CONST: frame->push(frame->co->consts[byte.arg]); break;
case OP_STORE_INCREMENT:{
const BaseRef* r = PyRef_AS_C(frame->top());
i64 val = PyInt_AS_C(r->get(this, frame));
r->set(this, frame, PyInt(val+byte.arg));
frame->_pop();
} break;
case OP_LOAD_LAMBDA: { case OP_LOAD_LAMBDA: {
PyVar obj = frame->co->consts[byte.arg]; PyVar obj = frame->co->consts[byte.arg];
setattr(obj, __module__, frame->_module); setattr(obj, __module__, frame->_module);
@ -42,14 +48,20 @@ class VM {
auto& p = frame->co->names[byte.arg]; auto& p = frame->co->names[byte.arg];
NameRef(p).set(this, frame, frame->pop_value(this)); NameRef(p).set(this, frame, frame->pop_value(this));
} break; } break;
case OP_BUILD_ATTR_REF: { case OP_BUILD_ATTR: {
auto& attr = frame->co->names[byte.arg]; int name = byte.arg >> 1;
bool _rvalue = byte.arg % 2 == 1;
auto& attr = frame->co->names[name];
PyVar obj = frame->pop_value(this); PyVar obj = frame->pop_value(this);
frame->push(PyRef(AttrRef(obj, NameRef(attr)))); AttrRef ref = AttrRef(obj, NameRef(attr));
if(_rvalue) frame->push(ref.get(this, frame));
else frame->push(PyRef(ref));
} break; } break;
case OP_BUILD_INDEX_REF: { case OP_BUILD_INDEX: {
PyVar index = frame->pop_value(this); PyVar index = frame->pop_value(this);
frame->push(PyRef(IndexRef(frame->pop_value(this), index))); auto ref = IndexRef(frame->pop_value(this), index);
if(byte.arg == 0) frame->push(PyRef(ref));
else frame->push(ref.get(this, frame));
} break; } break;
case OP_STORE_REF: { case OP_STORE_REF: {
PyVar obj = frame->pop_value(this); PyVar obj = frame->pop_value(this);
@ -794,7 +806,7 @@ public:
template<typename P> template<typename P>
inline PyVarRef PyRef(P&& value) { inline PyVarRef PyRef(P&& value) {
static_assert(std::is_base_of<BaseRef, P>::value, "P should derive from BaseRef"); static_assert(std::is_base_of<BaseRef, std::remove_reference_t<P>>::value, "P should derive from BaseRef");
return new_object(tp_ref, std::forward<P>(value)); return new_object(tp_ref, std::forward<P>(value));
} }