mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
df51577e06
commit
a67b59f4cb
@ -24,3 +24,7 @@ The initial version. Hello, world!
|
|||||||
+ Fix a bug for jsonify `nan` or `inf`
|
+ Fix a bug for jsonify `nan` or `inf`
|
||||||
+ Add `math.isnan` and `math.isinf`
|
+ Add `math.isnan` and `math.isinf`
|
||||||
+ Fix a bug of `__checkType`
|
+ Fix a bug of `__checkType`
|
||||||
|
|
||||||
|
## 0.5.0+1
|
||||||
|
|
||||||
|
+ Fix a bug on Windows
|
@ -1,6 +1,6 @@
|
|||||||
name: pocketpy
|
name: pocketpy
|
||||||
description: A lightweight Python interpreter for game engines.
|
description: A lightweight Python interpreter for game engines.
|
||||||
version: 0.4.8+6
|
version: 0.5.0+1
|
||||||
homepage: https://pocketpy.dev
|
homepage: https://pocketpy.dev
|
||||||
repository: https://github.com/blueloveth/pocketpy
|
repository: https://github.com/blueloveth/pocketpy
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PK_VERSION "0.4.8"
|
#define PK_VERSION "0.5.0"
|
||||||
|
|
||||||
//#define PKPY_NO_TYPE_CHECK
|
//#define PKPY_NO_TYPE_CHECK
|
||||||
//#define PKPY_NO_INDEX_CHECK
|
//#define PKPY_NO_INDEX_CHECK
|
||||||
@ -2277,7 +2277,7 @@ private:
|
|||||||
struct PyObject;
|
struct PyObject;
|
||||||
typedef pkpy::shared_ptr<PyObject> PyVar;
|
typedef pkpy::shared_ptr<PyObject> PyVar;
|
||||||
typedef PyVar PyVarOrNull;
|
typedef PyVar PyVarOrNull;
|
||||||
typedef PyVar VarRef;
|
typedef PyVar PyVarRef;
|
||||||
|
|
||||||
class PyVarList: public std::vector<PyVar> {
|
class PyVarList: public std::vector<PyVar> {
|
||||||
PyVar& at(size_t) = delete;
|
PyVar& at(size_t) = delete;
|
||||||
@ -2410,6 +2410,10 @@ namespace pkpy {
|
|||||||
return _args[i];
|
return _args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const PyVar& _index(uint8_t i) const {
|
||||||
|
return _args[i];
|
||||||
|
}
|
||||||
|
|
||||||
// overload = for &&
|
// overload = for &&
|
||||||
ArgList& operator=(ArgList&& other){
|
ArgList& operator=(ArgList&& other){
|
||||||
if(this != &other){
|
if(this != &other){
|
||||||
@ -2992,7 +2996,7 @@ typedef int64_t _Int;
|
|||||||
typedef double _Float;
|
typedef double _Float;
|
||||||
|
|
||||||
struct CodeObject;
|
struct CodeObject;
|
||||||
struct BasePointer;
|
struct BaseRef;
|
||||||
class VM;
|
class VM;
|
||||||
class Frame;
|
class Frame;
|
||||||
|
|
||||||
@ -3045,7 +3049,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
virtual PyVar next() = 0;
|
virtual PyVar next() = 0;
|
||||||
virtual bool hasNext() = 0;
|
virtual bool hasNext() = 0;
|
||||||
VarRef var;
|
PyVarRef var;
|
||||||
BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
|
BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
|
||||||
virtual ~BaseIterator() = default;
|
virtual ~BaseIterator() = default;
|
||||||
};
|
};
|
||||||
@ -3447,11 +3451,11 @@ struct Parser {
|
|||||||
|
|
||||||
class Frame;
|
class Frame;
|
||||||
|
|
||||||
struct BasePointer {
|
struct BaseRef {
|
||||||
virtual PyVar get(VM*, Frame*) const = 0;
|
virtual PyVar get(VM*, Frame*) const = 0;
|
||||||
virtual void set(VM*, Frame*, PyVar) const = 0;
|
virtual void set(VM*, Frame*, PyVar) const = 0;
|
||||||
virtual void del(VM*, Frame*) const = 0;
|
virtual void del(VM*, Frame*) const = 0;
|
||||||
virtual ~BasePointer() = default;
|
virtual ~BaseRef() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NameScope {
|
enum NameScope {
|
||||||
@ -3460,49 +3464,49 @@ enum NameScope {
|
|||||||
NAME_ATTR = 2,
|
NAME_ATTR = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NamePointer : BasePointer {
|
struct NameRef : BaseRef {
|
||||||
const std::pair<_Str, NameScope>* pair;
|
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;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AttrPointer : BasePointer {
|
struct AttrRef : BaseRef {
|
||||||
mutable PyVar obj;
|
mutable PyVar obj;
|
||||||
const NamePointer attr;
|
const NameRef attr;
|
||||||
AttrPointer(PyVar obj, const NamePointer attr) : obj(obj), attr(attr) {}
|
AttrRef(PyVar obj, const NameRef attr) : obj(obj), attr(attr) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexPointer : BasePointer {
|
struct IndexRef : BaseRef {
|
||||||
mutable PyVar obj;
|
mutable PyVar obj;
|
||||||
PyVar index;
|
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;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompoundPointer : BasePointer {
|
struct TupleRef : BaseRef {
|
||||||
PyVarList varRefs;
|
PyVarList varRefs;
|
||||||
CompoundPointer(const PyVarList& varRefs) : varRefs(varRefs) {}
|
TupleRef(const PyVarList& varRefs) : varRefs(varRefs) {}
|
||||||
CompoundPointer(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {}
|
TupleRef(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UserPointer : BasePointer {
|
struct UserPointer : BaseRef {
|
||||||
VarRef p;
|
PyVarRef p;
|
||||||
uint64_t f_id;
|
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;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
@ -3563,13 +3567,13 @@ OPCODE(RAISE_ERROR)
|
|||||||
OPCODE(STORE_FUNCTION)
|
OPCODE(STORE_FUNCTION)
|
||||||
OPCODE(BUILD_CLASS)
|
OPCODE(BUILD_CLASS)
|
||||||
|
|
||||||
OPCODE(LOAD_NAME_PTR) // no arg
|
OPCODE(LOAD_NAME_REF) // no arg
|
||||||
OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
||||||
OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr]
|
OPCODE(BUILD_INDEX_REF) // 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_NAME_REF) // 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(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr
|
||||||
OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr
|
OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr
|
||||||
OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_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_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
|
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(STORE_FUNCTION)
|
||||||
OPCODE(BUILD_CLASS)
|
OPCODE(BUILD_CLASS)
|
||||||
|
|
||||||
OPCODE(LOAD_NAME_PTR) // no arg
|
OPCODE(LOAD_NAME_REF) // no arg
|
||||||
OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
||||||
OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr]
|
OPCODE(BUILD_INDEX_REF) // 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_NAME_REF) // 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(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr
|
||||||
OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr
|
OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr
|
||||||
OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_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_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
|
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);
|
setAttr(obj, __module__, frame->_module);
|
||||||
frame->push(obj);
|
frame->push(obj);
|
||||||
} break;
|
} break;
|
||||||
case OP_LOAD_NAME_PTR: {
|
case OP_LOAD_NAME_REF: {
|
||||||
frame->push(PyPointer(NamePointer(
|
frame->push(PyRef(NameRef(
|
||||||
&(frame->code->co_names[byte.arg])
|
&(frame->code->co_names[byte.arg])
|
||||||
)));
|
)));
|
||||||
} break;
|
} break;
|
||||||
case OP_STORE_NAME_PTR: {
|
case OP_STORE_NAME_REF: {
|
||||||
const auto& p = frame->code->co_names[byte.arg];
|
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;
|
} break;
|
||||||
case OP_BUILD_ATTR_PTR: {
|
case OP_BUILD_ATTR_REF: {
|
||||||
const auto& attr = frame->code->co_names[byte.arg];
|
const auto& attr = frame->code->co_names[byte.arg];
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
frame->push(PyPointer(AttrPointer(obj, NamePointer(&attr))));
|
frame->push(PyRef(AttrRef(obj, NameRef(&attr))));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_ATTR_PTR_PTR: {
|
case OP_BUILD_ATTR_REF_PTR: {
|
||||||
const auto& attr = frame->code->co_names[byte.arg];
|
const auto& attr = frame->code->co_names[byte.arg];
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
__checkType(obj, _tp_user_pointer);
|
__checkType(obj, _tp_user_pointer);
|
||||||
const VarRef& var = UNION_GET(VarRef, obj);
|
const PyVarRef& var = UNION_GET(PyVarRef, obj);
|
||||||
auto p = PyPointer_AS_C(var);
|
auto p = PyRef_AS_C(var);
|
||||||
frame->push(PyPointer(AttrPointer(p->get(this, frame), &attr)));
|
frame->push(PyRef(AttrRef(p->get(this, frame), &attr)));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_INDEX_PTR: {
|
case OP_BUILD_INDEX_REF: {
|
||||||
PyVar index = frame->popValue(this);
|
PyVar index = frame->popValue(this);
|
||||||
VarRef obj = frame->popValue(this);
|
PyVarRef obj = frame->popValue(this);
|
||||||
frame->push(PyPointer(IndexPointer(obj, index)));
|
frame->push(PyRef(IndexRef(obj, index)));
|
||||||
} break;
|
} break;
|
||||||
case OP_STORE_PTR: {
|
case OP_STORE_REF: {
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
VarRef r = frame->__pop();
|
PyVarRef r = frame->__pop();
|
||||||
PyPointer_AS_C(r)->set(this, frame, std::move(obj));
|
PyRef_AS_C(r)->set(this, frame, std::move(obj));
|
||||||
} break;
|
} break;
|
||||||
case OP_DELETE_PTR: {
|
case OP_DELETE_REF: {
|
||||||
VarRef r = frame->__pop();
|
PyVarRef r = frame->__pop();
|
||||||
PyPointer_AS_C(r)->del(this, frame);
|
PyRef_AS_C(r)->del(this, frame);
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_SMART_TUPLE:
|
case OP_BUILD_SMART_TUPLE:
|
||||||
{
|
{
|
||||||
pkpy::ArgList items = frame->__popNReversed(byte.arg);
|
pkpy::ArgList items = frame->__popNReversed(byte.arg);
|
||||||
bool done = false;
|
bool done = false;
|
||||||
for(int i=0; i<items.size(); i++){
|
for(int i=0; i<items.size(); i++){
|
||||||
if(!items[i]->isType(_tp_pointer)) {
|
if(!items[i]->isType(_tp_ref)) {
|
||||||
done = true;
|
done = true;
|
||||||
PyVarList values(items.size());
|
PyVarList values(items.size());
|
||||||
for(int i=0; i<items.size(); i++){
|
for(int i=0; i<items.size(); i++){
|
||||||
@ -3986,7 +3990,7 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(done) break;
|
if(done) break;
|
||||||
frame->push(PyPointer(CompoundPointer(items.toList())));
|
frame->push(PyRef(TupleRef(items.toList())));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_STRING:
|
case OP_BUILD_STRING:
|
||||||
{
|
{
|
||||||
@ -4037,20 +4041,23 @@ protected:
|
|||||||
case OP_POP_TOP: frame->popValue(this); break;
|
case OP_POP_TOP: frame->popValue(this); break;
|
||||||
case OP_BINARY_OP:
|
case OP_BINARY_OP:
|
||||||
{
|
{
|
||||||
pkpy::ArgList args = frame->popNValuesReversed(this, 2);
|
frame->push(
|
||||||
frame->push(fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args)));
|
fastCall(BINARY_SPECIAL_METHODS[byte.arg],
|
||||||
|
frame->popNValuesReversed(this, 2))
|
||||||
|
);
|
||||||
} break;
|
} break;
|
||||||
case OP_BITWISE_OP:
|
case OP_BITWISE_OP:
|
||||||
{
|
{
|
||||||
pkpy::ArgList args = frame->popNValuesReversed(this, 2);
|
frame->push(
|
||||||
frame->push(fastCall(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args)));
|
fastCall(BITWISE_SPECIAL_METHODS[byte.arg],
|
||||||
|
frame->popNValuesReversed(this, 2))
|
||||||
|
);
|
||||||
} break;
|
} break;
|
||||||
case OP_COMPARE_OP:
|
case OP_COMPARE_OP:
|
||||||
{
|
{
|
||||||
pkpy::ArgList args = frame->popNValuesReversed(this, 2);
|
|
||||||
// for __ne__ we use the negation of __eq__
|
// for __ne__ we use the negation of __eq__
|
||||||
int op = byte.arg == 3 ? 2 : byte.arg;
|
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));
|
if(op != byte.arg) res = PyBool(!PyBool_AS_C(res));
|
||||||
frame->push(std::move(res));
|
frame->push(std::move(res));
|
||||||
} break;
|
} break;
|
||||||
@ -4081,11 +4088,11 @@ protected:
|
|||||||
case OP_UNARY_REF:
|
case OP_UNARY_REF:
|
||||||
{
|
{
|
||||||
// _pointer to pointer
|
// _pointer to pointer
|
||||||
VarRef obj = frame->__pop();
|
PyVarRef obj = frame->__pop();
|
||||||
__checkType(obj, _tp_pointer);
|
__checkType(obj, _tp_ref);
|
||||||
frame->push(newObject(
|
frame->push(newObject(
|
||||||
_tp_user_pointer,
|
_tp_user_pointer,
|
||||||
PyPointer(UserPointer(obj, frame->id))
|
PyRef(UserPointer(obj, frame->id))
|
||||||
));
|
));
|
||||||
} break;
|
} break;
|
||||||
case OP_UNARY_DEREF:
|
case OP_UNARY_DEREF:
|
||||||
@ -4093,7 +4100,7 @@ protected:
|
|||||||
// pointer to _pointer
|
// pointer to _pointer
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
__checkType(obj, _tp_user_pointer);
|
__checkType(obj, _tp_user_pointer);
|
||||||
frame->push(UNION_GET(VarRef, obj));
|
frame->push(UNION_GET(PyVarRef, obj));
|
||||||
} break;
|
} break;
|
||||||
case OP_POP_JUMP_IF_FALSE:
|
case OP_POP_JUMP_IF_FALSE:
|
||||||
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
||||||
@ -4145,11 +4152,11 @@ protected:
|
|||||||
case OP_GOTO: {
|
case OP_GOTO: {
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
const _Str& label = PyStr_AS_C(obj);
|
const _Str& label = PyStr_AS_C(obj);
|
||||||
auto it = frame->code->co_labels.find(label);
|
int* target = frame->code->co_labels.try_get(label);
|
||||||
if(it == frame->code->co_labels.end()){
|
if(target == nullptr){
|
||||||
_error("KeyError", "label '" + label + "' not found");
|
_error("KeyError", "label '" + label + "' not found");
|
||||||
}
|
}
|
||||||
frame->safeJump(it->second);
|
frame->safeJump(*target);
|
||||||
} break;
|
} break;
|
||||||
case OP_GET_ITER:
|
case OP_GET_ITER:
|
||||||
{
|
{
|
||||||
@ -4157,8 +4164,8 @@ protected:
|
|||||||
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
|
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
|
||||||
if(iter_fn != nullptr){
|
if(iter_fn != nullptr){
|
||||||
PyVar tmp = call(iter_fn, pkpy::oneArg(obj));
|
PyVar tmp = call(iter_fn, pkpy::oneArg(obj));
|
||||||
VarRef var = frame->__pop();
|
PyVarRef var = frame->__pop();
|
||||||
__checkType(var, _tp_pointer);
|
__checkType(var, _tp_ref);
|
||||||
PyIter_AS_C(tmp)->var = var;
|
PyIter_AS_C(tmp)->var = var;
|
||||||
frame->push(std::move(tmp));
|
frame->push(std::move(tmp));
|
||||||
}else{
|
}else{
|
||||||
@ -4171,7 +4178,7 @@ protected:
|
|||||||
// __top() must be PyIter, so no need to __deref()
|
// __top() must be PyIter, so no need to __deref()
|
||||||
auto& it = PyIter_AS_C(frame->__top());
|
auto& it = PyIter_AS_C(frame->__top());
|
||||||
if(it->hasNext()){
|
if(it->hasNext()){
|
||||||
PyPointer_AS_C(it->var)->set(this, frame, it->next());
|
PyRef_AS_C(it->var)->set(this, frame, it->next());
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
frame->safeJump(byte.arg);
|
frame->safeJump(byte.arg);
|
||||||
@ -4321,8 +4328,8 @@ public:
|
|||||||
PyVar fastCall(const _Str& name, pkpy::ArgList&& args){
|
PyVar fastCall(const _Str& name, pkpy::ArgList&& args){
|
||||||
PyObject* cls = args[0]->_type.get();
|
PyObject* cls = args[0]->_type.get();
|
||||||
while(cls != None.get()) {
|
while(cls != None.get()) {
|
||||||
auto it = cls->attribs.find(name);
|
PyVar* val = cls->attribs.try_get(name);
|
||||||
if(it != cls->attribs.end()) return call(it->second, std::move(args));
|
if(val != nullptr) return call(*val, std::move(args));
|
||||||
cls = cls->attribs[__base__].get();
|
cls = cls->attribs[__base__].get();
|
||||||
}
|
}
|
||||||
attributeError(args[0], name);
|
attributeError(args[0], name);
|
||||||
@ -4412,7 +4419,7 @@ public:
|
|||||||
|
|
||||||
for(int i=0; i<kwargs.size(); i+=2){
|
for(int i=0; i<kwargs.size(); i+=2){
|
||||||
const _Str& key = PyStr_AS_C(kwargs[i]);
|
const _Str& key = PyStr_AS_C(kwargs[i]);
|
||||||
if(fn->kwArgs.find(key) == fn->kwArgs.end()){
|
if(!fn->kwArgs.contains(key)){
|
||||||
typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()");
|
typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()");
|
||||||
}
|
}
|
||||||
const PyVar& val = kwargs[i+1];
|
const PyVar& val = kwargs[i+1];
|
||||||
@ -4425,8 +4432,8 @@ public:
|
|||||||
locals[key] = val;
|
locals[key] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it_m = (*callable)->attribs.find(__module__);
|
PyVar* it_m = (*callable)->attribs.try_get(__module__);
|
||||||
PyVar _module = it_m != (*callable)->attribs.end() ? it_m->second : topFrame()->_module;
|
PyVar _module = it_m != nullptr ? *it_m : topFrame()->_module;
|
||||||
if(opCall){
|
if(opCall){
|
||||||
__pushNewFrame(fn->code, _module, std::move(locals));
|
__pushNewFrame(fn->code, _module, std::move(locals));
|
||||||
return __py2py_call_signal;
|
return __py2py_call_signal;
|
||||||
@ -4507,9 +4514,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline PyVar newObject(PyVar type, T&& _value) {
|
inline PyVar newObject(PyVar type, T _value) {
|
||||||
__checkType(type, _tp_type);
|
__checkType(type, _tp_type);
|
||||||
return pkpy::make_shared<PyObject, Py_<T>>(std::forward<T>(_value), type);
|
return pkpy::make_shared<PyObject, Py_<T>>(_value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar newModule(_Str name) {
|
PyVar newModule(_Str name) {
|
||||||
@ -4661,19 +4668,19 @@ public:
|
|||||||
PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str;
|
PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str;
|
||||||
PyVar _tp_list, _tp_tuple;
|
PyVar _tp_list, _tp_tuple;
|
||||||
PyVar _tp_function, _tp_native_function, _tp_native_iterator, _tp_bounded_method;
|
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;
|
PyVar _tp_user_pointer, _tp_super;
|
||||||
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
inline VarRef PyPointer(P value) {
|
inline PyVarRef PyRef(P&& value) {
|
||||||
static_assert(std::is_base_of<BasePointer, P>::value, "P should derive from BasePointer");
|
static_assert(std::is_base_of<BaseRef, P>::value, "P should derive from BaseRef");
|
||||||
return newObject(_tp_pointer, value);
|
return newObject(_tp_ref, std::forward<P>(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");
|
if(!obj->isType(_tp_ref)) typeError("expected an l-value");
|
||||||
return (const BasePointer*)(obj->value());
|
return (const BaseRef*)(obj->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
||||||
@ -4713,7 +4720,7 @@ public:
|
|||||||
_tp_slice = newClassType("slice");
|
_tp_slice = newClassType("slice");
|
||||||
_tp_range = newClassType("range");
|
_tp_range = newClassType("range");
|
||||||
_tp_module = newClassType("module");
|
_tp_module = newClassType("module");
|
||||||
_tp_pointer = newClassType("_pointer");
|
_tp_ref = newClassType("_pointer");
|
||||||
_tp_user_pointer = newClassType("pointer");
|
_tp_user_pointer = newClassType("pointer");
|
||||||
|
|
||||||
newClassType("NoneType");
|
newClassType("NoneType");
|
||||||
@ -4848,18 +4855,18 @@ public:
|
|||||||
|
|
||||||
/***** Pointers' Impl *****/
|
/***** Pointers' Impl *****/
|
||||||
|
|
||||||
PyVar NamePointer::get(VM* vm, Frame* frame) const{
|
PyVar NameRef::get(VM* vm, Frame* frame) const{
|
||||||
auto it = frame->f_locals.find(pair->first);
|
PyVar* val = frame->f_locals.try_get(pair->first);
|
||||||
if(it != frame->f_locals.end()) return it->second;
|
if(val) return *val;
|
||||||
it = frame->f_globals().find(pair->first);
|
val = frame->f_globals().try_get(pair->first);
|
||||||
if(it != frame->f_globals().end()) return it->second;
|
if(val) return *val;
|
||||||
it = vm->builtins->attribs.find(pair->first);
|
val = vm->builtins->attribs.try_get(pair->first);
|
||||||
if(it != vm->builtins->attribs.end()) return it->second;
|
if(val) return *val;
|
||||||
vm->nameError(pair->first);
|
vm->nameError(pair->first);
|
||||||
return nullptr;
|
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) {
|
switch(pair->second) {
|
||||||
case NAME_LOCAL: frame->f_locals[pair->first] = std::move(val); break;
|
case NAME_LOCAL: frame->f_locals[pair->first] = std::move(val); break;
|
||||||
case NAME_GLOBAL:
|
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) {
|
switch(pair->second) {
|
||||||
case NAME_LOCAL: {
|
case NAME_LOCAL: {
|
||||||
if(frame->f_locals.count(pair->first) > 0){
|
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);
|
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);
|
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");
|
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));
|
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));
|
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));
|
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());
|
PyVarList args(varRefs.size());
|
||||||
for (int i = 0; i < varRefs.size(); i++) {
|
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);
|
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)){
|
if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){
|
||||||
vm->typeError("only tuple or list can be unpacked");
|
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("too many values to unpack");
|
||||||
if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack");
|
if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack");
|
||||||
for (int i = 0; i < varRefs.size(); i++) {
|
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{
|
void TupleRef::del(VM* vm, Frame* frame) const{
|
||||||
for (auto& r : varRefs) vm->PyPointer_AS_C(r)->del(vm, frame);
|
for (auto& r : varRefs) vm->PyRef_AS_C(r)->del(vm, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar UserPointer::get(VM* vm, Frame* frame) const{
|
PyVar UserPointer::get(VM* vm, Frame* frame) const{
|
||||||
frame = vm->__findFrame(f_id);
|
frame = vm->__findFrame(f_id);
|
||||||
if(frame == nullptr) vm->nullPointerError();
|
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{
|
void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
|
||||||
frame = vm->__findFrame(f_id);
|
frame = vm->__findFrame(f_id);
|
||||||
if(frame == nullptr) vm->nullPointerError();
|
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{
|
void UserPointer::del(VM* vm, Frame* frame) const{
|
||||||
@ -4965,7 +4972,7 @@ void UserPointer::del(VM* vm, Frame* frame) const{
|
|||||||
|
|
||||||
/***** Frame's Impl *****/
|
/***** Frame's Impl *****/
|
||||||
inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
|
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;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5336,7 +5343,7 @@ public:
|
|||||||
if(parser->matchChar('\'')) {eatString('\'', true); return;}
|
if(parser->matchChar('\'')) {eatString('\'', true); return;}
|
||||||
if(parser->matchChar('"')) {eatString('"', true); return;}
|
if(parser->matchChar('"')) {eatString('"', true); return;}
|
||||||
}
|
}
|
||||||
if (isdigit(c)) {
|
if (c >= '0' && c <= '9') {
|
||||||
eatNumber();
|
eatNumber();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -5464,7 +5471,7 @@ public:
|
|||||||
_TokenType op = parser->previous.type;
|
_TokenType op = parser->previous.type;
|
||||||
if(op == TK("=")) { // a = (expr)
|
if(op == TK("=")) { // a = (expr)
|
||||||
EXPR_TUPLE();
|
EXPR_TUPLE();
|
||||||
emitCode(OP_STORE_PTR);
|
emitCode(OP_STORE_REF);
|
||||||
}else{ // a += (expr) -> a = a + (expr)
|
}else{ // a += (expr) -> a = a + (expr)
|
||||||
// TODO: optimization is needed for inplace operators
|
// TODO: optimization is needed for inplace operators
|
||||||
emitCode(OP_DUP_TOP);
|
emitCode(OP_DUP_TOP);
|
||||||
@ -5477,7 +5484,7 @@ public:
|
|||||||
case TK("//="): emitCode(OP_BINARY_OP, 4); break;
|
case TK("//="): emitCode(OP_BINARY_OP, 4); break;
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
emitCode(OP_STORE_PTR);
|
emitCode(OP_STORE_REF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5662,21 +5669,21 @@ __LISTCOMP:
|
|||||||
tkname.str(),
|
tkname.str(),
|
||||||
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
||||||
);
|
);
|
||||||
emitCode(OP_LOAD_NAME_PTR, index);
|
emitCode(OP_LOAD_NAME_REF, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exprAttrib() {
|
void exprAttrib() {
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
const _Str& name = parser->previous.str();
|
const _Str& name = parser->previous.str();
|
||||||
int index = getCode()->addName(name, NAME_ATTR);
|
int index = getCode()->addName(name, NAME_ATTR);
|
||||||
emitCode(OP_BUILD_ATTR_PTR, index);
|
emitCode(OP_BUILD_ATTR_REF, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exprAttribPtr(){
|
void exprAttribPtr(){
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
const _Str& name = parser->previous.str();
|
const _Str& name = parser->previous.str();
|
||||||
int index = getCode()->addName(name, NAME_ATTR);
|
int index = getCode()->addName(name, NAME_ATTR);
|
||||||
emitCode(OP_BUILD_ATTR_PTR_PTR, index);
|
emitCode(OP_BUILD_ATTR_REF_PTR, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [:], [:b]
|
// [:], [:b]
|
||||||
@ -5706,7 +5713,7 @@ __LISTCOMP:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitCode(OP_BUILD_INDEX_PTR);
|
emitCode(OP_BUILD_INDEX_REF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exprValue() {
|
void exprValue() {
|
||||||
@ -5773,7 +5780,7 @@ __LISTCOMP:
|
|||||||
tkmodule = parser->previous;
|
tkmodule = parser->previous;
|
||||||
}
|
}
|
||||||
int index = getCode()->addName(tkmodule.str(), NAME_GLOBAL);
|
int index = getCode()->addName(tkmodule.str(), NAME_GLOBAL);
|
||||||
emitCode(OP_STORE_NAME_PTR, index);
|
emitCode(OP_STORE_NAME_REF, index);
|
||||||
} while (match(TK(",")));
|
} while (match(TK(",")));
|
||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
}
|
}
|
||||||
@ -5787,13 +5794,13 @@ __LISTCOMP:
|
|||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
Token tkname = parser->previous;
|
Token tkname = parser->previous;
|
||||||
int index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
int index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
||||||
emitCode(OP_BUILD_ATTR_PTR, index);
|
emitCode(OP_BUILD_ATTR_REF, index);
|
||||||
if (match(TK("as"))) {
|
if (match(TK("as"))) {
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
tkname = parser->previous;
|
tkname = parser->previous;
|
||||||
}
|
}
|
||||||
index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
||||||
emitCode(OP_STORE_NAME_PTR, index);
|
emitCode(OP_STORE_NAME_REF, index);
|
||||||
} while (match(TK(",")));
|
} while (match(TK(",")));
|
||||||
emitCode(OP_POP_TOP);
|
emitCode(OP_POP_TOP);
|
||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
@ -5916,11 +5923,11 @@ __LISTCOMP:
|
|||||||
tkname.str(),
|
tkname.str(),
|
||||||
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
||||||
);
|
);
|
||||||
emitCode(OP_STORE_NAME_PTR, index);
|
emitCode(OP_STORE_NAME_REF, index);
|
||||||
emitCode(OP_LOAD_NAME_PTR, index);
|
emitCode(OP_LOAD_NAME_REF, index);
|
||||||
emitCode(OP_WITH_ENTER);
|
emitCode(OP_WITH_ENTER);
|
||||||
compileBlockBody();
|
compileBlockBody();
|
||||||
emitCode(OP_LOAD_NAME_PTR, index);
|
emitCode(OP_LOAD_NAME_REF, index);
|
||||||
emitCode(OP_WITH_EXIT);
|
emitCode(OP_WITH_EXIT);
|
||||||
} else if(match(TK("label"))){
|
} else if(match(TK("label"))){
|
||||||
if(mode() != EXEC_MODE) syntaxError("'label' is only available in EXEC_MODE");
|
if(mode() != EXEC_MODE) syntaxError("'label' is only available in EXEC_MODE");
|
||||||
@ -5942,7 +5949,7 @@ __LISTCOMP:
|
|||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
} else if(match(TK("del"))){
|
} else if(match(TK("del"))){
|
||||||
EXPR();
|
EXPR();
|
||||||
emitCode(OP_DELETE_PTR);
|
emitCode(OP_DELETE_REF);
|
||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
} else if(match(TK("global"))){
|
} else if(match(TK("global"))){
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
@ -5956,7 +5963,7 @@ __LISTCOMP:
|
|||||||
|
|
||||||
// If last op is not an assignment, pop the result.
|
// If last op is not an assignment, pop the result.
|
||||||
uint8_t lastOp = getCode()->co_code.back().op;
|
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){
|
if(mode()==SINGLE_MODE && parser->indents.top() == 0){
|
||||||
emitCode(OP_PRINT_EXPR);
|
emitCode(OP_PRINT_EXPR);
|
||||||
}
|
}
|
||||||
@ -5980,7 +5987,7 @@ __LISTCOMP:
|
|||||||
isCompilingClass = false;
|
isCompilingClass = false;
|
||||||
|
|
||||||
if(superClsNameIdx == -1) emitCode(OP_LOAD_NONE);
|
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);
|
emitCode(OP_BUILD_CLASS, clsNameIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6207,13 +6214,13 @@ __NOT_ENOUGH_LINES:
|
|||||||
|
|
||||||
|
|
||||||
#define BIND_NUM_ARITH_OPT(name, op) \
|
#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])) \
|
if(!vm->isIntOrFloat(args[0], args[1])) \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
vm->typeError("unsupported operand type(s) for " #op ); \
|
||||||
if(args[0]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){ \
|
if(args._index(0)->isType(vm->_tp_int) && args._index(1)->isType(vm->_tp_int)){ \
|
||||||
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
|
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \
|
||||||
}else{ \
|
}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]); \
|
if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
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) {
|
_vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
||||||
vm->typeError("unsupported operand type(s) for " "//" );
|
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();
|
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) {
|
_vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
||||||
vm->typeError("unsupported operand type(s) for " "%" );
|
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();
|
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) {
|
_vm->bindMethod("int", "__repr__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
@ -6429,10 +6436,10 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#define __INT_BITWISE_OP(name,op) \
|
#define __INT_BITWISE_OP(name,op) \
|
||||||
_vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \
|
_vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \
|
||||||
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \
|
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
vm->typeError("unsupported operand type(s) for " #op ); \
|
||||||
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
|
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \
|
||||||
});
|
});
|
||||||
|
|
||||||
__INT_BITWISE_OP(__lshift__, <<)
|
__INT_BITWISE_OP(__lshift__, <<)
|
||||||
@ -6443,12 +6450,6 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
#undef __INT_BITWISE_OP
|
#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 ************/
|
/************ PyFloat ************/
|
||||||
_vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(args.size() == 0) return vm->PyFloat(0.0);
|
if(args.size() == 0) return vm->PyFloat(0.0);
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit eaeddb40e8691f6fbc8419da1d4996583aef07a8
|
Subproject commit d8e7e9986433707a21b796d510cccb6f098cf91c
|
@ -37,7 +37,7 @@
|
|||||||
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
#define UNREACHABLE() throw std::runtime_error( __FILE__ + std::string(":") + std::to_string(__LINE__) + " UNREACHABLE()!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PK_VERSION "0.4.8"
|
#define PK_VERSION "0.5.0"
|
||||||
|
|
||||||
//#define PKPY_NO_TYPE_CHECK
|
//#define PKPY_NO_TYPE_CHECK
|
||||||
//#define PKPY_NO_INDEX_CHECK
|
//#define PKPY_NO_INDEX_CHECK
|
||||||
@ -2277,7 +2277,7 @@ private:
|
|||||||
struct PyObject;
|
struct PyObject;
|
||||||
typedef pkpy::shared_ptr<PyObject> PyVar;
|
typedef pkpy::shared_ptr<PyObject> PyVar;
|
||||||
typedef PyVar PyVarOrNull;
|
typedef PyVar PyVarOrNull;
|
||||||
typedef PyVar VarRef;
|
typedef PyVar PyVarRef;
|
||||||
|
|
||||||
class PyVarList: public std::vector<PyVar> {
|
class PyVarList: public std::vector<PyVar> {
|
||||||
PyVar& at(size_t) = delete;
|
PyVar& at(size_t) = delete;
|
||||||
@ -2410,6 +2410,10 @@ namespace pkpy {
|
|||||||
return _args[i];
|
return _args[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const PyVar& _index(uint8_t i) const {
|
||||||
|
return _args[i];
|
||||||
|
}
|
||||||
|
|
||||||
// overload = for &&
|
// overload = for &&
|
||||||
ArgList& operator=(ArgList&& other){
|
ArgList& operator=(ArgList&& other){
|
||||||
if(this != &other){
|
if(this != &other){
|
||||||
@ -2992,7 +2996,7 @@ typedef int64_t _Int;
|
|||||||
typedef double _Float;
|
typedef double _Float;
|
||||||
|
|
||||||
struct CodeObject;
|
struct CodeObject;
|
||||||
struct BasePointer;
|
struct BaseRef;
|
||||||
class VM;
|
class VM;
|
||||||
class Frame;
|
class Frame;
|
||||||
|
|
||||||
@ -3045,7 +3049,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
virtual PyVar next() = 0;
|
virtual PyVar next() = 0;
|
||||||
virtual bool hasNext() = 0;
|
virtual bool hasNext() = 0;
|
||||||
VarRef var;
|
PyVarRef var;
|
||||||
BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
|
BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
|
||||||
virtual ~BaseIterator() = default;
|
virtual ~BaseIterator() = default;
|
||||||
};
|
};
|
||||||
@ -3447,11 +3451,11 @@ struct Parser {
|
|||||||
|
|
||||||
class Frame;
|
class Frame;
|
||||||
|
|
||||||
struct BasePointer {
|
struct BaseRef {
|
||||||
virtual PyVar get(VM*, Frame*) const = 0;
|
virtual PyVar get(VM*, Frame*) const = 0;
|
||||||
virtual void set(VM*, Frame*, PyVar) const = 0;
|
virtual void set(VM*, Frame*, PyVar) const = 0;
|
||||||
virtual void del(VM*, Frame*) const = 0;
|
virtual void del(VM*, Frame*) const = 0;
|
||||||
virtual ~BasePointer() = default;
|
virtual ~BaseRef() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NameScope {
|
enum NameScope {
|
||||||
@ -3460,49 +3464,49 @@ enum NameScope {
|
|||||||
NAME_ATTR = 2,
|
NAME_ATTR = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NamePointer : BasePointer {
|
struct NameRef : BaseRef {
|
||||||
const std::pair<_Str, NameScope>* pair;
|
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;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AttrPointer : BasePointer {
|
struct AttrRef : BaseRef {
|
||||||
mutable PyVar obj;
|
mutable PyVar obj;
|
||||||
const NamePointer attr;
|
const NameRef attr;
|
||||||
AttrPointer(PyVar obj, const NamePointer attr) : obj(obj), attr(attr) {}
|
AttrRef(PyVar obj, const NameRef attr) : obj(obj), attr(attr) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexPointer : BasePointer {
|
struct IndexRef : BaseRef {
|
||||||
mutable PyVar obj;
|
mutable PyVar obj;
|
||||||
PyVar index;
|
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;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompoundPointer : BasePointer {
|
struct TupleRef : BaseRef {
|
||||||
PyVarList varRefs;
|
PyVarList varRefs;
|
||||||
CompoundPointer(const PyVarList& varRefs) : varRefs(varRefs) {}
|
TupleRef(const PyVarList& varRefs) : varRefs(varRefs) {}
|
||||||
CompoundPointer(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {}
|
TupleRef(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {}
|
||||||
|
|
||||||
PyVar get(VM* vm, Frame* frame) const;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
void del(VM* vm, Frame* frame) const;
|
void del(VM* vm, Frame* frame) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UserPointer : BasePointer {
|
struct UserPointer : BaseRef {
|
||||||
VarRef p;
|
PyVarRef p;
|
||||||
uint64_t f_id;
|
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;
|
PyVar get(VM* vm, Frame* frame) const;
|
||||||
void set(VM* vm, Frame* frame, PyVar val) const;
|
void set(VM* vm, Frame* frame, PyVar val) const;
|
||||||
@ -3563,13 +3567,13 @@ OPCODE(RAISE_ERROR)
|
|||||||
OPCODE(STORE_FUNCTION)
|
OPCODE(STORE_FUNCTION)
|
||||||
OPCODE(BUILD_CLASS)
|
OPCODE(BUILD_CLASS)
|
||||||
|
|
||||||
OPCODE(LOAD_NAME_PTR) // no arg
|
OPCODE(LOAD_NAME_REF) // no arg
|
||||||
OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
||||||
OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr]
|
OPCODE(BUILD_INDEX_REF) // 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_NAME_REF) // 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(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr
|
||||||
OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr
|
OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr
|
||||||
OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_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_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
|
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(STORE_FUNCTION)
|
||||||
OPCODE(BUILD_CLASS)
|
OPCODE(BUILD_CLASS)
|
||||||
|
|
||||||
OPCODE(LOAD_NAME_PTR) // no arg
|
OPCODE(LOAD_NAME_REF) // no arg
|
||||||
OPCODE(BUILD_ATTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
OPCODE(BUILD_ATTR_REF) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr).name_ptr
|
||||||
OPCODE(BUILD_INDEX_PTR) // no arg, [ptr, expr] -> (*ptr)[expr]
|
OPCODE(BUILD_INDEX_REF) // 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_NAME_REF) // 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(STORE_REF) // no arg, [ptr, expr] -> *ptr = expr
|
||||||
OPCODE(DELETE_PTR) // no arg, [ptr] -> [] -> delete ptr
|
OPCODE(DELETE_REF) // no arg, [ptr] -> [] -> delete ptr
|
||||||
OPCODE(BUILD_ATTR_PTR_PTR) // arg for the name_ptr, [ptr, name_ptr] -> (*ptr)->name_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_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
|
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);
|
setAttr(obj, __module__, frame->_module);
|
||||||
frame->push(obj);
|
frame->push(obj);
|
||||||
} break;
|
} break;
|
||||||
case OP_LOAD_NAME_PTR: {
|
case OP_LOAD_NAME_REF: {
|
||||||
frame->push(PyPointer(NamePointer(
|
frame->push(PyRef(NameRef(
|
||||||
&(frame->code->co_names[byte.arg])
|
&(frame->code->co_names[byte.arg])
|
||||||
)));
|
)));
|
||||||
} break;
|
} break;
|
||||||
case OP_STORE_NAME_PTR: {
|
case OP_STORE_NAME_REF: {
|
||||||
const auto& p = frame->code->co_names[byte.arg];
|
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;
|
} break;
|
||||||
case OP_BUILD_ATTR_PTR: {
|
case OP_BUILD_ATTR_REF: {
|
||||||
const auto& attr = frame->code->co_names[byte.arg];
|
const auto& attr = frame->code->co_names[byte.arg];
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
frame->push(PyPointer(AttrPointer(obj, NamePointer(&attr))));
|
frame->push(PyRef(AttrRef(obj, NameRef(&attr))));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_ATTR_PTR_PTR: {
|
case OP_BUILD_ATTR_REF_PTR: {
|
||||||
const auto& attr = frame->code->co_names[byte.arg];
|
const auto& attr = frame->code->co_names[byte.arg];
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
__checkType(obj, _tp_user_pointer);
|
__checkType(obj, _tp_user_pointer);
|
||||||
const VarRef& var = UNION_GET(VarRef, obj);
|
const PyVarRef& var = UNION_GET(PyVarRef, obj);
|
||||||
auto p = PyPointer_AS_C(var);
|
auto p = PyRef_AS_C(var);
|
||||||
frame->push(PyPointer(AttrPointer(p->get(this, frame), &attr)));
|
frame->push(PyRef(AttrRef(p->get(this, frame), &attr)));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_INDEX_PTR: {
|
case OP_BUILD_INDEX_REF: {
|
||||||
PyVar index = frame->popValue(this);
|
PyVar index = frame->popValue(this);
|
||||||
VarRef obj = frame->popValue(this);
|
PyVarRef obj = frame->popValue(this);
|
||||||
frame->push(PyPointer(IndexPointer(obj, index)));
|
frame->push(PyRef(IndexRef(obj, index)));
|
||||||
} break;
|
} break;
|
||||||
case OP_STORE_PTR: {
|
case OP_STORE_REF: {
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
VarRef r = frame->__pop();
|
PyVarRef r = frame->__pop();
|
||||||
PyPointer_AS_C(r)->set(this, frame, std::move(obj));
|
PyRef_AS_C(r)->set(this, frame, std::move(obj));
|
||||||
} break;
|
} break;
|
||||||
case OP_DELETE_PTR: {
|
case OP_DELETE_REF: {
|
||||||
VarRef r = frame->__pop();
|
PyVarRef r = frame->__pop();
|
||||||
PyPointer_AS_C(r)->del(this, frame);
|
PyRef_AS_C(r)->del(this, frame);
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_SMART_TUPLE:
|
case OP_BUILD_SMART_TUPLE:
|
||||||
{
|
{
|
||||||
pkpy::ArgList items = frame->__popNReversed(byte.arg);
|
pkpy::ArgList items = frame->__popNReversed(byte.arg);
|
||||||
bool done = false;
|
bool done = false;
|
||||||
for(int i=0; i<items.size(); i++){
|
for(int i=0; i<items.size(); i++){
|
||||||
if(!items[i]->isType(_tp_pointer)) {
|
if(!items[i]->isType(_tp_ref)) {
|
||||||
done = true;
|
done = true;
|
||||||
PyVarList values(items.size());
|
PyVarList values(items.size());
|
||||||
for(int i=0; i<items.size(); i++){
|
for(int i=0; i<items.size(); i++){
|
||||||
@ -3986,7 +3990,7 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(done) break;
|
if(done) break;
|
||||||
frame->push(PyPointer(CompoundPointer(items.toList())));
|
frame->push(PyRef(TupleRef(items.toList())));
|
||||||
} break;
|
} break;
|
||||||
case OP_BUILD_STRING:
|
case OP_BUILD_STRING:
|
||||||
{
|
{
|
||||||
@ -4037,20 +4041,23 @@ protected:
|
|||||||
case OP_POP_TOP: frame->popValue(this); break;
|
case OP_POP_TOP: frame->popValue(this); break;
|
||||||
case OP_BINARY_OP:
|
case OP_BINARY_OP:
|
||||||
{
|
{
|
||||||
pkpy::ArgList args = frame->popNValuesReversed(this, 2);
|
frame->push(
|
||||||
frame->push(fastCall(BINARY_SPECIAL_METHODS[byte.arg], std::move(args)));
|
fastCall(BINARY_SPECIAL_METHODS[byte.arg],
|
||||||
|
frame->popNValuesReversed(this, 2))
|
||||||
|
);
|
||||||
} break;
|
} break;
|
||||||
case OP_BITWISE_OP:
|
case OP_BITWISE_OP:
|
||||||
{
|
{
|
||||||
pkpy::ArgList args = frame->popNValuesReversed(this, 2);
|
frame->push(
|
||||||
frame->push(fastCall(BITWISE_SPECIAL_METHODS[byte.arg], std::move(args)));
|
fastCall(BITWISE_SPECIAL_METHODS[byte.arg],
|
||||||
|
frame->popNValuesReversed(this, 2))
|
||||||
|
);
|
||||||
} break;
|
} break;
|
||||||
case OP_COMPARE_OP:
|
case OP_COMPARE_OP:
|
||||||
{
|
{
|
||||||
pkpy::ArgList args = frame->popNValuesReversed(this, 2);
|
|
||||||
// for __ne__ we use the negation of __eq__
|
// for __ne__ we use the negation of __eq__
|
||||||
int op = byte.arg == 3 ? 2 : byte.arg;
|
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));
|
if(op != byte.arg) res = PyBool(!PyBool_AS_C(res));
|
||||||
frame->push(std::move(res));
|
frame->push(std::move(res));
|
||||||
} break;
|
} break;
|
||||||
@ -4081,11 +4088,11 @@ protected:
|
|||||||
case OP_UNARY_REF:
|
case OP_UNARY_REF:
|
||||||
{
|
{
|
||||||
// _pointer to pointer
|
// _pointer to pointer
|
||||||
VarRef obj = frame->__pop();
|
PyVarRef obj = frame->__pop();
|
||||||
__checkType(obj, _tp_pointer);
|
__checkType(obj, _tp_ref);
|
||||||
frame->push(newObject(
|
frame->push(newObject(
|
||||||
_tp_user_pointer,
|
_tp_user_pointer,
|
||||||
PyPointer(UserPointer(obj, frame->id))
|
PyRef(UserPointer(obj, frame->id))
|
||||||
));
|
));
|
||||||
} break;
|
} break;
|
||||||
case OP_UNARY_DEREF:
|
case OP_UNARY_DEREF:
|
||||||
@ -4093,7 +4100,7 @@ protected:
|
|||||||
// pointer to _pointer
|
// pointer to _pointer
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
__checkType(obj, _tp_user_pointer);
|
__checkType(obj, _tp_user_pointer);
|
||||||
frame->push(UNION_GET(VarRef, obj));
|
frame->push(UNION_GET(PyVarRef, obj));
|
||||||
} break;
|
} break;
|
||||||
case OP_POP_JUMP_IF_FALSE:
|
case OP_POP_JUMP_IF_FALSE:
|
||||||
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
|
||||||
@ -4145,11 +4152,11 @@ protected:
|
|||||||
case OP_GOTO: {
|
case OP_GOTO: {
|
||||||
PyVar obj = frame->popValue(this);
|
PyVar obj = frame->popValue(this);
|
||||||
const _Str& label = PyStr_AS_C(obj);
|
const _Str& label = PyStr_AS_C(obj);
|
||||||
auto it = frame->code->co_labels.find(label);
|
int* target = frame->code->co_labels.try_get(label);
|
||||||
if(it == frame->code->co_labels.end()){
|
if(target == nullptr){
|
||||||
_error("KeyError", "label '" + label + "' not found");
|
_error("KeyError", "label '" + label + "' not found");
|
||||||
}
|
}
|
||||||
frame->safeJump(it->second);
|
frame->safeJump(*target);
|
||||||
} break;
|
} break;
|
||||||
case OP_GET_ITER:
|
case OP_GET_ITER:
|
||||||
{
|
{
|
||||||
@ -4157,8 +4164,8 @@ protected:
|
|||||||
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
|
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
|
||||||
if(iter_fn != nullptr){
|
if(iter_fn != nullptr){
|
||||||
PyVar tmp = call(iter_fn, pkpy::oneArg(obj));
|
PyVar tmp = call(iter_fn, pkpy::oneArg(obj));
|
||||||
VarRef var = frame->__pop();
|
PyVarRef var = frame->__pop();
|
||||||
__checkType(var, _tp_pointer);
|
__checkType(var, _tp_ref);
|
||||||
PyIter_AS_C(tmp)->var = var;
|
PyIter_AS_C(tmp)->var = var;
|
||||||
frame->push(std::move(tmp));
|
frame->push(std::move(tmp));
|
||||||
}else{
|
}else{
|
||||||
@ -4171,7 +4178,7 @@ protected:
|
|||||||
// __top() must be PyIter, so no need to __deref()
|
// __top() must be PyIter, so no need to __deref()
|
||||||
auto& it = PyIter_AS_C(frame->__top());
|
auto& it = PyIter_AS_C(frame->__top());
|
||||||
if(it->hasNext()){
|
if(it->hasNext()){
|
||||||
PyPointer_AS_C(it->var)->set(this, frame, it->next());
|
PyRef_AS_C(it->var)->set(this, frame, it->next());
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
frame->safeJump(byte.arg);
|
frame->safeJump(byte.arg);
|
||||||
@ -4321,8 +4328,8 @@ public:
|
|||||||
PyVar fastCall(const _Str& name, pkpy::ArgList&& args){
|
PyVar fastCall(const _Str& name, pkpy::ArgList&& args){
|
||||||
PyObject* cls = args[0]->_type.get();
|
PyObject* cls = args[0]->_type.get();
|
||||||
while(cls != None.get()) {
|
while(cls != None.get()) {
|
||||||
auto it = cls->attribs.find(name);
|
PyVar* val = cls->attribs.try_get(name);
|
||||||
if(it != cls->attribs.end()) return call(it->second, std::move(args));
|
if(val != nullptr) return call(*val, std::move(args));
|
||||||
cls = cls->attribs[__base__].get();
|
cls = cls->attribs[__base__].get();
|
||||||
}
|
}
|
||||||
attributeError(args[0], name);
|
attributeError(args[0], name);
|
||||||
@ -4412,7 +4419,7 @@ public:
|
|||||||
|
|
||||||
for(int i=0; i<kwargs.size(); i+=2){
|
for(int i=0; i<kwargs.size(); i+=2){
|
||||||
const _Str& key = PyStr_AS_C(kwargs[i]);
|
const _Str& key = PyStr_AS_C(kwargs[i]);
|
||||||
if(fn->kwArgs.find(key) == fn->kwArgs.end()){
|
if(!fn->kwArgs.contains(key)){
|
||||||
typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()");
|
typeError(key.__escape(true) + " is an invalid keyword argument for " + fn->name + "()");
|
||||||
}
|
}
|
||||||
const PyVar& val = kwargs[i+1];
|
const PyVar& val = kwargs[i+1];
|
||||||
@ -4425,8 +4432,8 @@ public:
|
|||||||
locals[key] = val;
|
locals[key] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it_m = (*callable)->attribs.find(__module__);
|
PyVar* it_m = (*callable)->attribs.try_get(__module__);
|
||||||
PyVar _module = it_m != (*callable)->attribs.end() ? it_m->second : topFrame()->_module;
|
PyVar _module = it_m != nullptr ? *it_m : topFrame()->_module;
|
||||||
if(opCall){
|
if(opCall){
|
||||||
__pushNewFrame(fn->code, _module, std::move(locals));
|
__pushNewFrame(fn->code, _module, std::move(locals));
|
||||||
return __py2py_call_signal;
|
return __py2py_call_signal;
|
||||||
@ -4661,19 +4668,19 @@ public:
|
|||||||
PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str;
|
PyVar _tp_object, _tp_type, _tp_int, _tp_float, _tp_bool, _tp_str;
|
||||||
PyVar _tp_list, _tp_tuple;
|
PyVar _tp_list, _tp_tuple;
|
||||||
PyVar _tp_function, _tp_native_function, _tp_native_iterator, _tp_bounded_method;
|
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;
|
PyVar _tp_user_pointer, _tp_super;
|
||||||
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
inline VarRef PyPointer(P value) {
|
inline PyVarRef PyRef(P&& value) {
|
||||||
static_assert(std::is_base_of<BasePointer, P>::value, "P should derive from BasePointer");
|
static_assert(std::is_base_of<BaseRef, P>::value, "P should derive from BaseRef");
|
||||||
return newObject(_tp_pointer, value);
|
return newObject(_tp_ref, std::forward<P>(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");
|
if(!obj->isType(_tp_ref)) typeError("expected an l-value");
|
||||||
return (const BasePointer*)(obj->value());
|
return (const BaseRef*)(obj->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
__DEF_PY_AS_C(Int, _Int, _tp_int)
|
||||||
@ -4713,7 +4720,7 @@ public:
|
|||||||
_tp_slice = newClassType("slice");
|
_tp_slice = newClassType("slice");
|
||||||
_tp_range = newClassType("range");
|
_tp_range = newClassType("range");
|
||||||
_tp_module = newClassType("module");
|
_tp_module = newClassType("module");
|
||||||
_tp_pointer = newClassType("_pointer");
|
_tp_ref = newClassType("_pointer");
|
||||||
_tp_user_pointer = newClassType("pointer");
|
_tp_user_pointer = newClassType("pointer");
|
||||||
|
|
||||||
newClassType("NoneType");
|
newClassType("NoneType");
|
||||||
@ -4848,18 +4855,18 @@ public:
|
|||||||
|
|
||||||
/***** Pointers' Impl *****/
|
/***** Pointers' Impl *****/
|
||||||
|
|
||||||
PyVar NamePointer::get(VM* vm, Frame* frame) const{
|
PyVar NameRef::get(VM* vm, Frame* frame) const{
|
||||||
auto it = frame->f_locals.find(pair->first);
|
PyVar* val = frame->f_locals.try_get(pair->first);
|
||||||
if(it != frame->f_locals.end()) return it->second;
|
if(val) return *val;
|
||||||
it = frame->f_globals().find(pair->first);
|
val = frame->f_globals().try_get(pair->first);
|
||||||
if(it != frame->f_globals().end()) return it->second;
|
if(val) return *val;
|
||||||
it = vm->builtins->attribs.find(pair->first);
|
val = vm->builtins->attribs.try_get(pair->first);
|
||||||
if(it != vm->builtins->attribs.end()) return it->second;
|
if(val) return *val;
|
||||||
vm->nameError(pair->first);
|
vm->nameError(pair->first);
|
||||||
return nullptr;
|
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) {
|
switch(pair->second) {
|
||||||
case NAME_LOCAL: frame->f_locals[pair->first] = std::move(val); break;
|
case NAME_LOCAL: frame->f_locals[pair->first] = std::move(val); break;
|
||||||
case NAME_GLOBAL:
|
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) {
|
switch(pair->second) {
|
||||||
case NAME_LOCAL: {
|
case NAME_LOCAL: {
|
||||||
if(frame->f_locals.count(pair->first) > 0){
|
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);
|
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);
|
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");
|
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));
|
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));
|
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));
|
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());
|
PyVarList args(varRefs.size());
|
||||||
for (int i = 0; i < varRefs.size(); i++) {
|
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);
|
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)){
|
if(!val->isType(vm->_tp_tuple) && !val->isType(vm->_tp_list)){
|
||||||
vm->typeError("only tuple or list can be unpacked");
|
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("too many values to unpack");
|
||||||
if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack");
|
if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack");
|
||||||
for (int i = 0; i < varRefs.size(); i++) {
|
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{
|
void TupleRef::del(VM* vm, Frame* frame) const{
|
||||||
for (auto& r : varRefs) vm->PyPointer_AS_C(r)->del(vm, frame);
|
for (auto& r : varRefs) vm->PyRef_AS_C(r)->del(vm, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar UserPointer::get(VM* vm, Frame* frame) const{
|
PyVar UserPointer::get(VM* vm, Frame* frame) const{
|
||||||
frame = vm->__findFrame(f_id);
|
frame = vm->__findFrame(f_id);
|
||||||
if(frame == nullptr) vm->nullPointerError();
|
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{
|
void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
|
||||||
frame = vm->__findFrame(f_id);
|
frame = vm->__findFrame(f_id);
|
||||||
if(frame == nullptr) vm->nullPointerError();
|
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{
|
void UserPointer::del(VM* vm, Frame* frame) const{
|
||||||
@ -4965,7 +4972,7 @@ void UserPointer::del(VM* vm, Frame* frame) const{
|
|||||||
|
|
||||||
/***** Frame's Impl *****/
|
/***** Frame's Impl *****/
|
||||||
inline PyVar Frame::__deref_pointer(VM* vm, PyVar v){
|
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;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5336,7 +5343,7 @@ public:
|
|||||||
if(parser->matchChar('\'')) {eatString('\'', true); return;}
|
if(parser->matchChar('\'')) {eatString('\'', true); return;}
|
||||||
if(parser->matchChar('"')) {eatString('"', true); return;}
|
if(parser->matchChar('"')) {eatString('"', true); return;}
|
||||||
}
|
}
|
||||||
if (isdigit(c)) {
|
if (c >= '0' && c <= '9') {
|
||||||
eatNumber();
|
eatNumber();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -5464,7 +5471,7 @@ public:
|
|||||||
_TokenType op = parser->previous.type;
|
_TokenType op = parser->previous.type;
|
||||||
if(op == TK("=")) { // a = (expr)
|
if(op == TK("=")) { // a = (expr)
|
||||||
EXPR_TUPLE();
|
EXPR_TUPLE();
|
||||||
emitCode(OP_STORE_PTR);
|
emitCode(OP_STORE_REF);
|
||||||
}else{ // a += (expr) -> a = a + (expr)
|
}else{ // a += (expr) -> a = a + (expr)
|
||||||
// TODO: optimization is needed for inplace operators
|
// TODO: optimization is needed for inplace operators
|
||||||
emitCode(OP_DUP_TOP);
|
emitCode(OP_DUP_TOP);
|
||||||
@ -5477,7 +5484,7 @@ public:
|
|||||||
case TK("//="): emitCode(OP_BINARY_OP, 4); break;
|
case TK("//="): emitCode(OP_BINARY_OP, 4); break;
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
}
|
}
|
||||||
emitCode(OP_STORE_PTR);
|
emitCode(OP_STORE_REF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5662,21 +5669,21 @@ __LISTCOMP:
|
|||||||
tkname.str(),
|
tkname.str(),
|
||||||
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
||||||
);
|
);
|
||||||
emitCode(OP_LOAD_NAME_PTR, index);
|
emitCode(OP_LOAD_NAME_REF, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exprAttrib() {
|
void exprAttrib() {
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
const _Str& name = parser->previous.str();
|
const _Str& name = parser->previous.str();
|
||||||
int index = getCode()->addName(name, NAME_ATTR);
|
int index = getCode()->addName(name, NAME_ATTR);
|
||||||
emitCode(OP_BUILD_ATTR_PTR, index);
|
emitCode(OP_BUILD_ATTR_REF, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exprAttribPtr(){
|
void exprAttribPtr(){
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
const _Str& name = parser->previous.str();
|
const _Str& name = parser->previous.str();
|
||||||
int index = getCode()->addName(name, NAME_ATTR);
|
int index = getCode()->addName(name, NAME_ATTR);
|
||||||
emitCode(OP_BUILD_ATTR_PTR_PTR, index);
|
emitCode(OP_BUILD_ATTR_REF_PTR, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [:], [:b]
|
// [:], [:b]
|
||||||
@ -5706,7 +5713,7 @@ __LISTCOMP:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitCode(OP_BUILD_INDEX_PTR);
|
emitCode(OP_BUILD_INDEX_REF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exprValue() {
|
void exprValue() {
|
||||||
@ -5773,7 +5780,7 @@ __LISTCOMP:
|
|||||||
tkmodule = parser->previous;
|
tkmodule = parser->previous;
|
||||||
}
|
}
|
||||||
int index = getCode()->addName(tkmodule.str(), NAME_GLOBAL);
|
int index = getCode()->addName(tkmodule.str(), NAME_GLOBAL);
|
||||||
emitCode(OP_STORE_NAME_PTR, index);
|
emitCode(OP_STORE_NAME_REF, index);
|
||||||
} while (match(TK(",")));
|
} while (match(TK(",")));
|
||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
}
|
}
|
||||||
@ -5787,13 +5794,13 @@ __LISTCOMP:
|
|||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
Token tkname = parser->previous;
|
Token tkname = parser->previous;
|
||||||
int index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
int index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
||||||
emitCode(OP_BUILD_ATTR_PTR, index);
|
emitCode(OP_BUILD_ATTR_REF, index);
|
||||||
if (match(TK("as"))) {
|
if (match(TK("as"))) {
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
tkname = parser->previous;
|
tkname = parser->previous;
|
||||||
}
|
}
|
||||||
index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
index = getCode()->addName(tkname.str(), NAME_GLOBAL);
|
||||||
emitCode(OP_STORE_NAME_PTR, index);
|
emitCode(OP_STORE_NAME_REF, index);
|
||||||
} while (match(TK(",")));
|
} while (match(TK(",")));
|
||||||
emitCode(OP_POP_TOP);
|
emitCode(OP_POP_TOP);
|
||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
@ -5916,11 +5923,11 @@ __LISTCOMP:
|
|||||||
tkname.str(),
|
tkname.str(),
|
||||||
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
|
||||||
);
|
);
|
||||||
emitCode(OP_STORE_NAME_PTR, index);
|
emitCode(OP_STORE_NAME_REF, index);
|
||||||
emitCode(OP_LOAD_NAME_PTR, index);
|
emitCode(OP_LOAD_NAME_REF, index);
|
||||||
emitCode(OP_WITH_ENTER);
|
emitCode(OP_WITH_ENTER);
|
||||||
compileBlockBody();
|
compileBlockBody();
|
||||||
emitCode(OP_LOAD_NAME_PTR, index);
|
emitCode(OP_LOAD_NAME_REF, index);
|
||||||
emitCode(OP_WITH_EXIT);
|
emitCode(OP_WITH_EXIT);
|
||||||
} else if(match(TK("label"))){
|
} else if(match(TK("label"))){
|
||||||
if(mode() != EXEC_MODE) syntaxError("'label' is only available in EXEC_MODE");
|
if(mode() != EXEC_MODE) syntaxError("'label' is only available in EXEC_MODE");
|
||||||
@ -5942,7 +5949,7 @@ __LISTCOMP:
|
|||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
} else if(match(TK("del"))){
|
} else if(match(TK("del"))){
|
||||||
EXPR();
|
EXPR();
|
||||||
emitCode(OP_DELETE_PTR);
|
emitCode(OP_DELETE_REF);
|
||||||
consumeEndStatement();
|
consumeEndStatement();
|
||||||
} else if(match(TK("global"))){
|
} else if(match(TK("global"))){
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
@ -5956,7 +5963,7 @@ __LISTCOMP:
|
|||||||
|
|
||||||
// If last op is not an assignment, pop the result.
|
// If last op is not an assignment, pop the result.
|
||||||
uint8_t lastOp = getCode()->co_code.back().op;
|
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){
|
if(mode()==SINGLE_MODE && parser->indents.top() == 0){
|
||||||
emitCode(OP_PRINT_EXPR);
|
emitCode(OP_PRINT_EXPR);
|
||||||
}
|
}
|
||||||
@ -5980,7 +5987,7 @@ __LISTCOMP:
|
|||||||
isCompilingClass = false;
|
isCompilingClass = false;
|
||||||
|
|
||||||
if(superClsNameIdx == -1) emitCode(OP_LOAD_NONE);
|
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);
|
emitCode(OP_BUILD_CLASS, clsNameIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6207,13 +6214,13 @@ __NOT_ENOUGH_LINES:
|
|||||||
|
|
||||||
|
|
||||||
#define BIND_NUM_ARITH_OPT(name, op) \
|
#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])) \
|
if(!vm->isIntOrFloat(args[0], args[1])) \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
vm->typeError("unsupported operand type(s) for " #op ); \
|
||||||
if(args[0]->isType(vm->_tp_int) && args[1]->isType(vm->_tp_int)){ \
|
if(args._index(0)->isType(vm->_tp_int) && args._index(1)->isType(vm->_tp_int)){ \
|
||||||
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
|
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \
|
||||||
}else{ \
|
}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]); \
|
if constexpr(is_eq) return vm->PyBool(args[0] == args[1]); \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
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) {
|
_vm->bindMethod("int", "__floordiv__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
||||||
vm->typeError("unsupported operand type(s) for " "//" );
|
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();
|
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) {
|
_vm->bindMethod("int", "__mod__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int))
|
||||||
vm->typeError("unsupported operand type(s) for " "%" );
|
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();
|
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) {
|
_vm->bindMethod("int", "__repr__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
@ -6429,10 +6436,10 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#define __INT_BITWISE_OP(name,op) \
|
#define __INT_BITWISE_OP(name,op) \
|
||||||
_vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \
|
_vm->bindMethod("int", #name, [](VM* vm, const pkpy::ArgList& args) { \
|
||||||
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \
|
if(!args[0]->isType(vm->_tp_int) || !args[1]->isType(vm->_tp_int)) \
|
||||||
vm->typeError("unsupported operand type(s) for " #op ); \
|
vm->typeError("unsupported operand type(s) for " #op ); \
|
||||||
return vm->PyInt(vm->PyInt_AS_C(args[0]) op vm->PyInt_AS_C(args[1])); \
|
return vm->PyInt(vm->PyInt_AS_C(args._index(0)) op vm->PyInt_AS_C(args._index(1))); \
|
||||||
});
|
});
|
||||||
|
|
||||||
__INT_BITWISE_OP(__lshift__, <<)
|
__INT_BITWISE_OP(__lshift__, <<)
|
||||||
@ -6443,12 +6450,6 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
|
|
||||||
#undef __INT_BITWISE_OP
|
#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 ************/
|
/************ PyFloat ************/
|
||||||
_vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
_vm->bindMethod("float", "__new__", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
if(args.size() == 0) return vm->PyFloat(0.0);
|
if(args.size() == 0) return vm->PyFloat(0.0);
|
||||||
|
@ -266,7 +266,7 @@ public:
|
|||||||
if(parser->matchChar('\'')) {eatString('\'', true); return;}
|
if(parser->matchChar('\'')) {eatString('\'', true); return;}
|
||||||
if(parser->matchChar('"')) {eatString('"', true); return;}
|
if(parser->matchChar('"')) {eatString('"', true); return;}
|
||||||
}
|
}
|
||||||
if (isdigit(c)) {
|
if (c >= '0' && c <= '9') {
|
||||||
eatNumber();
|
eatNumber();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user