mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
test ++
/--
This commit is contained in:
parent
b6bb543c84
commit
f076bf4310
@ -1,6 +1,8 @@
|
||||
UPPER_BOUND = 5000000
|
||||
PREFIX = 32338
|
||||
|
||||
exit(0)
|
||||
|
||||
class Node:
|
||||
def __init__(self):
|
||||
self.children = {}
|
||||
|
@ -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)
|
@ -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/'
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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{
|
||||
|
@ -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
|
@ -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",
|
||||
|
24
src/vm.h
24
src/vm.h
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user