From a67b59f4cb34d1c47c2a4d24400f21de5de08ef5 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 11 Dec 2022 04:58:45 +0800 Subject: [PATCH] up --- plugins/flutter/CHANGELOG.md | 6 +- plugins/flutter/pubspec.yaml | 2 +- plugins/flutter/src/pocketpy.h | 291 +++++++++--------- plugins/godot/godot-cpp | 2 +- .../com.bl.pocketpy/Plugins/iOS/pocketpy.h | 287 ++++++++--------- src/compiler.h | 2 +- 6 files changed, 298 insertions(+), 292 deletions(-) diff --git a/plugins/flutter/CHANGELOG.md b/plugins/flutter/CHANGELOG.md index 27ec326f..de50bbed 100644 --- a/plugins/flutter/CHANGELOG.md +++ b/plugins/flutter/CHANGELOG.md @@ -23,4 +23,8 @@ The initial version. Hello, world! + Fix some bugs about compile error + Fix a bug for jsonify `nan` or `inf` + Add `math.isnan` and `math.isinf` -+ Fix a bug of `__checkType` \ No newline at end of file ++ Fix a bug of `__checkType` + +## 0.5.0+1 + ++ Fix a bug on Windows \ No newline at end of file diff --git a/plugins/flutter/pubspec.yaml b/plugins/flutter/pubspec.yaml index 277964c4..47c0fef7 100644 --- a/plugins/flutter/pubspec.yaml +++ b/plugins/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: pocketpy description: A lightweight Python interpreter for game engines. -version: 0.4.8+6 +version: 0.5.0+1 homepage: https://pocketpy.dev repository: https://github.com/blueloveth/pocketpy diff --git a/plugins/flutter/src/pocketpy.h b/plugins/flutter/src/pocketpy.h index c821b4f4..22675ce8 100644 --- a/plugins/flutter/src/pocketpy.h +++ b/plugins/flutter/src/pocketpy.h @@ -37,7 +37,7 @@ #define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!"); #endif -#define PK_VERSION "0.4.8" +#define PK_VERSION "0.5.0" //#define PKPY_NO_TYPE_CHECK //#define PKPY_NO_INDEX_CHECK @@ -2277,7 +2277,7 @@ private: struct PyObject; typedef pkpy::shared_ptr PyVar; typedef PyVar PyVarOrNull; -typedef PyVar VarRef; +typedef PyVar PyVarRef; class PyVarList: public std::vector { PyVar& at(size_t) = delete; @@ -2410,6 +2410,10 @@ namespace pkpy { return _args[i]; } + inline const PyVar& _index(uint8_t i) const { + return _args[i]; + } + // overload = for && ArgList& operator=(ArgList&& other){ if(this != &other){ @@ -2992,7 +2996,7 @@ typedef int64_t _Int; typedef double _Float; struct CodeObject; -struct BasePointer; +struct BaseRef; class VM; class Frame; @@ -3045,7 +3049,7 @@ protected: public: virtual PyVar next() = 0; virtual bool hasNext() = 0; - VarRef var; + PyVarRef var; BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {} virtual ~BaseIterator() = default; }; @@ -3447,11 +3451,11 @@ struct Parser { class Frame; -struct BasePointer { +struct BaseRef { virtual PyVar get(VM*, Frame*) const = 0; virtual void set(VM*, Frame*, PyVar) const = 0; virtual void del(VM*, Frame*) const = 0; - virtual ~BasePointer() = default; + virtual ~BaseRef() = default; }; enum NameScope { @@ -3460,49 +3464,49 @@ enum NameScope { NAME_ATTR = 2, }; -struct NamePointer : BasePointer { +struct NameRef : BaseRef { const std::pair<_Str, NameScope>* pair; - NamePointer(const std::pair<_Str, NameScope>* pair) : pair(pair) {} + NameRef(const std::pair<_Str, NameScope>* pair) : pair(pair) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct AttrPointer : BasePointer { +struct AttrRef : BaseRef { mutable PyVar obj; - const NamePointer attr; - AttrPointer(PyVar obj, const NamePointer attr) : obj(obj), attr(attr) {} + const NameRef attr; + AttrRef(PyVar obj, const NameRef attr) : obj(obj), attr(attr) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct IndexPointer : BasePointer { +struct IndexRef : BaseRef { mutable PyVar obj; PyVar index; - IndexPointer(PyVar obj, PyVar index) : obj(obj), index(index) {} + IndexRef(PyVar obj, PyVar index) : obj(obj), index(index) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct CompoundPointer : BasePointer { +struct TupleRef : BaseRef { PyVarList varRefs; - CompoundPointer(const PyVarList& varRefs) : varRefs(varRefs) {} - CompoundPointer(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {} + TupleRef(const PyVarList& varRefs) : varRefs(varRefs) {} + TupleRef(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct UserPointer : BasePointer { - VarRef p; +struct UserPointer : BaseRef { + PyVarRef p; uint64_t f_id; - UserPointer(VarRef p, uint64_t f_id) : p(p), f_id(f_id) {} + UserPointer(PyVarRef p, uint64_t f_id) : p(p), f_id(f_id) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; @@ -3563,13 +3567,13 @@ OPCODE(RAISE_ERROR) OPCODE(STORE_FUNCTION) OPCODE(BUILD_CLASS) -OPCODE(LOAD_NAME_PTR) // no arg -OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr -OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr] -OPCODE(STORE_NAME_PTR) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack -OPCODE(STORE_PTR) // no arg, [ptr, expr] -> *ptr = expr -OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr -OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr +OPCODE(LOAD_NAME_REF) // no arg +OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr +OPCODE(BUILD_INDEX_REF) // no arg, [ptr, expr] -> (*ptr)[expr] +OPCODE(STORE_NAME_REF) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack +OPCODE(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr +OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr +OPCODE(BUILD_ATTR_REF_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr OPCODE(BUILD_SMART_TUPLE) // if all elements are pointers, build a compound pointer, otherwise build a tuple OPCODE(BUILD_STRING) // arg is the expr count, build a string from the top of the stack @@ -3638,13 +3642,13 @@ OPCODE(RAISE_ERROR) OPCODE(STORE_FUNCTION) OPCODE(BUILD_CLASS) -OPCODE(LOAD_NAME_PTR) // no arg -OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr -OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr] -OPCODE(STORE_NAME_PTR) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack -OPCODE(STORE_PTR) // no arg, [ptr, expr] -> *ptr = expr -OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr -OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr +OPCODE(LOAD_NAME_REF) // no arg +OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr +OPCODE(BUILD_INDEX_REF) // no arg, [ptr, expr] -> (*ptr)[expr] +OPCODE(STORE_NAME_REF) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack +OPCODE(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr +OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr +OPCODE(BUILD_ATTR_REF_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr OPCODE(BUILD_SMART_TUPLE) // if all elements are pointers, build a compound pointer, otherwise build a tuple OPCODE(BUILD_STRING) // arg is the expr count, build a string from the top of the stack @@ -3934,48 +3938,48 @@ protected: setAttr(obj, __module__, frame->_module); frame->push(obj); } break; - case OP_LOAD_NAME_PTR: { - frame->push(PyPointer(NamePointer( + case OP_LOAD_NAME_REF: { + frame->push(PyRef(NameRef( &(frame->code->co_names[byte.arg]) ))); } break; - case OP_STORE_NAME_PTR: { + case OP_STORE_NAME_REF: { const auto& p = frame->code->co_names[byte.arg]; - NamePointer(&p).set(this, frame, frame->popValue(this)); + NameRef(&p).set(this, frame, frame->popValue(this)); } break; - case OP_BUILD_ATTR_PTR: { + case OP_BUILD_ATTR_REF: { const auto& attr = frame->code->co_names[byte.arg]; PyVar obj = frame->popValue(this); - frame->push(PyPointer(AttrPointer(obj, NamePointer(&attr)))); + frame->push(PyRef(AttrRef(obj, NameRef(&attr)))); } break; - case OP_BUILD_ATTR_PTR_PTR: { + case OP_BUILD_ATTR_REF_PTR: { const auto& attr = frame->code->co_names[byte.arg]; PyVar obj = frame->popValue(this); __checkType(obj, _tp_user_pointer); - const VarRef& var = UNION_GET(VarRef, obj); - auto p = PyPointer_AS_C(var); - frame->push(PyPointer(AttrPointer(p->get(this, frame), &attr))); + const PyVarRef& var = UNION_GET(PyVarRef, obj); + auto p = PyRef_AS_C(var); + frame->push(PyRef(AttrRef(p->get(this, frame), &attr))); } break; - case OP_BUILD_INDEX_PTR: { + case OP_BUILD_INDEX_REF: { PyVar index = frame->popValue(this); - VarRef obj = frame->popValue(this); - frame->push(PyPointer(IndexPointer(obj, index))); + PyVarRef obj = frame->popValue(this); + frame->push(PyRef(IndexRef(obj, index))); } break; - case OP_STORE_PTR: { + case OP_STORE_REF: { PyVar obj = frame->popValue(this); - VarRef r = frame->__pop(); - PyPointer_AS_C(r)->set(this, frame, std::move(obj)); + PyVarRef r = frame->__pop(); + PyRef_AS_C(r)->set(this, frame, std::move(obj)); } break; - case OP_DELETE_PTR: { - VarRef r = frame->__pop(); - PyPointer_AS_C(r)->del(this, frame); + case OP_DELETE_REF: { + PyVarRef r = frame->__pop(); + PyRef_AS_C(r)->del(this, frame); } break; case OP_BUILD_SMART_TUPLE: { pkpy::ArgList items = frame->__popNReversed(byte.arg); bool done = false; for(int i=0; iisType(_tp_pointer)) { + if(!items[i]->isType(_tp_ref)) { done = true; PyVarList values(items.size()); for(int i=0; ipush(PyPointer(CompoundPointer(items.toList()))); + frame->push(PyRef(TupleRef(items.toList()))); } break; case OP_BUILD_STRING: { @@ -4037,20 +4041,23 @@ protected: case OP_POP_TOP: frame->popValue(this); break; case OP_BINARY_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); - frame->push(fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args))); + frame->push( + fastCall(BINARY_SPECIAL_METHODS[byte.arg], + frame->popNValuesReversed(this, 2)) + ); } break; case OP_BITWISE_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); - frame->push(fastCall(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args))); + frame->push( + fastCall(BITWISE_SPECIAL_METHODS[byte.arg], + frame->popNValuesReversed(this, 2)) + ); } break; case OP_COMPARE_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); // for __ne__ we use the negation of __eq__ int op = byte.arg == 3 ? 2 : byte.arg; - PyVar res = fastCall(CMP_SPECIAL_METHODS[op], std::move(args)); + PyVar res = fastCall(CMP_SPECIAL_METHODS[op], frame->popNValuesReversed(this, 2)); if(op != byte.arg) res = PyBool(!PyBool_AS_C(res)); frame->push(std::move(res)); } break; @@ -4081,11 +4088,11 @@ protected: case OP_UNARY_REF: { // _pointer to pointer - VarRef obj = frame->__pop(); - __checkType(obj, _tp_pointer); + PyVarRef obj = frame->__pop(); + __checkType(obj, _tp_ref); frame->push(newObject( _tp_user_pointer, - PyPointer(UserPointer(obj, frame->id)) + PyRef(UserPointer(obj, frame->id)) )); } break; case OP_UNARY_DEREF: @@ -4093,7 +4100,7 @@ protected: // pointer to _pointer PyVar obj = frame->popValue(this); __checkType(obj, _tp_user_pointer); - frame->push(UNION_GET(VarRef, obj)); + frame->push(UNION_GET(PyVarRef, obj)); } break; case OP_POP_JUMP_IF_FALSE: if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg); @@ -4145,11 +4152,11 @@ protected: case OP_GOTO: { PyVar obj = frame->popValue(this); const _Str& label = PyStr_AS_C(obj); - auto it = frame->code->co_labels.find(label); - if(it == frame->code->co_labels.end()){ + int* target = frame->code->co_labels.try_get(label); + if(target == nullptr){ _error("KeyError", "label '" + label + "' not found"); } - frame->safeJump(it->second); + frame->safeJump(*target); } break; case OP_GET_ITER: { @@ -4157,8 +4164,8 @@ protected: PyVarOrNull iter_fn = getAttr(obj, __iter__, false); if(iter_fn != nullptr){ PyVar tmp = call(iter_fn, pkpy::oneArg(obj)); - VarRef var = frame->__pop(); - __checkType(var, _tp_pointer); + PyVarRef var = frame->__pop(); + __checkType(var, _tp_ref); PyIter_AS_C(tmp)->var = var; frame->push(std::move(tmp)); }else{ @@ -4171,7 +4178,7 @@ protected: // __top() must be PyIter, so no need to __deref() auto& it = PyIter_AS_C(frame->__top()); if(it->hasNext()){ - PyPointer_AS_C(it->var)->set(this, frame, it->next()); + PyRef_AS_C(it->var)->set(this, frame, it->next()); } else{ frame->safeJump(byte.arg); @@ -4321,8 +4328,8 @@ public: PyVar fastCall(const _Str& name, pkpy::ArgList&& args){ PyObject* cls = args[0]->_type.get(); while(cls != None.get()) { - auto it = cls->attribs.find(name); - if(it != cls->attribs.end()) return call(it->second, std::move(args)); + PyVar* val = cls->attribs.try_get(name); + if(val != nullptr) return call(*val, std::move(args)); cls = cls->attribs[__base__].get(); } attributeError(args[0], name); @@ -4412,7 +4419,7 @@ public: for(int i=0; ikwArgs.find(key) == fn->kwArgs.end()){ + if(!fn->kwArgs.contains(key)){ typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()"); } const PyVar& val = kwargs[i+1]; @@ -4425,8 +4432,8 @@ public: locals[key] = val; } - auto it_m = (*callable)->attribs.find(__module__); - PyVar _module = it_m != (*callable)->attribs.end() ? it_m->second : topFrame()->_module; + PyVar* it_m = (*callable)->attribs.try_get(__module__); + PyVar _module = it_m != nullptr ? *it_m : topFrame()->_module; if(opCall){ __pushNewFrame(fn->code, _module, std::move(locals)); return __py2py_call_signal; @@ -4507,9 +4514,9 @@ public: } template - inline PyVar newObject(PyVar type, T&& _value) { + inline PyVar newObject(PyVar type, T _value) { __checkType(type, _tp_type); - return pkpy::make_shared>(std::forward(_value), type); + return pkpy::make_shared>(_value, type); } PyVar newModule(_Str name) { @@ -4661,19 +4668,19 @@ public: PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str; PyVar _tp_list, _tp_tuple; PyVar _tp_function, _tp_native_function, _tp_native_iterator, _tp_bounded_method; - PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer; + PyVar _tp_slice, _tp_range, _tp_module, _tp_ref; PyVar _tp_user_pointer, _tp_super; template - inline VarRef PyPointer(P value) { - static_assert(std::is_base_of::value, "P should derive from BasePointer"); - return newObject(_tp_pointer, value); + inline PyVarRef PyRef(P&& value) { + static_assert(std::is_base_of::value, "P should derive from BaseRef"); + return newObject(_tp_ref, std::forward

