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
PREFIX = 32338
exit(0)
class Node:
def __init__(self):
self.children = {}

View File

@ -1,4 +1,30 @@
import random
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):
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':
return os.system("pocketpy.exe " + filepath) == 0
else:
@ -16,7 +23,7 @@ def test_dir(path):
if not filename.endswith('.py'):
continue
filepath = os.path.join(path, filename)
print("> " + filepath)
print("> " + filepath, flush=True)
if path == 'benchmarks/':
_0 = time.time()
@ -30,7 +37,7 @@ def test_dir(path):
if not test_file(filepath): exit(1)
if len(sys.argv) == 2:
assert sys.argv[1] == 'benchmark'
assert 'benchmark' in sys.argv[1]
d = 'benchmarks/'
else:
d = 'tests/'

View File

@ -73,6 +73,8 @@ public:
rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("@str")] = { METHOD(exprLiteral), 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(exprAssign), PREC_ASSIGNMENT };
rules[TK("+=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT };
@ -225,7 +227,12 @@ private:
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 '>': {
if(parser->matchchar('=')) parser->set_next_token(TK(">="));
else if(parser->matchchar('>')) parser->set_next_token(TK(">>"));
@ -241,6 +248,7 @@ private:
case '-': {
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("-"));
return;
}
@ -456,6 +464,16 @@ private:
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() {
TokenIndex op = parser->prev.type;
parse_expression((Precedence)(rules[op].precedence + 1));
@ -626,7 +644,8 @@ __LISTCOMP:
consume(TK("@id"));
const Str& name = parser->prev.str();
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]
@ -655,7 +674,8 @@ __LISTCOMP:
consume(TK("]"));
}
}
emit(OP_BUILD_INDEX_REF);
emit(OP_BUILD_INDEX, (int)co()->_rvalue);
}
void exprValue() {
@ -730,7 +750,7 @@ __LISTCOMP:
consume(TK("@id"));
Token tkname = parser->prev;
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"))) {
consume(TK("@id"));
tkname = parser->prev;
@ -923,7 +943,7 @@ __LISTCOMP:
consume_end_stmt();
// If last op is not an assignment, pop the result.
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);
emit(OP_POP_TOP, -1, true);
}

View File

@ -113,7 +113,7 @@ namespace pkpy {
inline static void call(int* counter) {
PyObject* obj = (PyObject*)(counter + 1);
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();
free(counter);
}else{

View File

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

View File

@ -10,7 +10,7 @@ constexpr const char* kTokens[] = {
"+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->",
"<<", ">>", "&", "|", "^", "?",
"==", "!=", ">=", "<=",
"+=", "-=", "*=", "/=", "//=", "%=", "&=", "|=", "^=",
"+=", "-=", "*=", "/=", "//=", "%=", "&=", "|=", "^=", "++", "--",
/** KW_BEGIN **/
"class", "import", "as", "def", "lambda", "pass", "del", "from", "with",
"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_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: {
PyVar obj = frame->co->consts[byte.arg];
setattr(obj, __module__, frame->_module);
@ -42,14 +48,20 @@ class VM {
auto& p = frame->co->names[byte.arg];
NameRef(p).set(this, frame, frame->pop_value(this));
} break;
case OP_BUILD_ATTR_REF: {
auto& attr = frame->co->names[byte.arg];
case OP_BUILD_ATTR: {
int name = byte.arg >> 1;
bool _rvalue = byte.arg % 2 == 1;
auto& attr = frame->co->names[name];
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;
case OP_BUILD_INDEX_REF: {
case OP_BUILD_INDEX: {
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;
case OP_STORE_REF: {
PyVar obj = frame->pop_value(this);
@ -794,7 +806,7 @@ public:
template<typename P>
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));
}