mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
refactor
This commit is contained in:
parent
4083d16a38
commit
c4b3d2bb5f
@ -44,7 +44,6 @@ The features marked with `YES` are supported, and the features marked with `NO`
|
||||
+ `__iter__`
|
||||
+ `__next__`
|
||||
+ `__neg__`
|
||||
+ `__bool__` (unused)
|
||||
|
||||
#### Logical operators
|
||||
|
||||
|
@ -176,12 +176,11 @@ struct CString{
|
||||
// unary operators
|
||||
const StrName __repr__ = StrName::get("__repr__");
|
||||
const StrName __str__ = StrName::get("__str__");
|
||||
const StrName __hash__ = StrName::get("__hash__"); // unused
|
||||
const StrName __hash__ = StrName::get("__hash__");
|
||||
const StrName __len__ = StrName::get("__len__");
|
||||
const StrName __iter__ = StrName::get("__iter__");
|
||||
const StrName __next__ = StrName::get("__next__"); // unused
|
||||
const StrName __neg__ = StrName::get("__neg__"); // unused
|
||||
const StrName __bool__ = StrName::get("__bool__"); // unused
|
||||
const StrName __next__ = StrName::get("__next__");
|
||||
const StrName __neg__ = StrName::get("__neg__");
|
||||
// logical operators
|
||||
const StrName __eq__ = StrName::get("__eq__");
|
||||
const StrName __lt__ = StrName::get("__lt__");
|
||||
|
@ -57,7 +57,6 @@ struct PyTypeInfo{
|
||||
PyObject* (*m__iter__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__next__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__neg__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__bool__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__invert__)(VM* vm, PyObject*) = nullptr;
|
||||
|
||||
BinaryFuncC m__eq__ = nullptr;
|
||||
@ -244,60 +243,37 @@ public:
|
||||
Type _new_type_object(StrName name, Type base=0, bool subclass_enabled=false);
|
||||
const PyTypeInfo* _inst_type_info(PyObject* obj);
|
||||
|
||||
#define BIND_UNARY_SPECIAL(name) \
|
||||
void bind##name(Type type, PyObject* (*f)(VM*, PyObject*)){ \
|
||||
_all_types[type].m##name = f; \
|
||||
PyObject* nf = bind_method<0>(_t(type), #name, [](VM* vm, ArgsView args){ \
|
||||
return lambda_get_userdata<PyObject*(*)(VM*, PyObject*)>(args.begin())(vm, args[0]);\
|
||||
}); \
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f); \
|
||||
}
|
||||
|
||||
BIND_UNARY_SPECIAL(__repr__)
|
||||
BIND_UNARY_SPECIAL(__str__)
|
||||
BIND_UNARY_SPECIAL(__iter__)
|
||||
BIND_UNARY_SPECIAL(__next__)
|
||||
BIND_UNARY_SPECIAL(__neg__)
|
||||
BIND_UNARY_SPECIAL(__bool__)
|
||||
BIND_UNARY_SPECIAL(__invert__)
|
||||
|
||||
void bind__repr__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__str__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__iter__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__next__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__neg__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__invert__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__hash__(Type type, i64 (*f)(VM* vm, PyObject*));
|
||||
void bind__len__(Type type, i64 (*f)(VM* vm, PyObject*));
|
||||
#undef BIND_UNARY_SPECIAL
|
||||
|
||||
|
||||
#define BIND_BINARY_SPECIAL(name) \
|
||||
void bind##name(Type type, BinaryFuncC f){ \
|
||||
_all_types[type].m##name = f; \
|
||||
PyObject* nf = bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \
|
||||
return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]);\
|
||||
}); \
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f); \
|
||||
}
|
||||
void bind__eq__(Type type, BinaryFuncC f);
|
||||
void bind__lt__(Type type, BinaryFuncC f);
|
||||
void bind__le__(Type type, BinaryFuncC f);
|
||||
void bind__gt__(Type type, BinaryFuncC f);
|
||||
void bind__ge__(Type type, BinaryFuncC f);
|
||||
void bind__contains__(Type type, BinaryFuncC f);
|
||||
|
||||
BIND_BINARY_SPECIAL(__eq__)
|
||||
BIND_BINARY_SPECIAL(__lt__)
|
||||
BIND_BINARY_SPECIAL(__le__)
|
||||
BIND_BINARY_SPECIAL(__gt__)
|
||||
BIND_BINARY_SPECIAL(__ge__)
|
||||
BIND_BINARY_SPECIAL(__contains__)
|
||||
void bind__add__(Type type, BinaryFuncC f);
|
||||
void bind__sub__(Type type, BinaryFuncC f);
|
||||
void bind__mul__(Type type, BinaryFuncC f);
|
||||
void bind__truediv__(Type type, BinaryFuncC f);
|
||||
void bind__floordiv__(Type type, BinaryFuncC f);
|
||||
void bind__mod__(Type type, BinaryFuncC f);
|
||||
void bind__pow__(Type type, BinaryFuncC f);
|
||||
void bind__matmul__(Type type, BinaryFuncC f);
|
||||
|
||||
BIND_BINARY_SPECIAL(__add__)
|
||||
BIND_BINARY_SPECIAL(__sub__)
|
||||
BIND_BINARY_SPECIAL(__mul__)
|
||||
BIND_BINARY_SPECIAL(__truediv__)
|
||||
BIND_BINARY_SPECIAL(__floordiv__)
|
||||
BIND_BINARY_SPECIAL(__mod__)
|
||||
BIND_BINARY_SPECIAL(__pow__)
|
||||
BIND_BINARY_SPECIAL(__matmul__)
|
||||
|
||||
BIND_BINARY_SPECIAL(__lshift__)
|
||||
BIND_BINARY_SPECIAL(__rshift__)
|
||||
BIND_BINARY_SPECIAL(__and__)
|
||||
BIND_BINARY_SPECIAL(__or__)
|
||||
BIND_BINARY_SPECIAL(__xor__)
|
||||
|
||||
#undef BIND_BINARY_SPECIAL
|
||||
void bind__lshift__(Type type, BinaryFuncC f);
|
||||
void bind__rshift__(Type type, BinaryFuncC f);
|
||||
void bind__and__(Type type, BinaryFuncC f);
|
||||
void bind__or__(Type type, BinaryFuncC f);
|
||||
void bind__xor__(Type type, BinaryFuncC f);
|
||||
|
||||
void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*));
|
||||
void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*));
|
||||
@ -314,19 +290,12 @@ public:
|
||||
template<int ARGC, typename __T>
|
||||
PyObject* bind_constructor(__T&& type, NativeFuncC fn) {
|
||||
static_assert(ARGC==-1 || ARGC>=1);
|
||||
return bind_func<ARGC>(std::forward<__T>(type), "__new__", fn);
|
||||
}
|
||||
|
||||
template<typename T, typename __T>
|
||||
PyObject* bind_default_constructor(__T&& type) {
|
||||
return bind_constructor<1>(std::forward<__T>(type), [](VM* vm, ArgsView args){
|
||||
return vm->heap.gcnew<T>(PK_OBJ_GET(Type, args[0]), T());
|
||||
});
|
||||
return bind_func<ARGC>(std::forward<__T>(type), __new__, fn);
|
||||
}
|
||||
|
||||
template<typename T, typename __T>
|
||||
PyObject* bind_notimplemented_constructor(__T&& type) {
|
||||
return bind_constructor<-1>(std::forward<__T>(type), [](VM* vm, ArgsView args){
|
||||
return bind_func<-1>(std::forward<__T>(type), __new__, [](VM* vm, ArgsView args){
|
||||
vm->NotImplementedError();
|
||||
return vm->None;
|
||||
});
|
||||
@ -357,19 +326,8 @@ public:
|
||||
void KeyError(PyObject* obj){ _builtin_error("KeyError", obj); }
|
||||
void ImportError(const Str& msg){ _builtin_error("ImportError", msg); }
|
||||
|
||||
void BinaryOptError(const char* op, PyObject* _0, PyObject* _1) {
|
||||
StrName name_0 = _type_name(vm, _tp(_0));
|
||||
StrName name_1 = _type_name(vm, _tp(_1));
|
||||
TypeError(_S("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
|
||||
}
|
||||
|
||||
void AttributeError(PyObject* obj, StrName name){
|
||||
if(isinstance(obj, vm->tp_type)){
|
||||
_builtin_error("AttributeError", _S("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
|
||||
}else{
|
||||
_builtin_error("AttributeError", _S(_type_name(vm, _tp(obj)).escape(), " object has no attribute ", name.escape()));
|
||||
}
|
||||
}
|
||||
void BinaryOptError(const char* op, PyObject* _0, PyObject* _1);
|
||||
void AttributeError(PyObject* obj, StrName name);
|
||||
void AttributeError(const Str& msg){ _builtin_error("AttributeError", msg); }
|
||||
|
||||
void check_type(PyObject* obj, Type type){
|
||||
@ -447,11 +405,11 @@ public:
|
||||
PyObject* _format_string(Str, PyObject*);
|
||||
void setattr(PyObject* obj, StrName name, PyObject* value);
|
||||
template<int ARGC>
|
||||
PyObject* bind_method(Type, Str, NativeFuncC);
|
||||
PyObject* bind_method(Type, StrName, NativeFuncC);
|
||||
template<int ARGC>
|
||||
PyObject* bind_method(PyObject*, Str, NativeFuncC);
|
||||
PyObject* bind_method(PyObject*, StrName, NativeFuncC);
|
||||
template<int ARGC>
|
||||
PyObject* bind_func(PyObject*, Str, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
||||
PyObject* bind_func(PyObject*, StrName, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
||||
void _error(PyObject*);
|
||||
PyObject* _run_top_frame();
|
||||
void post_init();
|
||||
@ -615,20 +573,20 @@ __T _py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, false>(vm,
|
||||
|
||||
|
||||
template<int ARGC>
|
||||
PyObject* VM::bind_method(Type type, Str name, NativeFuncC fn) {
|
||||
PyObject* VM::bind_method(Type type, StrName name, NativeFuncC fn) {
|
||||
PyObject* nf = VAR(NativeFunc(fn, ARGC, true));
|
||||
_t(type)->attr().set(name, nf);
|
||||
return nf;
|
||||
}
|
||||
|
||||
template<int ARGC>
|
||||
PyObject* VM::bind_method(PyObject* obj, Str name, NativeFuncC fn) {
|
||||
PyObject* VM::bind_method(PyObject* obj, StrName name, NativeFuncC fn) {
|
||||
check_type(obj, tp_type);
|
||||
return bind_method<ARGC>(PK_OBJ_GET(Type, obj), name, fn);
|
||||
}
|
||||
|
||||
template<int ARGC>
|
||||
PyObject* VM::bind_func(PyObject* obj, Str name, NativeFuncC fn, UserData userdata, BindType bt) {
|
||||
PyObject* VM::bind_func(PyObject* obj, StrName name, NativeFuncC fn, UserData userdata, BindType bt) {
|
||||
PyObject* nf = VAR(NativeFunc(fn, ARGC, false));
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(userdata);
|
||||
switch(bt){
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace pkpy{
|
||||
|
||||
void VoidP::_register(VM* vm, PyObject* mod, PyObject* type){
|
||||
vm->bind_constructor<2>(type, [](VM* vm, ArgsView args){
|
||||
vm->bind_func<2>(type, __new__, [](VM* vm, ArgsView args){
|
||||
Type cls = PK_OBJ_GET(Type, args[0]);
|
||||
i64 addr = CAST(i64, args[1]);
|
||||
return vm->heap.gcnew<VoidP>(cls, reinterpret_cast<void*>(addr));
|
||||
|
@ -264,7 +264,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
|
||||
void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type){
|
||||
PY_STRUCT_LIKE(Mat3x3)
|
||||
|
||||
vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){
|
||||
vm->bind_func<-1>(type, __new__, [](VM* vm, ArgsView args){
|
||||
if(args.size() == 1+0) return vm->heap.gcnew<Mat3x3>(PK_OBJ_GET(Type, args[0]), Mat3x3::zeros());
|
||||
if(args.size() == 1+1){
|
||||
const List& list = CAST(List&, args[1]);
|
||||
|
@ -266,7 +266,10 @@ struct LineProfilerW{
|
||||
LineProfiler profiler;
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||
vm->bind_default_constructor<LineProfilerW>(type);
|
||||
vm->bind_func<1>(type, __new__, [](VM* vm, ArgsView args){
|
||||
Type cls = PK_OBJ_GET(Type, args[0]);
|
||||
return vm->heap.gcnew<LineProfilerW>(cls);
|
||||
});
|
||||
|
||||
vm->bind(type, "add_function(self, func)", [](VM* vm, ArgsView args){
|
||||
LineProfilerW& self = PK_OBJ_GET(LineProfilerW, args[0]);
|
||||
|
@ -11,7 +11,10 @@ struct Random{
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||
vm->bind_default_constructor<Random>(type);
|
||||
vm->bind_func<1>(type, __new__, [](VM* vm, ArgsView args){
|
||||
Type cls = PK_OBJ_GET(Type, args[0]);
|
||||
return vm->heap.gcnew<Random>(cls);
|
||||
});
|
||||
|
||||
vm->bind_method<1>(type, "seed", [](VM* vm, ArgsView args) {
|
||||
Random& self = _CAST(Random&, args[0]);
|
||||
|
66
src/vm.cpp
66
src/vm.cpp
@ -1220,6 +1220,20 @@ void VM::_builtin_error(StrName type){ _error(call(builtins->attr(type))); }
|
||||
void VM::_builtin_error(StrName type, PyObject* arg){ _error(call(builtins->attr(type), arg)); }
|
||||
void VM::_builtin_error(StrName type, const Str& msg){ _builtin_error(type, VAR(msg)); }
|
||||
|
||||
void VM::BinaryOptError(const char* op, PyObject* _0, PyObject* _1) {
|
||||
StrName name_0 = _type_name(vm, _tp(_0));
|
||||
StrName name_1 = _type_name(vm, _tp(_1));
|
||||
TypeError(_S("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
|
||||
}
|
||||
|
||||
void VM::AttributeError(PyObject* obj, StrName name){
|
||||
if(isinstance(obj, vm->tp_type)){
|
||||
_builtin_error("AttributeError", _S("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
|
||||
}else{
|
||||
_builtin_error("AttributeError", _S(_type_name(vm, _tp(obj)).escape(), " object has no attribute ", name.escape()));
|
||||
}
|
||||
}
|
||||
|
||||
void VM::_error(PyObject* e_obj){
|
||||
PK_ASSERT(isinstance(e_obj, tp_exception))
|
||||
Exception& e = PK_OBJ_GET(Exception, e_obj);
|
||||
@ -1293,6 +1307,23 @@ void VM::bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)){
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
|
||||
}
|
||||
|
||||
#define BIND_UNARY_SPECIAL(name) \
|
||||
void VM::bind##name(Type type, PyObject* (*f)(VM*, PyObject*)){ \
|
||||
_all_types[type].m##name = f; \
|
||||
PyObject* nf = bind_method<0>(_t(type), #name, [](VM* vm, ArgsView args){ \
|
||||
return lambda_get_userdata<PyObject*(*)(VM*, PyObject*)>(args.begin())(vm, args[0]);\
|
||||
}); \
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f); \
|
||||
}
|
||||
|
||||
BIND_UNARY_SPECIAL(__repr__)
|
||||
BIND_UNARY_SPECIAL(__str__)
|
||||
BIND_UNARY_SPECIAL(__iter__)
|
||||
BIND_UNARY_SPECIAL(__next__)
|
||||
BIND_UNARY_SPECIAL(__neg__)
|
||||
BIND_UNARY_SPECIAL(__invert__)
|
||||
#undef BIND_UNARY_SPECIAL
|
||||
|
||||
void VM::bind__hash__(Type type, i64 (*f)(VM*, PyObject*)){
|
||||
PyObject* obj = _t(type);
|
||||
_all_types[type].m__hash__ = f;
|
||||
@ -1313,6 +1344,41 @@ void VM::bind__len__(Type type, i64 (*f)(VM*, PyObject*)){
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
|
||||
}
|
||||
|
||||
|
||||
#define BIND_BINARY_SPECIAL(name) \
|
||||
void VM::bind##name(Type type, BinaryFuncC f){ \
|
||||
_all_types[type].m##name = f; \
|
||||
PyObject* nf = bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \
|
||||
return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]);\
|
||||
}); \
|
||||
PK_OBJ_GET(NativeFunc, nf).set_userdata(f); \
|
||||
}
|
||||
|
||||
BIND_BINARY_SPECIAL(__eq__)
|
||||
BIND_BINARY_SPECIAL(__lt__)
|
||||
BIND_BINARY_SPECIAL(__le__)
|
||||
BIND_BINARY_SPECIAL(__gt__)
|
||||
BIND_BINARY_SPECIAL(__ge__)
|
||||
BIND_BINARY_SPECIAL(__contains__)
|
||||
|
||||
BIND_BINARY_SPECIAL(__add__)
|
||||
BIND_BINARY_SPECIAL(__sub__)
|
||||
BIND_BINARY_SPECIAL(__mul__)
|
||||
BIND_BINARY_SPECIAL(__truediv__)
|
||||
BIND_BINARY_SPECIAL(__floordiv__)
|
||||
BIND_BINARY_SPECIAL(__mod__)
|
||||
BIND_BINARY_SPECIAL(__pow__)
|
||||
BIND_BINARY_SPECIAL(__matmul__)
|
||||
|
||||
BIND_BINARY_SPECIAL(__lshift__)
|
||||
BIND_BINARY_SPECIAL(__rshift__)
|
||||
BIND_BINARY_SPECIAL(__and__)
|
||||
BIND_BINARY_SPECIAL(__or__)
|
||||
BIND_BINARY_SPECIAL(__xor__)
|
||||
|
||||
#undef BIND_BINARY_SPECIAL
|
||||
|
||||
|
||||
void Dict::_probe_0(PyObject *key, bool &ok, int &i) const{
|
||||
ok = false;
|
||||
i64 hash = vm->py_hash(key);
|
||||
|
Loading…
x
Reference in New Issue
Block a user