(value)); } - inline const BasePointer* PyPointer_AS_C(const PyVar& obj) + inline const BaseRef* PyRef_AS_C(const PyVar& obj) { - if(!obj->isType(_tp_pointer)) typeError("expected an l-value"); - return (const BasePointer*)(obj->value()); + if(!obj->isType(_tp_ref)) typeError("expected an l-value"); + return (const BaseRef*)(obj->value()); } __DEF_PY_AS_C(Int, _Int, _tp_int) @@ -4713,7 +4720,7 @@ public: _tp_slice = newClassType("slice"); _tp_range = newClassType("range"); _tp_module = newClassType("module"); - _tp_pointer = newClassType("_pointer"); + _tp_ref = newClassType("_pointer"); _tp_user_pointer = newClassType("pointer"); newClassType("NoneType"); @@ -4848,18 +4855,18 @@ public: /***** Pointers' Impl *****/ -PyVar NamePointer::get(VM* vm, Frame* frame) const{ - auto it = frame->f_locals.find(pair->first); - if(it != frame->f_locals.end()) return it->second; - it = frame->f_globals().find(pair->first); - if(it != frame->f_globals().end()) return it->second; - it = vm->builtins->attribs.find(pair->first); - if(it != vm->builtins->attribs.end()) return it->second; +PyVar NameRef::get(VM* vm, Frame* frame) const{ + PyVar* val = frame->f_locals.try_get(pair->first); + if(val) return *val; + val = frame->f_globals().try_get(pair->first); + if(val) return *val; + val = vm->builtins->attribs.try_get(pair->first); + if(val) return *val; vm->nameError(pair->first); return nullptr; } -void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{ +void NameRef::set(VM* vm, Frame* frame, PyVar val) const{ switch(pair->second) { case NAME_LOCAL: frame->f_locals[pair->first] = std::move(val); break; case NAME_GLOBAL: @@ -4874,7 +4881,7 @@ void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{ } } -void NamePointer::del(VM* vm, Frame* frame) const{ +void NameRef::del(VM* vm, Frame* frame) const{ switch(pair->second) { case NAME_LOCAL: { if(frame->f_locals.count(pair->first) > 0){ @@ -4899,39 +4906,39 @@ void NamePointer::del(VM* vm, Frame* frame) const{ } } -PyVar AttrPointer::get(VM* vm, Frame* frame) const{ +PyVar AttrRef::get(VM* vm, Frame* frame) const{ return vm->getAttr(obj, attr.pair->first); } -void AttrPointer::set(VM* vm, Frame* frame, PyVar val) const{ +void AttrRef::set(VM* vm, Frame* frame, PyVar val) const{ vm->setAttr(obj, attr.pair->first, val); } -void AttrPointer::del(VM* vm, Frame* frame) const{ +void AttrRef::del(VM* vm, Frame* frame) const{ vm->typeError("cannot delete attribute"); } -PyVar IndexPointer::get(VM* vm, Frame* frame) const{ +PyVar IndexRef::get(VM* vm, Frame* frame) const{ return vm->call(obj, __getitem__, pkpy::oneArg(index)); } -void IndexPointer::set(VM* vm, Frame* frame, PyVar val) const{ +void IndexRef::set(VM* vm, Frame* frame, PyVar val) const{ vm->call(obj, __setitem__, pkpy::twoArgs(index, val)); } -void IndexPointer::del(VM* vm, Frame* frame) const{ +void IndexRef::del(VM* vm, Frame* frame) const{ vm->call(obj, __delitem__, pkpy::oneArg(index)); } -PyVar CompoundPointer::get(VM* vm, Frame* frame) const{ +PyVar TupleRef::get(VM* vm, Frame* frame) const{ PyVarList args(varRefs.size()); for (int i = 0; i < varRefs.size(); i++) { - args[i] = vm->PyPointer_AS_C(varRefs[i])->get(vm, frame); + args[i] = vm->PyRef_AS_C(varRefs[i])->get(vm, frame); } return vm->PyTuple(args); } -void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{ +void TupleRef::set(VM* vm, Frame* frame, PyVar val) const{ if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){ vm->typeError("only tuple or list can be unpacked"); } @@ -4939,24 +4946,24 @@ void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{ if(args.size() > varRefs.size()) vm->valueError("too many values to unpack"); if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack"); for (int i = 0; i < varRefs.size(); i++) { - vm->PyPointer_AS_C(varRefs[i])->set(vm, frame, args[i]); + vm->PyRef_AS_C(varRefs[i])->set(vm, frame, args[i]); } } -void CompoundPointer::del(VM* vm, Frame* frame) const{ - for (auto& r : varRefs) vm->PyPointer_AS_C(r)->del(vm, frame); +void TupleRef::del(VM* vm, Frame* frame) const{ + for (auto& r : varRefs) vm->PyRef_AS_C(r)->del(vm, frame); } PyVar UserPointer::get(VM* vm, Frame* frame) const{ frame = vm->__findFrame(f_id); if(frame == nullptr) vm->nullPointerError(); - return vm->PyPointer_AS_C(p)->get(vm, frame); + return vm->PyRef_AS_C(p)->get(vm, frame); } void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{ frame = vm->__findFrame(f_id); if(frame == nullptr) vm->nullPointerError(); - vm->PyPointer_AS_C(p)->set(vm, frame, val); + vm->PyRef_AS_C(p)->set(vm, frame, val); } void UserPointer::del(VM* vm, Frame* frame) const{ @@ -4965,7 +4972,7 @@ void UserPointer::del(VM* vm, Frame* frame) const{ /***** Frame's Impl *****/ inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){ - if(v->isType(vm->_tp_pointer)) return vm->PyPointer_AS_C(v)->get(vm, this); + if(v->isType(vm->_tp_ref)) return vm->PyRef_AS_C(v)->get(vm, this); return v; } @@ -5336,7 +5343,7 @@ public: if(parser->matchChar('\'')) {eatString('\'', true); return;} if(parser->matchChar('"')) {eatString('"', true); return;} } - if (isdigit(c)) { + if (c >= '0' && c <= '9') { eatNumber(); return; } @@ -5464,7 +5471,7 @@ public: _TokenType op = parser->previous.type; if(op == TK("=")) { // a = (expr) EXPR_TUPLE(); - emitCode(OP_STORE_PTR); + emitCode(OP_STORE_REF); }else{ // a += (expr) -> a = a + (expr) // TODO: optimization is needed for inplace operators emitCode(OP_DUP_TOP); @@ -5477,7 +5484,7 @@ public: case TK("//="): emitCode(OP_BINARY_OP, 4); break; default: UNREACHABLE(); } - emitCode(OP_STORE_PTR); + emitCode(OP_STORE_REF); } } @@ -5662,21 +5669,21 @@ __LISTCOMP: tkname.str(), codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL ); - emitCode(OP_LOAD_NAME_PTR, index); + emitCode(OP_LOAD_NAME_REF, index); } void exprAttrib() { consume(TK("@id")); const _Str& name = parser->previous.str(); int index = getCode()->addName(name, NAME_ATTR); - emitCode(OP_BUILD_ATTR_PTR, index); + emitCode(OP_BUILD_ATTR_REF, index); } void exprAttribPtr(){ consume(TK("@id")); const _Str& name = parser->previous.str(); int index = getCode()->addName(name, NAME_ATTR); - emitCode(OP_BUILD_ATTR_PTR_PTR, index); + emitCode(OP_BUILD_ATTR_REF_PTR, index); } // [:], [:b] @@ -5706,7 +5713,7 @@ __LISTCOMP: } } - emitCode(OP_BUILD_INDEX_PTR); + emitCode(OP_BUILD_INDEX_REF); } void exprValue() { @@ -5773,7 +5780,7 @@ __LISTCOMP: tkmodule = parser->previous; } int index = getCode()->addName(tkmodule.str(), NAME_GLOBAL); - emitCode(OP_STORE_NAME_PTR, index); + emitCode(OP_STORE_NAME_REF, index); } while (match(TK(","))); consumeEndStatement(); } @@ -5787,13 +5794,13 @@ __LISTCOMP: consume(TK("@id")); Token tkname = parser->previous; int index = getCode()->addName(tkname.str(), NAME_GLOBAL); - emitCode(OP_BUILD_ATTR_PTR, index); + emitCode(OP_BUILD_ATTR_REF, index); if (match(TK("as"))) { consume(TK("@id")); tkname = parser->previous; } index = getCode()->addName(tkname.str(), NAME_GLOBAL); - emitCode(OP_STORE_NAME_PTR, index); + emitCode(OP_STORE_NAME_REF, index); } while (match(TK(","))); emitCode(OP_POP_TOP); consumeEndStatement(); @@ -5916,11 +5923,11 @@ __LISTCOMP: tkname.str(), codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL ); - emitCode(OP_STORE_NAME_PTR, index); - emitCode(OP_LOAD_NAME_PTR, index); + emitCode(OP_STORE_NAME_REF, index); + emitCode(OP_LOAD_NAME_REF, index); emitCode(OP_WITH_ENTER); compileBlockBody(); - emitCode(OP_LOAD_NAME_PTR, index); + emitCode(OP_LOAD_NAME_REF, index); emitCode(OP_WITH_EXIT); } else if(match(TK("label"))){ if(mode() != EXEC_MODE) syntaxError("'label' is only available in EXEC_MODE"); @@ -5942,7 +5949,7 @@ __LISTCOMP: consumeEndStatement(); } else if(match(TK("del"))){ EXPR(); - emitCode(OP_DELETE_PTR); + emitCode(OP_DELETE_REF); consumeEndStatement(); } else if(match(TK("global"))){ consume(TK("@id")); @@ -5956,7 +5963,7 @@ __LISTCOMP: // If last op is not an assignment, pop the result. uint8_t lastOp = getCode()->co_code.back().op; - if( lastOp != OP_STORE_NAME_PTR && lastOp != OP_STORE_PTR){ + if( lastOp != OP_STORE_NAME_REF && lastOp != OP_STORE_REF){ if(mode()==SINGLE_MODE && parser->indents.top() == 0){ emitCode(OP_PRINT_EXPR); } @@ -5980,7 +5987,7 @@ __LISTCOMP: isCompilingClass = false; if(superClsNameIdx == -1) emitCode(OP_LOAD_NONE); - else emitCode(OP_LOAD_NAME_PTR, superClsNameIdx); + else emitCode(OP_LOAD_NAME_REF, superClsNameIdx); emitCode(OP_BUILD_CLASS, clsNameIdx); } @@ -6207,13 +6214,13 @@ __NOT_ENOUGH_LINES: #define BIND_NUM_ARITH_OPT(name, op) \ - _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ + _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ if(!vm->isIntOrFloat(args[0], args[1])) \ - vm->typeError("unsupported operand type(s) for " #op ); \ - if(args[0]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){ \ - return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ + vm->typeError("unsupported operand type(s) for " #op ); \ + if(args._index(0)->isType(vm->_tp_int) && args._index(1)->isType(vm->_tp_int)){ \ + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ }else{ \ - return vm->PyFloat(vm->numToFloat(args[0]) op vm->numToFloat(args[1])); \ + return vm->PyFloat(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \ } \ }); @@ -6223,7 +6230,7 @@ __NOT_ENOUGH_LINES: if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \ vm->typeError("unsupported operand type(s) for " #op ); \ } \ - return vm->PyBool(vm->numToFloat(args[0]) op vm->numToFloat(args[1])); \ + return vm->PyBool(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \ }); @@ -6407,17 +6414,17 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) { if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) vm->typeError("unsupported operand type(s) for " "//" ); - _Int rhs = vm->PyInt_AS_C(args[1]); + _Int rhs = vm->PyInt_AS_C(args._index(1)); if(rhs == 0) vm->zeroDivisionError(); - return vm->PyInt(vm->PyInt_AS_C(args[0]) / rhs); + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) / rhs); }); _vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) { if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) vm->typeError("unsupported operand type(s) for " "%" ); - _Int rhs = vm->PyInt_AS_C(args[1]); + _Int rhs = vm->PyInt_AS_C(args._index(1)); if(rhs == 0) vm->zeroDivisionError(); - return vm->PyInt(vm->PyInt_AS_C(args[0]) % rhs); + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) % rhs); }); _vm->bindMethod("int", "__repr__", [](VM* vm, const pkpy::ArgList& args) { @@ -6429,10 +6436,10 @@ void __initializeBuiltinFunctions(VM* _vm) { }); #define __INT_BITWISE_OP(name,op) \ - _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ - if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ - vm->typeError("unsupported operand type(s) for " #op ); \ - return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ + _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ + if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ + vm->typeError("unsupported operand type(s) for " #op ); \ + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ }); __INT_BITWISE_OP(__lshift__, <<) @@ -6443,12 +6450,6 @@ void __initializeBuiltinFunctions(VM* _vm) { #undef __INT_BITWISE_OP - _vm->bindMethod("int", "__xor__", [](VM* vm, const pkpy::ArgList& args) { - if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) - vm->typeError("unsupported operand type(s) for " "^" ); - return vm->PyInt(vm->PyInt_AS_C(args[0]) ^ vm->PyInt_AS_C(args[1])); - }); - /************ PyFloat ************/ _vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) { if(args.size() == 0) return vm->PyFloat(0.0); diff --git a/plugins/godot/godot-cpp b/plugins/godot/godot-cpp index eaeddb40..d8e7e998 160000 --- a/plugins/godot/godot-cpp +++ b/plugins/godot/godot-cpp @@ -1 +1 @@ -Subproject commit eaeddb40e8691f6fbc8419da1d4996583aef07a8 +Subproject commit d8e7e9986433707a21b796d510cccb6f098cf91c diff --git a/plugins/unity/com.bl.pocketpy/Plugins/iOS/pocketpy.h b/plugins/unity/com.bl.pocketpy/Plugins/iOS/pocketpy.h index bcad5d69..22675ce8 100644 --- a/plugins/unity/com.bl.pocketpy/Plugins/iOS/pocketpy.h +++ b/plugins/unity/com.bl.pocketpy/Plugins/iOS/pocketpy.h @@ -37,7 +37,7 @@ #define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!"); #endif -#define PK_VERSION "0.4.8" +#define PK_VERSION "0.5.0" //#define PKPY_NO_TYPE_CHECK //#define PKPY_NO_INDEX_CHECK @@ -2277,7 +2277,7 @@ private: struct PyObject; typedef pkpy::shared_ptr PyVar; typedef PyVar PyVarOrNull; -typedef PyVar VarRef; +typedef PyVar PyVarRef; class PyVarList: public std::vector { PyVar& at(size_t) = delete; @@ -2410,6 +2410,10 @@ namespace pkpy { return _args[i]; } + inline const PyVar& _index(uint8_t i) const { + return _args[i]; + } + // overload = for && ArgList& operator=(ArgList&& other){ if(this != &other){ @@ -2992,7 +2996,7 @@ typedef int64_t _Int; typedef double _Float; struct CodeObject; -struct BasePointer; +struct BaseRef; class VM; class Frame; @@ -3045,7 +3049,7 @@ protected: public: virtual PyVar next() = 0; virtual bool hasNext() = 0; - VarRef var; + PyVarRef var; BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {} virtual ~BaseIterator() = default; }; @@ -3447,11 +3451,11 @@ struct Parser { class Frame; -struct BasePointer { +struct BaseRef { virtual PyVar get(VM*, Frame*) const = 0; virtual void set(VM*, Frame*, PyVar) const = 0; virtual void del(VM*, Frame*) const = 0; - virtual ~BasePointer() = default; + virtual ~BaseRef() = default; }; enum NameScope { @@ -3460,49 +3464,49 @@ enum NameScope { NAME_ATTR = 2, }; -struct NamePointer : BasePointer { +struct NameRef : BaseRef { const std::pair<_Str, NameScope>* pair; - NamePointer(const std::pair<_Str, NameScope>* pair) : pair(pair) {} + NameRef(const std::pair<_Str, NameScope>* pair) : pair(pair) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct AttrPointer : BasePointer { +struct AttrRef : BaseRef { mutable PyVar obj; - const NamePointer attr; - AttrPointer(PyVar obj, const NamePointer attr) : obj(obj), attr(attr) {} + const NameRef attr; + AttrRef(PyVar obj, const NameRef attr) : obj(obj), attr(attr) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct IndexPointer : BasePointer { +struct IndexRef : BaseRef { mutable PyVar obj; PyVar index; - IndexPointer(PyVar obj, PyVar index) : obj(obj), index(index) {} + IndexRef(PyVar obj, PyVar index) : obj(obj), index(index) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct CompoundPointer : BasePointer { +struct TupleRef : BaseRef { PyVarList varRefs; - CompoundPointer(const PyVarList& varRefs) : varRefs(varRefs) {} - CompoundPointer(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {} + TupleRef(const PyVarList& varRefs) : varRefs(varRefs) {} + TupleRef(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; void del(VM* vm, Frame* frame) const; }; -struct UserPointer : BasePointer { - VarRef p; +struct UserPointer : BaseRef { + PyVarRef p; uint64_t f_id; - UserPointer(VarRef p, uint64_t f_id) : p(p), f_id(f_id) {} + UserPointer(PyVarRef p, uint64_t f_id) : p(p), f_id(f_id) {} PyVar get(VM* vm, Frame* frame) const; void set(VM* vm, Frame* frame, PyVar val) const; @@ -3563,13 +3567,13 @@ OPCODE(RAISE_ERROR) OPCODE(STORE_FUNCTION) OPCODE(BUILD_CLASS) -OPCODE(LOAD_NAME_PTR) // no arg -OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr -OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr] -OPCODE(STORE_NAME_PTR) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack -OPCODE(STORE_PTR) // no arg, [ptr, expr] -> *ptr = expr -OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr -OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr +OPCODE(LOAD_NAME_REF) // no arg +OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr +OPCODE(BUILD_INDEX_REF) // no arg, [ptr, expr] -> (*ptr)[expr] +OPCODE(STORE_NAME_REF) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack +OPCODE(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr +OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr +OPCODE(BUILD_ATTR_REF_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr OPCODE(BUILD_SMART_TUPLE) // if all elements are pointers, build a compound pointer, otherwise build a tuple OPCODE(BUILD_STRING) // arg is the expr count, build a string from the top of the stack @@ -3638,13 +3642,13 @@ OPCODE(RAISE_ERROR) OPCODE(STORE_FUNCTION) OPCODE(BUILD_CLASS) -OPCODE(LOAD_NAME_PTR) // no arg -OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr -OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr] -OPCODE(STORE_NAME_PTR) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack -OPCODE(STORE_PTR) // no arg, [ptr, expr] -> *ptr = expr -OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr -OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr +OPCODE(LOAD_NAME_REF) // no arg +OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr +OPCODE(BUILD_INDEX_REF) // no arg, [ptr, expr] -> (*ptr)[expr] +OPCODE(STORE_NAME_REF) // arg for the name_ptr, [expr], directly store to the name_ptr without pushing it to the stack +OPCODE(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr +OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr +OPCODE(BUILD_ATTR_REF_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_ptr OPCODE(BUILD_SMART_TUPLE) // if all elements are pointers, build a compound pointer, otherwise build a tuple OPCODE(BUILD_STRING) // arg is the expr count, build a string from the top of the stack @@ -3934,48 +3938,48 @@ protected: setAttr(obj, __module__, frame->_module); frame->push(obj); } break; - case OP_LOAD_NAME_PTR: { - frame->push(PyPointer(NamePointer( + case OP_LOAD_NAME_REF: { + frame->push(PyRef(NameRef( &(frame->code->co_names[byte.arg]) ))); } break; - case OP_STORE_NAME_PTR: { + case OP_STORE_NAME_REF: { const auto& p = frame->code->co_names[byte.arg]; - NamePointer(&p).set(this, frame, frame->popValue(this)); + NameRef(&p).set(this, frame, frame->popValue(this)); } break; - case OP_BUILD_ATTR_PTR: { + case OP_BUILD_ATTR_REF: { const auto& attr = frame->code->co_names[byte.arg]; PyVar obj = frame->popValue(this); - frame->push(PyPointer(AttrPointer(obj, NamePointer(&attr)))); + frame->push(PyRef(AttrRef(obj, NameRef(&attr)))); } break; - case OP_BUILD_ATTR_PTR_PTR: { + case OP_BUILD_ATTR_REF_PTR: { const auto& attr = frame->code->co_names[byte.arg]; PyVar obj = frame->popValue(this); __checkType(obj, _tp_user_pointer); - const VarRef& var = UNION_GET(VarRef, obj); - auto p = PyPointer_AS_C(var); - frame->push(PyPointer(AttrPointer(p->get(this, frame), &attr))); + const PyVarRef& var = UNION_GET(PyVarRef, obj); + auto p = PyRef_AS_C(var); + frame->push(PyRef(AttrRef(p->get(this, frame), &attr))); } break; - case OP_BUILD_INDEX_PTR: { + case OP_BUILD_INDEX_REF: { PyVar index = frame->popValue(this); - VarRef obj = frame->popValue(this); - frame->push(PyPointer(IndexPointer(obj, index))); + PyVarRef obj = frame->popValue(this); + frame->push(PyRef(IndexRef(obj, index))); } break; - case OP_STORE_PTR: { + case OP_STORE_REF: { PyVar obj = frame->popValue(this); - VarRef r = frame->__pop(); - PyPointer_AS_C(r)->set(this, frame, std::move(obj)); + PyVarRef r = frame->__pop(); + PyRef_AS_C(r)->set(this, frame, std::move(obj)); } break; - case OP_DELETE_PTR: { - VarRef r = frame->__pop(); - PyPointer_AS_C(r)->del(this, frame); + case OP_DELETE_REF: { + PyVarRef r = frame->__pop(); + PyRef_AS_C(r)->del(this, frame); } break; case OP_BUILD_SMART_TUPLE: { pkpy::ArgList items = frame->__popNReversed(byte.arg); bool done = false; for(int i=0; iisType(_tp_pointer)) { + if(!items[i]->isType(_tp_ref)) { done = true; PyVarList values(items.size()); for(int i=0; ipush(PyPointer(CompoundPointer(items.toList()))); + frame->push(PyRef(TupleRef(items.toList()))); } break; case OP_BUILD_STRING: { @@ -4037,20 +4041,23 @@ protected: case OP_POP_TOP: frame->popValue(this); break; case OP_BINARY_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); - frame->push(fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args))); + frame->push( + fastCall(BINARY_SPECIAL_METHODS[byte.arg], + frame->popNValuesReversed(this, 2)) + ); } break; case OP_BITWISE_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); - frame->push(fastCall(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args))); + frame->push( + fastCall(BITWISE_SPECIAL_METHODS[byte.arg], + frame->popNValuesReversed(this, 2)) + ); } break; case OP_COMPARE_OP: { - pkpy::ArgList args = frame->popNValuesReversed(this, 2); // for __ne__ we use the negation of __eq__ int op = byte.arg == 3 ? 2 : byte.arg; - PyVar res = fastCall(CMP_SPECIAL_METHODS[op], std::move(args)); + PyVar res = fastCall(CMP_SPECIAL_METHODS[op], frame->popNValuesReversed(this, 2)); if(op != byte.arg) res = PyBool(!PyBool_AS_C(res)); frame->push(std::move(res)); } break; @@ -4081,11 +4088,11 @@ protected: case OP_UNARY_REF: { // _pointer to pointer - VarRef obj = frame->__pop(); - __checkType(obj, _tp_pointer); + PyVarRef obj = frame->__pop(); + __checkType(obj, _tp_ref); frame->push(newObject( _tp_user_pointer, - PyPointer(UserPointer(obj, frame->id)) + PyRef(UserPointer(obj, frame->id)) )); } break; case OP_UNARY_DEREF: @@ -4093,7 +4100,7 @@ protected: // pointer to _pointer PyVar obj = frame->popValue(this); __checkType(obj, _tp_user_pointer); - frame->push(UNION_GET(VarRef, obj)); + frame->push(UNION_GET(PyVarRef, obj)); } break; case OP_POP_JUMP_IF_FALSE: if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg); @@ -4145,11 +4152,11 @@ protected: case OP_GOTO: { PyVar obj = frame->popValue(this); const _Str& label = PyStr_AS_C(obj); - auto it = frame->code->co_labels.find(label); - if(it == frame->code->co_labels.end()){ + int* target = frame->code->co_labels.try_get(label); + if(target == nullptr){ _error("KeyError", "label '" + label + "' not found"); } - frame->safeJump(it->second); + frame->safeJump(*target); } break; case OP_GET_ITER: { @@ -4157,8 +4164,8 @@ protected: PyVarOrNull iter_fn = getAttr(obj, __iter__, false); if(iter_fn != nullptr){ PyVar tmp = call(iter_fn, pkpy::oneArg(obj)); - VarRef var = frame->__pop(); - __checkType(var, _tp_pointer); + PyVarRef var = frame->__pop(); + __checkType(var, _tp_ref); PyIter_AS_C(tmp)->var = var; frame->push(std::move(tmp)); }else{ @@ -4171,7 +4178,7 @@ protected: // __top() must be PyIter, so no need to __deref() auto& it = PyIter_AS_C(frame->__top()); if(it->hasNext()){ - PyPointer_AS_C(it->var)->set(this, frame, it->next()); + PyRef_AS_C(it->var)->set(this, frame, it->next()); } else{ frame->safeJump(byte.arg); @@ -4321,8 +4328,8 @@ public: PyVar fastCall(const _Str& name, pkpy::ArgList&& args){ PyObject* cls = args[0]->_type.get(); while(cls != None.get()) { - auto it = cls->attribs.find(name); - if(it != cls->attribs.end()) return call(it->second, std::move(args)); + PyVar* val = cls->attribs.try_get(name); + if(val != nullptr) return call(*val, std::move(args)); cls = cls->attribs[__base__].get(); } attributeError(args[0], name); @@ -4412,7 +4419,7 @@ public: for(int i=0; ikwArgs.find(key) == fn->kwArgs.end()){ + if(!fn->kwArgs.contains(key)){ typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()"); } const PyVar& val = kwargs[i+1]; @@ -4425,8 +4432,8 @@ public: locals[key] = val; } - auto it_m = (*callable)->attribs.find(__module__); - PyVar _module = it_m != (*callable)->attribs.end() ? it_m->second : topFrame()->_module; + PyVar* it_m = (*callable)->attribs.try_get(__module__); + PyVar _module = it_m != nullptr ? *it_m : topFrame()->_module; if(opCall){ __pushNewFrame(fn->code, _module, std::move(locals)); return __py2py_call_signal; @@ -4661,19 +4668,19 @@ public: PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str; PyVar _tp_list, _tp_tuple; PyVar _tp_function, _tp_native_function, _tp_native_iterator, _tp_bounded_method; - PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer; + PyVar _tp_slice, _tp_range, _tp_module, _tp_ref; PyVar _tp_user_pointer, _tp_super; template - inline VarRef PyPointer(P value) { - static_assert(std::is_base_of::value, "P should derive from BasePointer"); - return newObject(_tp_pointer, value); + inline PyVarRef PyRef(P&& value) { + static_assert(std::is_base_of::value, "P should derive from BaseRef"); + return newObject(_tp_ref, std::forward

(value)); } - inline const BasePointer* PyPointer_AS_C(const PyVar& obj) + inline const BaseRef* PyRef_AS_C(const PyVar& obj) { - if(!obj->isType(_tp_pointer)) typeError("expected an l-value"); - return (const BasePointer*)(obj->value()); + if(!obj->isType(_tp_ref)) typeError("expected an l-value"); + return (const BaseRef*)(obj->value()); } __DEF_PY_AS_C(Int, _Int, _tp_int) @@ -4713,7 +4720,7 @@ public: _tp_slice = newClassType("slice"); _tp_range = newClassType("range"); _tp_module = newClassType("module"); - _tp_pointer = newClassType("_pointer"); + _tp_ref = newClassType("_pointer"); _tp_user_pointer = newClassType("pointer"); newClassType("NoneType"); @@ -4848,18 +4855,18 @@ public: /***** Pointers' Impl *****/ -PyVar NamePointer::get(VM* vm, Frame* frame) const{ - auto it = frame->f_locals.find(pair->first); - if(it != frame->f_locals.end()) return it->second; - it = frame->f_globals().find(pair->first); - if(it != frame->f_globals().end()) return it->second; - it = vm->builtins->attribs.find(pair->first); - if(it != vm->builtins->attribs.end()) return it->second; +PyVar NameRef::get(VM* vm, Frame* frame) const{ + PyVar* val = frame->f_locals.try_get(pair->first); + if(val) return *val; + val = frame->f_globals().try_get(pair->first); + if(val) return *val; + val = vm->builtins->attribs.try_get(pair->first); + if(val) return *val; vm->nameError(pair->first); return nullptr; } -void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{ +void NameRef::set(VM* vm, Frame* frame, PyVar val) const{ switch(pair->second) { case NAME_LOCAL: frame->f_locals[pair->first] = std::move(val); break; case NAME_GLOBAL: @@ -4874,7 +4881,7 @@ void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{ } } -void NamePointer::del(VM* vm, Frame* frame) const{ +void NameRef::del(VM* vm, Frame* frame) const{ switch(pair->second) { case NAME_LOCAL: { if(frame->f_locals.count(pair->first) > 0){ @@ -4899,39 +4906,39 @@ void NamePointer::del(VM* vm, Frame* frame) const{ } } -PyVar AttrPointer::get(VM* vm, Frame* frame) const{ +PyVar AttrRef::get(VM* vm, Frame* frame) const{ return vm->getAttr(obj, attr.pair->first); } -void AttrPointer::set(VM* vm, Frame* frame, PyVar val) const{ +void AttrRef::set(VM* vm, Frame* frame, PyVar val) const{ vm->setAttr(obj, attr.pair->first, val); } -void AttrPointer::del(VM* vm, Frame* frame) const{ +void AttrRef::del(VM* vm, Frame* frame) const{ vm->typeError("cannot delete attribute"); } -PyVar IndexPointer::get(VM* vm, Frame* frame) const{ +PyVar IndexRef::get(VM* vm, Frame* frame) const{ return vm->call(obj, __getitem__, pkpy::oneArg(index)); } -void IndexPointer::set(VM* vm, Frame* frame, PyVar val) const{ +void IndexRef::set(VM* vm, Frame* frame, PyVar val) const{ vm->call(obj, __setitem__, pkpy::twoArgs(index, val)); } -void IndexPointer::del(VM* vm, Frame* frame) const{ +void IndexRef::del(VM* vm, Frame* frame) const{ vm->call(obj, __delitem__, pkpy::oneArg(index)); } -PyVar CompoundPointer::get(VM* vm, Frame* frame) const{ +PyVar TupleRef::get(VM* vm, Frame* frame) const{ PyVarList args(varRefs.size()); for (int i = 0; i < varRefs.size(); i++) { - args[i] = vm->PyPointer_AS_C(varRefs[i])->get(vm, frame); + args[i] = vm->PyRef_AS_C(varRefs[i])->get(vm, frame); } return vm->PyTuple(args); } -void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{ +void TupleRef::set(VM* vm, Frame* frame, PyVar val) const{ if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){ vm->typeError("only tuple or list can be unpacked"); } @@ -4939,24 +4946,24 @@ void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{ if(args.size() > varRefs.size()) vm->valueError("too many values to unpack"); if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack"); for (int i = 0; i < varRefs.size(); i++) { - vm->PyPointer_AS_C(varRefs[i])->set(vm, frame, args[i]); + vm->PyRef_AS_C(varRefs[i])->set(vm, frame, args[i]); } } -void CompoundPointer::del(VM* vm, Frame* frame) const{ - for (auto& r : varRefs) vm->PyPointer_AS_C(r)->del(vm, frame); +void TupleRef::del(VM* vm, Frame* frame) const{ + for (auto& r : varRefs) vm->PyRef_AS_C(r)->del(vm, frame); } PyVar UserPointer::get(VM* vm, Frame* frame) const{ frame = vm->__findFrame(f_id); if(frame == nullptr) vm->nullPointerError(); - return vm->PyPointer_AS_C(p)->get(vm, frame); + return vm->PyRef_AS_C(p)->get(vm, frame); } void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{ frame = vm->__findFrame(f_id); if(frame == nullptr) vm->nullPointerError(); - vm->PyPointer_AS_C(p)->set(vm, frame, val); + vm->PyRef_AS_C(p)->set(vm, frame, val); } void UserPointer::del(VM* vm, Frame* frame) const{ @@ -4965,7 +4972,7 @@ void UserPointer::del(VM* vm, Frame* frame) const{ /***** Frame's Impl *****/ inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){ - if(v->isType(vm->_tp_pointer)) return vm->PyPointer_AS_C(v)->get(vm, this); + if(v->isType(vm->_tp_ref)) return vm->PyRef_AS_C(v)->get(vm, this); return v; } @@ -5336,7 +5343,7 @@ public: if(parser->matchChar('\'')) {eatString('\'', true); return;} if(parser->matchChar('"')) {eatString('"', true); return;} } - if (isdigit(c)) { + if (c >= '0' && c <= '9') { eatNumber(); return; } @@ -5464,7 +5471,7 @@ public: _TokenType op = parser->previous.type; if(op == TK("=")) { // a = (expr) EXPR_TUPLE(); - emitCode(OP_STORE_PTR); + emitCode(OP_STORE_REF); }else{ // a += (expr) -> a = a + (expr) // TODO: optimization is needed for inplace operators emitCode(OP_DUP_TOP); @@ -5477,7 +5484,7 @@ public: case TK("//="): emitCode(OP_BINARY_OP, 4); break; default: UNREACHABLE(); } - emitCode(OP_STORE_PTR); + emitCode(OP_STORE_REF); } } @@ -5662,21 +5669,21 @@ __LISTCOMP: tkname.str(), codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL ); - emitCode(OP_LOAD_NAME_PTR, index); + emitCode(OP_LOAD_NAME_REF, index); } void exprAttrib() { consume(TK("@id")); const _Str& name = parser->previous.str(); int index = getCode()->addName(name, NAME_ATTR); - emitCode(OP_BUILD_ATTR_PTR, index); + emitCode(OP_BUILD_ATTR_REF, index); } void exprAttribPtr(){ consume(TK("@id")); const _Str& name = parser->previous.str(); int index = getCode()->addName(name, NAME_ATTR); - emitCode(OP_BUILD_ATTR_PTR_PTR, index); + emitCode(OP_BUILD_ATTR_REF_PTR, index); } // [:], [:b] @@ -5706,7 +5713,7 @@ __LISTCOMP: } } - emitCode(OP_BUILD_INDEX_PTR); + emitCode(OP_BUILD_INDEX_REF); } void exprValue() { @@ -5773,7 +5780,7 @@ __LISTCOMP: tkmodule = parser->previous; } int index = getCode()->addName(tkmodule.str(), NAME_GLOBAL); - emitCode(OP_STORE_NAME_PTR, index); + emitCode(OP_STORE_NAME_REF, index); } while (match(TK(","))); consumeEndStatement(); } @@ -5787,13 +5794,13 @@ __LISTCOMP: consume(TK("@id")); Token tkname = parser->previous; int index = getCode()->addName(tkname.str(), NAME_GLOBAL); - emitCode(OP_BUILD_ATTR_PTR, index); + emitCode(OP_BUILD_ATTR_REF, index); if (match(TK("as"))) { consume(TK("@id")); tkname = parser->previous; } index = getCode()->addName(tkname.str(), NAME_GLOBAL); - emitCode(OP_STORE_NAME_PTR, index); + emitCode(OP_STORE_NAME_REF, index); } while (match(TK(","))); emitCode(OP_POP_TOP); consumeEndStatement(); @@ -5916,11 +5923,11 @@ __LISTCOMP: tkname.str(), codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL ); - emitCode(OP_STORE_NAME_PTR, index); - emitCode(OP_LOAD_NAME_PTR, index); + emitCode(OP_STORE_NAME_REF, index); + emitCode(OP_LOAD_NAME_REF, index); emitCode(OP_WITH_ENTER); compileBlockBody(); - emitCode(OP_LOAD_NAME_PTR, index); + emitCode(OP_LOAD_NAME_REF, index); emitCode(OP_WITH_EXIT); } else if(match(TK("label"))){ if(mode() != EXEC_MODE) syntaxError("'label' is only available in EXEC_MODE"); @@ -5942,7 +5949,7 @@ __LISTCOMP: consumeEndStatement(); } else if(match(TK("del"))){ EXPR(); - emitCode(OP_DELETE_PTR); + emitCode(OP_DELETE_REF); consumeEndStatement(); } else if(match(TK("global"))){ consume(TK("@id")); @@ -5956,7 +5963,7 @@ __LISTCOMP: // If last op is not an assignment, pop the result. uint8_t lastOp = getCode()->co_code.back().op; - if( lastOp != OP_STORE_NAME_PTR && lastOp != OP_STORE_PTR){ + if( lastOp != OP_STORE_NAME_REF && lastOp != OP_STORE_REF){ if(mode()==SINGLE_MODE && parser->indents.top() == 0){ emitCode(OP_PRINT_EXPR); } @@ -5980,7 +5987,7 @@ __LISTCOMP: isCompilingClass = false; if(superClsNameIdx == -1) emitCode(OP_LOAD_NONE); - else emitCode(OP_LOAD_NAME_PTR, superClsNameIdx); + else emitCode(OP_LOAD_NAME_REF, superClsNameIdx); emitCode(OP_BUILD_CLASS, clsNameIdx); } @@ -6207,13 +6214,13 @@ __NOT_ENOUGH_LINES: #define BIND_NUM_ARITH_OPT(name, op) \ - _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ + _vm->bindMethodMulti({"int","float"}, #name, [](VM* vm, const pkpy::ArgList& args){ \ if(!vm->isIntOrFloat(args[0], args[1])) \ - vm->typeError("unsupported operand type(s) for " #op ); \ - if(args[0]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){ \ - return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ + vm->typeError("unsupported operand type(s) for " #op ); \ + if(args._index(0)->isType(vm->_tp_int) && args._index(1)->isType(vm->_tp_int)){ \ + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ }else{ \ - return vm->PyFloat(vm->numToFloat(args[0]) op vm->numToFloat(args[1])); \ + return vm->PyFloat(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \ } \ }); @@ -6223,7 +6230,7 @@ __NOT_ENOUGH_LINES: if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \ vm->typeError("unsupported operand type(s) for " #op ); \ } \ - return vm->PyBool(vm->numToFloat(args[0]) op vm->numToFloat(args[1])); \ + return vm->PyBool(vm->numToFloat(args._index(0)) op vm->numToFloat(args._index(1))); \ }); @@ -6407,17 +6414,17 @@ void __initializeBuiltinFunctions(VM* _vm) { _vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) { if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) vm->typeError("unsupported operand type(s) for " "//" ); - _Int rhs = vm->PyInt_AS_C(args[1]); + _Int rhs = vm->PyInt_AS_C(args._index(1)); if(rhs == 0) vm->zeroDivisionError(); - return vm->PyInt(vm->PyInt_AS_C(args[0]) / rhs); + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) / rhs); }); _vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) { if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) vm->typeError("unsupported operand type(s) for " "%" ); - _Int rhs = vm->PyInt_AS_C(args[1]); + _Int rhs = vm->PyInt_AS_C(args._index(1)); if(rhs == 0) vm->zeroDivisionError(); - return vm->PyInt(vm->PyInt_AS_C(args[0]) % rhs); + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) % rhs); }); _vm->bindMethod("int", "__repr__", [](VM* vm, const pkpy::ArgList& args) { @@ -6429,10 +6436,10 @@ void __initializeBuiltinFunctions(VM* _vm) { }); #define __INT_BITWISE_OP(name,op) \ - _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ - if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ - vm->typeError("unsupported operand type(s) for " #op ); \ - return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \ + _vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \ + if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \ + vm->typeError("unsupported operand type(s) for " #op ); \ + return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \ }); __INT_BITWISE_OP(__lshift__, <<) @@ -6443,12 +6450,6 @@ void __initializeBuiltinFunctions(VM* _vm) { #undef __INT_BITWISE_OP - _vm->bindMethod("int", "__xor__", [](VM* vm, const pkpy::ArgList& args) { - if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) - vm->typeError("unsupported operand type(s) for " "^" ); - return vm->PyInt(vm->PyInt_AS_C(args[0]) ^ vm->PyInt_AS_C(args[1])); - }); - /************ PyFloat ************/ _vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) { if(args.size() == 0) return vm->PyFloat(0.0); diff --git a/src/compiler.h b/src/compiler.h index ab9bfbb9..cc93ada8 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -266,7 +266,7 @@ public: if(parser->matchChar('\'')) {eatString('\'', true); return;} if(parser->matchChar('"')) {eatString('"', true); return;} } - if (isdigit(c)) { + if (c >= '0' && c <= '9') { eatNumber(); return; }