mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
remove PY_CLASS
macro
This commit is contained in:
parent
43ec97a707
commit
f944113567
@ -38,8 +38,6 @@ struct PyLuaObject{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PyLuaTable: PyLuaObject{
|
struct PyLuaTable: PyLuaObject{
|
||||||
PY_CLASS(PyLuaTable, lua, Table)
|
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||||
Type t = PK_OBJ_GET(Type, type);
|
Type t = PK_OBJ_GET(Type, type);
|
||||||
PyTypeInfo* ti = &vm->_all_types[t];
|
PyTypeInfo* ti = &vm->_all_types[t];
|
||||||
@ -198,8 +196,6 @@ static PyObject* lua_popx_multi_to_python(VM* vm, int count){
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct PyLuaFunction: PyLuaObject{
|
struct PyLuaFunction: PyLuaObject{
|
||||||
PY_CLASS(PyLuaFunction, lua, Function)
|
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||||
vm->bind_notimplemented_constructor<PyLuaFunction>(type);
|
vm->bind_notimplemented_constructor<PyLuaFunction>(type);
|
||||||
vm->_all_types[PK_OBJ_GET(Type, type)].subclass_enabled = false;
|
vm->_all_types[PK_OBJ_GET(Type, type)].subclass_enabled = false;
|
||||||
@ -274,13 +270,13 @@ void lua_push_from_python(VM* vm, PyObject* val){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_type(val, PyLuaTable::_type(vm))){
|
if(vm->is_user_type<PyLuaTable>(val)){
|
||||||
const PyLuaTable& table = _CAST(PyLuaTable&, val);
|
const PyLuaTable& table = _CAST(PyLuaTable&, val);
|
||||||
lua_rawgeti(_L, LUA_REGISTRYINDEX, table.r);
|
lua_rawgeti(_L, LUA_REGISTRYINDEX, table.r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_type(val, PyLuaFunction::_type(vm))){
|
if(vm->is_user_type<PyLuaFunction>(val)){
|
||||||
const PyLuaFunction& func = _CAST(PyLuaFunction&, val);
|
const PyLuaFunction& func = _CAST(PyLuaFunction&, val);
|
||||||
lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r);
|
lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r);
|
||||||
return;
|
return;
|
||||||
@ -311,11 +307,11 @@ PyObject* lua_popx_to_python(VM* vm) {
|
|||||||
return VAR(val);
|
return VAR(val);
|
||||||
}
|
}
|
||||||
case LUA_TTABLE: {
|
case LUA_TTABLE: {
|
||||||
PyObject* obj = vm->heap.gcnew<PyLuaTable>(PyLuaTable::_type(vm));
|
PyObject* obj = vm->new_user_object<PyLuaTable>();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
case LUA_TFUNCTION: {
|
case LUA_TFUNCTION: {
|
||||||
PyObject* obj = vm->heap.gcnew<PyLuaFunction>(PyLuaFunction::_type(vm));
|
PyObject* obj = vm->new_user_object<PyLuaFunction>();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -335,8 +331,8 @@ void initialize_lua_bridge(VM* vm, lua_State* newL){
|
|||||||
}
|
}
|
||||||
_L = newL;
|
_L = newL;
|
||||||
|
|
||||||
PyLuaTable::register_class(vm, mod);
|
vm->register_user_class<PyLuaTable>(mod, "Table");
|
||||||
PyLuaFunction::register_class(vm, mod);
|
vm->register_user_class<PyLuaFunction>(mod, "Function");
|
||||||
|
|
||||||
vm->bind(mod, "dostring(__source: str)", [](VM* vm, ArgsView args){
|
vm->bind(mod, "dostring(__source: str)", [](VM* vm, ArgsView args){
|
||||||
const char* source = CAST(CString, args[0]);
|
const char* source = CAST(CString, args[0]);
|
||||||
|
@ -169,7 +169,7 @@ struct wrapped__Point{
|
|||||||
int main(){
|
int main(){
|
||||||
VM* vm = new VM();
|
VM* vm = new VM();
|
||||||
// register the wrapper class in builtins
|
// register the wrapper class in builtins
|
||||||
wrapped__Point::register_class(vm, vm->builtins);
|
vm->register_user_class<wrapped__Point>(vm->builtins);
|
||||||
|
|
||||||
// use the Point class
|
// use the Point class
|
||||||
vm->exec("a = Point(1, 2)");
|
vm->exec("a = Point(1, 2)");
|
||||||
|
@ -141,7 +141,7 @@ Access extended python types
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// VoidP was defined by `PY_CLASS` macro
|
// VoidP was defined by `PY_CLASS` macro
|
||||||
Type voidp_t = VoidP::_type(vm);
|
Type voidp_t = vm->_tp_user<VoidP>();
|
||||||
```
|
```
|
||||||
|
|
||||||
Check if an object is a python type
|
Check if an object is a python type
|
||||||
|
@ -142,7 +142,7 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
|
|||||||
vm->bind_func<1>(type, "from_struct", [](VM* vm, ArgsView args){ \
|
vm->bind_func<1>(type, "from_struct", [](VM* vm, ArgsView args){ \
|
||||||
C99Struct& s = CAST(C99Struct&, args[0]); \
|
C99Struct& s = CAST(C99Struct&, args[0]); \
|
||||||
if(s.size != sizeof(vT)) vm->ValueError("size mismatch"); \
|
if(s.size != sizeof(vT)) vm->ValueError("size mismatch"); \
|
||||||
PyObject* obj = vm->heap.gcnew<wT>(wT::_type(vm)); \
|
PyObject* obj = vm->new_user_object<wT>(); \
|
||||||
memcpy(_CAST(wT&, obj)._(), s.p, sizeof(vT)); \
|
memcpy(_CAST(wT&, obj)._(), s.p, sizeof(vT)); \
|
||||||
return obj; \
|
return obj; \
|
||||||
}, {}, BindType::STATICMETHOD); \
|
}, {}, BindType::STATICMETHOD); \
|
||||||
@ -163,7 +163,7 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
|
|||||||
}); \
|
}); \
|
||||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
|
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
|
||||||
wT& self = _CAST(wT&, _0); \
|
wT& self = _CAST(wT&, _0); \
|
||||||
if(!vm->isinstance(_1, wT::_type(vm))) return vm->NotImplemented; \
|
if(!vm->isinstance(_1, vm->_tp_user<wT>())) return vm->NotImplemented; \
|
||||||
wT& other = _CAST(wT&, _1); \
|
wT& other = _CAST(wT&, _1); \
|
||||||
return VAR(self == other); \
|
return VAR(self == other); \
|
||||||
}); \
|
}); \
|
||||||
|
@ -6,22 +6,14 @@
|
|||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
#define PY_CLASS(T, mod, name) \
|
#define PY_CLASS(T, mod, name) \
|
||||||
static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
|
[[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
|
||||||
static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
|
[[deprecated]] static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
|
||||||
std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \
|
return vm->register_user_class<T>(mod, #name, base); \
|
||||||
if(mod_name != #mod) throw std::runtime_error(_S("register_class() failed: ", mod_name, " != ", #mod).str()); \
|
|
||||||
PyObject* type = vm->new_type_object(mod, #name, base); \
|
|
||||||
mod->attr().set(#name, type); \
|
|
||||||
vm->_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type); \
|
|
||||||
T::_register(vm, mod, type); \
|
|
||||||
return type; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), __VA_ARGS__)
|
#define VAR_T(T, ...) vm->heap.gcnew<T>(vm->_tp_user<T>(), __VA_ARGS__)
|
||||||
|
|
||||||
struct VoidP{
|
struct VoidP{
|
||||||
PY_CLASS(VoidP, c, void_p)
|
|
||||||
|
|
||||||
void* ptr;
|
void* ptr;
|
||||||
VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){}
|
VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
#define PK_VERSION "1.4.6"
|
#define PK_VERSION "1.5.0"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
struct RangeIter{
|
struct RangeIter{
|
||||||
PY_CLASS(RangeIter, builtins, _range_iterator)
|
|
||||||
Range r;
|
Range r;
|
||||||
i64 current;
|
i64 current;
|
||||||
RangeIter(Range r) : r(r), current(r.start) {}
|
RangeIter(Range r) : r(r), current(r.start) {}
|
||||||
@ -16,7 +15,6 @@ struct RangeIter{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ArrayIter{
|
struct ArrayIter{
|
||||||
PY_CLASS(ArrayIter, builtins, _array_iterator)
|
|
||||||
PyObject* ref;
|
PyObject* ref;
|
||||||
PyObject** begin;
|
PyObject** begin;
|
||||||
PyObject** end;
|
PyObject** end;
|
||||||
@ -30,7 +28,6 @@ struct ArrayIter{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct StringIter{
|
struct StringIter{
|
||||||
PY_CLASS(StringIter, builtins, _string_iterator)
|
|
||||||
PyObject* ref;
|
PyObject* ref;
|
||||||
int i; // byte index
|
int i; // byte index
|
||||||
StringIter(PyObject* ref) : ref(ref), i(0) {}
|
StringIter(PyObject* ref) : ref(ref), i(0) {}
|
||||||
@ -39,7 +36,6 @@ struct StringIter{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Generator{
|
struct Generator{
|
||||||
PY_CLASS(Generator, builtins, generator)
|
|
||||||
Frame frame;
|
Frame frame;
|
||||||
int state; // 0,1,2
|
int state; // 0,1,2
|
||||||
List s_backup;
|
List s_backup;
|
||||||
@ -58,7 +54,6 @@ struct Generator{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DictItemsIter{
|
struct DictItemsIter{
|
||||||
PY_CLASS(DictItemsIter, builtins, _dict_items_iterator)
|
|
||||||
PyObject* ref;
|
PyObject* ref;
|
||||||
int i;
|
int i;
|
||||||
DictItemsIter(PyObject* ref) : ref(ref) {
|
DictItemsIter(PyObject* ref) : ref(ref) {
|
||||||
|
@ -7,8 +7,6 @@ namespace pkpy{
|
|||||||
inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; }
|
inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; }
|
||||||
|
|
||||||
struct Vec2{
|
struct Vec2{
|
||||||
PY_CLASS(Vec2, linalg, vec2)
|
|
||||||
|
|
||||||
Vec2* _() { return this; }
|
Vec2* _() { return this; }
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
|
|
||||||
@ -35,8 +33,6 @@ struct Vec2{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Vec3{
|
struct Vec3{
|
||||||
PY_CLASS(Vec3, linalg, vec3)
|
|
||||||
|
|
||||||
Vec3* _() { return this; }
|
Vec3* _() { return this; }
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
|
|
||||||
@ -62,8 +58,6 @@ struct Vec3{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Vec4{
|
struct Vec4{
|
||||||
PY_CLASS(Vec4, linalg, vec4)
|
|
||||||
|
|
||||||
Vec4* _() { return this; }
|
Vec4* _() { return this; }
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
|
|
||||||
@ -88,8 +82,6 @@ struct Vec4{
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Mat3x3{
|
struct Mat3x3{
|
||||||
PY_CLASS(Mat3x3, linalg, mat3x3)
|
|
||||||
|
|
||||||
Mat3x3* _(){ return this; }
|
Mat3x3* _(){ return this; }
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
|
|
||||||
|
@ -425,6 +425,30 @@ public:
|
|||||||
PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
||||||
PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
|
PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
PyObject* register_user_class(PyObject* mod, StrName name, Type base=0, bool subclass_enabled=false){
|
||||||
|
PyObject* type = new_type_object(mod, name, base, subclass_enabled);
|
||||||
|
mod->attr().set(name, type);
|
||||||
|
_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);
|
||||||
|
T::_register(vm, mod, type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename ...Args>
|
||||||
|
PyObject* new_user_object(Args&&... args){
|
||||||
|
return heap.gcnew<T>(_tp_user<T>(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Type _tp_user(){
|
||||||
|
return _find_type_in_cxx_typeid_map<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool is_user_type(PyObject* obj){
|
||||||
|
return _tp(obj) == _tp_user<T>();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Type _find_type_in_cxx_typeid_map(){
|
Type _find_type_in_cxx_typeid_map(){
|
||||||
auto it = _cxx_typeid_map.find(typeid(T));
|
auto it = _cxx_typeid_map.find(typeid(T));
|
||||||
|
@ -4,7 +4,6 @@ namespace pkpy{
|
|||||||
|
|
||||||
struct Array2d{
|
struct Array2d{
|
||||||
PK_ALWAYS_PASS_BY_POINTER(Array2d)
|
PK_ALWAYS_PASS_BY_POINTER(Array2d)
|
||||||
PY_CLASS(Array2d, array2d, array2d)
|
|
||||||
|
|
||||||
PyObject** data;
|
PyObject** data;
|
||||||
int n_cols;
|
int n_cols;
|
||||||
@ -105,7 +104,7 @@ struct Array2d{
|
|||||||
|
|
||||||
if(is_type(xy[0], VM::tp_slice) && is_type(xy[1], VM::tp_slice)){
|
if(is_type(xy[0], VM::tp_slice) && is_type(xy[1], VM::tp_slice)){
|
||||||
HANDLE_SLICE();
|
HANDLE_SLICE();
|
||||||
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm));
|
PyObject* new_array_obj = vm->new_user_object<Array2d>();
|
||||||
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
||||||
new_array.init(stop_col - start_col, stop_row - start_row);
|
new_array.init(stop_col - start_col, stop_row - start_row);
|
||||||
for(int j = start_row; j < stop_row; j++){
|
for(int j = start_row; j < stop_row; j++){
|
||||||
@ -150,7 +149,7 @@ struct Array2d{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_type(_2, Array2d::_type(vm))){
|
if(!vm->is_user_type<Array2d>(_2)){
|
||||||
vm->TypeError(_S("expected int/float/str/bool/None or an array2d instance"));
|
vm->TypeError(_S("expected int/float/str/bool/None or an array2d instance"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +191,7 @@ struct Array2d{
|
|||||||
vm->bind(type, "map(self, f)", [](VM* vm, ArgsView args){
|
vm->bind(type, "map(self, f)", [](VM* vm, ArgsView args){
|
||||||
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
||||||
PyObject* f = args[1];
|
PyObject* f = args[1];
|
||||||
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm));
|
PyObject* new_array_obj = vm->new_user_object<Array2d>();
|
||||||
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
||||||
new_array.init(self.n_cols, self.n_rows);
|
new_array.init(self.n_cols, self.n_rows);
|
||||||
for(int i = 0; i < new_array.numel; i++){
|
for(int i = 0; i < new_array.numel; i++){
|
||||||
@ -203,7 +202,7 @@ struct Array2d{
|
|||||||
|
|
||||||
vm->bind(type, "copy(self)", [](VM* vm, ArgsView args){
|
vm->bind(type, "copy(self)", [](VM* vm, ArgsView args){
|
||||||
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
||||||
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm));
|
PyObject* new_array_obj = vm->new_user_object<Array2d>();
|
||||||
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
||||||
new_array.init(self.n_cols, self.n_rows);
|
new_array.init(self.n_cols, self.n_rows);
|
||||||
for(int i = 0; i < new_array.numel; i++){
|
for(int i = 0; i < new_array.numel; i++){
|
||||||
@ -255,7 +254,7 @@ struct Array2d{
|
|||||||
|
|
||||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
|
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
|
||||||
Array2d& self = PK_OBJ_GET(Array2d, _0);
|
Array2d& self = PK_OBJ_GET(Array2d, _0);
|
||||||
if(!is_type(_1, Array2d::_type(vm))) return vm->NotImplemented;
|
if(!vm->is_user_type<Array2d>(_1)) return vm->NotImplemented;
|
||||||
Array2d& other = PK_OBJ_GET(Array2d, _1);
|
Array2d& other = PK_OBJ_GET(Array2d, _1);
|
||||||
if(self.n_cols != other.n_cols || self.n_rows != other.n_rows) return vm->False;
|
if(self.n_cols != other.n_cols || self.n_rows != other.n_rows) return vm->False;
|
||||||
for(int i = 0; i < self.numel; i++){
|
for(int i = 0; i < self.numel; i++){
|
||||||
@ -266,7 +265,7 @@ struct Array2d{
|
|||||||
|
|
||||||
vm->bind(type, "count_neighbors(self, value, neighborhood='Moore') -> array2d[int]", [](VM* vm, ArgsView args){
|
vm->bind(type, "count_neighbors(self, value, neighborhood='Moore') -> array2d[int]", [](VM* vm, ArgsView args){
|
||||||
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
||||||
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm));
|
PyObject* new_array_obj = vm->new_user_object<Array2d>();
|
||||||
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
||||||
new_array.init(self.n_cols, self.n_rows);
|
new_array.init(self.n_cols, self.n_rows);
|
||||||
PyObject* value = args[1];
|
PyObject* value = args[1];
|
||||||
@ -347,8 +346,7 @@ struct Array2d{
|
|||||||
|
|
||||||
struct Array2dIter{
|
struct Array2dIter{
|
||||||
PK_ALWAYS_PASS_BY_POINTER(Array2dIter)
|
PK_ALWAYS_PASS_BY_POINTER(Array2dIter)
|
||||||
PY_CLASS(Array2dIter, array2d, _array2d_iterator)
|
|
||||||
|
|
||||||
PyObject* ref;
|
PyObject* ref;
|
||||||
int i;
|
int i;
|
||||||
Array2dIter(PyObject* ref) : ref(ref), i(0) {}
|
Array2dIter(PyObject* ref) : ref(ref), i(0) {}
|
||||||
@ -375,10 +373,10 @@ struct Array2dIter{
|
|||||||
void add_module_array2d(VM* vm){
|
void add_module_array2d(VM* vm){
|
||||||
PyObject* mod = vm->new_module("array2d");
|
PyObject* mod = vm->new_module("array2d");
|
||||||
|
|
||||||
Array2d::register_class(vm, mod);
|
vm->register_user_class<Array2d>(mod, "array2d");
|
||||||
Array2dIter::register_class(vm, mod);
|
vm->register_user_class<Array2dIter>(mod, "_array2d_iter");
|
||||||
|
|
||||||
vm->bind__iter__(Array2d::_type(vm), [](VM* vm, PyObject* _0){
|
vm->bind__iter__(vm->_tp_user<Array2d>(), [](VM* vm, PyObject* _0){
|
||||||
return VAR_T(Array2dIter, _0);
|
return VAR_T(Array2dIter, _0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
13
src/cffi.cpp
13
src/cffi.cpp
@ -21,7 +21,7 @@ namespace pkpy{
|
|||||||
|
|
||||||
#define BIND_CMP(name, op) \
|
#define BIND_CMP(name, op) \
|
||||||
vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ \
|
vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ \
|
||||||
if(!vm->isinstance(rhs, VoidP::_type(vm))) return vm->NotImplemented; \
|
if(!vm->isinstance(rhs, vm->_tp_user<VoidP>())) return vm->NotImplemented; \
|
||||||
void* _0 = PK_OBJ_GET(VoidP, lhs).ptr; \
|
void* _0 = PK_OBJ_GET(VoidP, lhs).ptr; \
|
||||||
void* _1 = PK_OBJ_GET(VoidP, rhs).ptr; \
|
void* _1 = PK_OBJ_GET(VoidP, rhs).ptr; \
|
||||||
return VAR(_0 op _1); \
|
return VAR(_0 op _1); \
|
||||||
@ -96,7 +96,7 @@ namespace pkpy{
|
|||||||
|
|
||||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
|
||||||
C99Struct& self = _CAST(C99Struct&, lhs);
|
C99Struct& self = _CAST(C99Struct&, lhs);
|
||||||
if(!is_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
if(!vm->is_user_type<C99Struct>(rhs)) return vm->NotImplemented;
|
||||||
C99Struct& other = _CAST(C99Struct&, rhs);
|
C99Struct& other = _CAST(C99Struct&, rhs);
|
||||||
bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
|
bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
|
||||||
return VAR(ok);
|
return VAR(ok);
|
||||||
@ -161,15 +161,16 @@ void add_module_c(VM* vm){
|
|||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
VoidP::register_class(vm, mod);
|
vm->register_user_class<VoidP>(mod, "void_p");
|
||||||
C99Struct::register_class(vm, mod);
|
vm->register_user_class<C99Struct>(mod, "struct");
|
||||||
|
|
||||||
mod->attr().set("NULL", VAR_T(VoidP, nullptr));
|
mod->attr().set("NULL", VAR_T(VoidP, nullptr));
|
||||||
|
|
||||||
vm->bind(mod, "p_cast(ptr: 'void_p', cls: type[T]) -> T", [](VM* vm, ArgsView args){
|
vm->bind(mod, "p_cast(ptr: 'void_p', cls: type[T]) -> T", [](VM* vm, ArgsView args){
|
||||||
VoidP& ptr = CAST(VoidP&, args[0]);
|
VoidP& ptr = CAST(VoidP&, args[0]);
|
||||||
vm->check_type(args[1], vm->tp_type);
|
vm->check_type(args[1], vm->tp_type);
|
||||||
Type cls = PK_OBJ_GET(Type, args[1]);
|
Type cls = PK_OBJ_GET(Type, args[1]);
|
||||||
if(!vm->issubclass(cls, VoidP::_type(vm))){
|
if(!vm->issubclass(cls, vm->_tp_user<VoidP>())){
|
||||||
vm->ValueError("expected a subclass of void_p");
|
vm->ValueError("expected a subclass of void_p");
|
||||||
}
|
}
|
||||||
return vm->heap.gcnew<VoidP>(cls, ptr.ptr);
|
return vm->heap.gcnew<VoidP>(cls, ptr.ptr);
|
||||||
@ -194,7 +195,7 @@ void add_module_c(VM* vm){
|
|||||||
T val = CAST(T, args[0]); \
|
T val = CAST(T, args[0]); \
|
||||||
return VAR_T(C99Struct, &val, sizeof(T)); \
|
return VAR_T(C99Struct, &val, sizeof(T)); \
|
||||||
}); \
|
}); \
|
||||||
type = vm->new_type_object(mod, CNAME "_p", VoidP::_type(vm)); \
|
type = vm->new_type_object(mod, CNAME "_p", vm->_tp_user<VoidP>()); \
|
||||||
mod->attr().set(CNAME "_p", type); \
|
mod->attr().set(CNAME "_p", type); \
|
||||||
type_t = PK_OBJ_GET(Type, type); \
|
type_t = PK_OBJ_GET(Type, type); \
|
||||||
vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){ \
|
vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){ \
|
||||||
|
@ -4,7 +4,6 @@ namespace pkpy
|
|||||||
{
|
{
|
||||||
struct PyDequeIter // Iterator for the deque type
|
struct PyDequeIter // Iterator for the deque type
|
||||||
{
|
{
|
||||||
PY_CLASS(PyDequeIter, collections, _deque_iterator)
|
|
||||||
PyObject *ref;
|
PyObject *ref;
|
||||||
bool is_reversed;
|
bool is_reversed;
|
||||||
std::deque<PyObject *>::iterator begin, end, current;
|
std::deque<PyObject *>::iterator begin, end, current;
|
||||||
@ -48,7 +47,6 @@ namespace pkpy
|
|||||||
}
|
}
|
||||||
struct PyDeque
|
struct PyDeque
|
||||||
{
|
{
|
||||||
PY_CLASS(PyDeque, collections, deque);
|
|
||||||
PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen); // constructor
|
PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen); // constructor
|
||||||
// PyDeque members
|
// PyDeque members
|
||||||
std::deque<PyObject *> dequeItems;
|
std::deque<PyObject *> dequeItems;
|
||||||
@ -108,9 +106,7 @@ namespace pkpy
|
|||||||
vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
|
vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
|
||||||
{
|
{
|
||||||
PyDeque &self = _CAST(PyDeque &, _0);
|
PyDeque &self = _CAST(PyDeque &, _0);
|
||||||
return vm->heap.gcnew<PyDequeIter>(
|
return vm->new_user_object<PyDequeIter>(_0, self.dequeItems.begin(), self.dequeItems.end());
|
||||||
PyDequeIter::_type(vm), _0,
|
|
||||||
self.dequeItems.begin(), self.dequeItems.end());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
|
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
|
||||||
@ -134,7 +130,7 @@ namespace pkpy
|
|||||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1)
|
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1)
|
||||||
{
|
{
|
||||||
const PyDeque &self = _CAST(PyDeque&, _0);
|
const PyDeque &self = _CAST(PyDeque&, _0);
|
||||||
if(!is_type(_0, PyDeque::_type(vm))) return vm->NotImplemented;
|
if(!vm->is_user_type<PyDeque>(_0)) return vm->NotImplemented;
|
||||||
const PyDeque &other = _CAST(PyDeque&, _1);
|
const PyDeque &other = _CAST(PyDeque&, _1);
|
||||||
if (self.dequeItems.size() != other.dequeItems.size()) return vm->False;
|
if (self.dequeItems.size() != other.dequeItems.size()) return vm->False;
|
||||||
for (int i = 0; i < self.dequeItems.size(); i++){
|
for (int i = 0; i < self.dequeItems.size(); i++){
|
||||||
@ -214,8 +210,8 @@ namespace pkpy
|
|||||||
{
|
{
|
||||||
auto _lock = vm->heap.gc_scope_lock(); // locking the heap
|
auto _lock = vm->heap.gc_scope_lock(); // locking the heap
|
||||||
PyDeque &self = _CAST(PyDeque &, args[0]);
|
PyDeque &self = _CAST(PyDeque &, args[0]);
|
||||||
PyObject *newDequeObj = vm->heap.gcnew<PyDeque>(PyDeque::_type(vm), vm, vm->None, vm->None); // create the empty deque
|
PyObject *newDequeObj = vm->new_user_object<PyDeque>(vm, vm->None, vm->None); // create the empty deque
|
||||||
PyDeque &newDeque = _CAST(PyDeque &, newDequeObj); // cast it to PyDeque so we can use its methods
|
PyDeque &newDeque = _CAST(PyDeque &, newDequeObj); // cast it to PyDeque so we can use its methods
|
||||||
for (auto it = self.dequeItems.begin(); it != self.dequeItems.end(); ++it)
|
for (auto it = self.dequeItems.begin(); it != self.dequeItems.end(); ++it)
|
||||||
newDeque.insertObj(false, true, -1, *it);
|
newDeque.insertObj(false, true, -1, *it);
|
||||||
return newDequeObj;
|
return newDequeObj;
|
||||||
@ -546,12 +542,11 @@ namespace pkpy
|
|||||||
PK_OBJ_MARK(obj);
|
PK_OBJ_MARK(obj);
|
||||||
}
|
}
|
||||||
/// @brief registers the PyDeque class
|
/// @brief registers the PyDeque class
|
||||||
/// @param vm is needed for the new_module and register_class
|
|
||||||
void add_module_collections(VM *vm)
|
void add_module_collections(VM *vm)
|
||||||
{
|
{
|
||||||
PyObject *mod = vm->new_module("collections");
|
PyObject *mod = vm->new_module("collections");
|
||||||
PyDeque::register_class(vm, mod);
|
vm->register_user_class<PyDeque>(mod, "deque");
|
||||||
PyDequeIter::register_class(vm, mod);
|
vm->register_user_class<PyDequeIter>(mod, "_deque_iter");
|
||||||
CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE);
|
CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE);
|
||||||
vm->_exec(code, mod);
|
vm->_exec(code, mod);
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,6 @@ namespace pkpy{
|
|||||||
#if PK_ENABLE_OS
|
#if PK_ENABLE_OS
|
||||||
|
|
||||||
struct FileIO {
|
struct FileIO {
|
||||||
PY_CLASS(FileIO, io, FileIO)
|
|
||||||
|
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
bool is_text;
|
bool is_text;
|
||||||
|
|
||||||
@ -142,7 +140,7 @@ void FileIO::close(){
|
|||||||
|
|
||||||
void add_module_io(VM* vm){
|
void add_module_io(VM* vm){
|
||||||
PyObject* mod = vm->new_module("io");
|
PyObject* mod = vm->new_module("io");
|
||||||
FileIO::register_class(vm, mod);
|
vm->register_user_class<FileIO>(mod, "FileIO");
|
||||||
|
|
||||||
mod->attr().set("SEEK_SET", VAR(SEEK_SET));
|
mod->attr().set("SEEK_SET", VAR(SEEK_SET));
|
||||||
mod->attr().set("SEEK_CUR", VAR(SEEK_CUR));
|
mod->attr().set("SEEK_CUR", VAR(SEEK_CUR));
|
||||||
|
@ -24,15 +24,15 @@ namespace pkpy{
|
|||||||
|
|
||||||
#define BIND_VEC_FUNCTION_1(D, name) \
|
#define BIND_VEC_FUNCTION_1(D, name) \
|
||||||
vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \
|
vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \
|
||||||
Vec##D& self = _CAST(Vec##D&, args[0]); \
|
Vec##D& self = _CAST(Vec##D&, args[0]); \
|
||||||
Vec##D& other = CAST(Vec##D&, args[1]); \
|
Vec##D& other = CAST(Vec##D&, args[1]); \
|
||||||
return VAR(self.name(other)); \
|
return VAR(self.name(other)); \
|
||||||
});
|
});
|
||||||
|
|
||||||
#define BIND_VEC_MUL_OP(D) \
|
#define BIND_VEC_MUL_OP(D) \
|
||||||
vm->bind__mul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
|
vm->bind__mul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
|
||||||
Vec##D& self = _CAST(Vec##D&, _0); \
|
Vec##D& self = _CAST(Vec##D&, _0); \
|
||||||
if(is_type(_1, Vec##D::_type(vm))){ \
|
if(vm->is_user_type<Vec##D>(_1)){ \
|
||||||
Vec##D& other = _CAST(Vec##D&, _1); \
|
Vec##D& other = _CAST(Vec##D&, _1); \
|
||||||
return VAR(self * other); \
|
return VAR(self * other); \
|
||||||
} \
|
} \
|
||||||
@ -369,11 +369,11 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
|
|||||||
|
|
||||||
vm->bind__matmul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
|
vm->bind__matmul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
|
||||||
Mat3x3& self = _CAST(Mat3x3&, _0);
|
Mat3x3& self = _CAST(Mat3x3&, _0);
|
||||||
if(is_type(_1, Mat3x3::_type(vm))){
|
if(vm->is_user_type<Mat3x3>(_1)){
|
||||||
const Mat3x3& other = _CAST(Mat3x3&, _1);
|
const Mat3x3& other = _CAST(Mat3x3&, _1);
|
||||||
return VAR_T(Mat3x3, self.matmul(other));
|
return VAR_T(Mat3x3, self.matmul(other));
|
||||||
}
|
}
|
||||||
if(is_type(_1, Vec3::_type(vm))){
|
if(vm->is_user_type<Vec3>(_1)){
|
||||||
const Vec3& other = _CAST(Vec3&, _1);
|
const Vec3& other = _CAST(Vec3&, _1);
|
||||||
return VAR_T(Vec3, self.matmul(other));
|
return VAR_T(Vec3, self.matmul(other));
|
||||||
}
|
}
|
||||||
@ -540,10 +540,11 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
|
|||||||
|
|
||||||
void add_module_linalg(VM* vm){
|
void add_module_linalg(VM* vm){
|
||||||
PyObject* linalg = vm->new_module("linalg");
|
PyObject* linalg = vm->new_module("linalg");
|
||||||
Vec2::register_class(vm, linalg);
|
|
||||||
Vec3::register_class(vm, linalg);
|
vm->register_user_class<Vec2>(linalg, "vec2");
|
||||||
Vec4::register_class(vm, linalg);
|
vm->register_user_class<Vec3>(linalg, "vec3");
|
||||||
Mat3x3::register_class(vm, linalg);
|
vm->register_user_class<Vec4>(linalg, "vec4");
|
||||||
|
vm->register_user_class<Mat3x3>(linalg, "mat3x3");
|
||||||
|
|
||||||
PyObject* float_p = vm->_modules["c"]->attr("float_p");
|
PyObject* float_p = vm->_modules["c"]->attr("float_p");
|
||||||
linalg->attr().set("vec2_p", float_p);
|
linalg->attr().set("vec2_p", float_p);
|
||||||
|
@ -13,8 +13,6 @@ void add_module_operator(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct PyStructTime{
|
struct PyStructTime{
|
||||||
PY_CLASS(PyStructTime, time, struct_time)
|
|
||||||
|
|
||||||
int tm_year;
|
int tm_year;
|
||||||
int tm_mon;
|
int tm_mon;
|
||||||
int tm_mday;
|
int tm_mday;
|
||||||
@ -56,7 +54,7 @@ struct PyStructTime{
|
|||||||
|
|
||||||
void add_module_time(VM* vm){
|
void add_module_time(VM* vm){
|
||||||
PyObject* mod = vm->new_module("time");
|
PyObject* mod = vm->new_module("time");
|
||||||
PyStructTime::register_class(vm, mod);
|
vm->register_user_class<PyStructTime>(mod, "struct_time");
|
||||||
|
|
||||||
vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) {
|
vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) {
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
@ -298,8 +296,6 @@ struct _LpGuard{
|
|||||||
|
|
||||||
// line_profiler wrapper
|
// line_profiler wrapper
|
||||||
struct LineProfilerW{
|
struct LineProfilerW{
|
||||||
PY_CLASS(LineProfilerW, line_profiler, LineProfiler)
|
|
||||||
|
|
||||||
LineProfiler profiler;
|
LineProfiler profiler;
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||||
@ -352,7 +348,7 @@ _LpGuard::~_LpGuard(){
|
|||||||
|
|
||||||
void add_module_line_profiler(VM *vm){
|
void add_module_line_profiler(VM *vm){
|
||||||
PyObject* mod = vm->new_module("line_profiler");
|
PyObject* mod = vm->new_module("line_profiler");
|
||||||
LineProfilerW::register_class(vm, mod);
|
vm->register_user_class<LineProfilerW>(mod, "LineProfiler");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void add_module_line_profiler(VM* vm){
|
void add_module_line_profiler(VM* vm){
|
||||||
|
@ -1383,7 +1383,7 @@ void init_builtins(VM* _vm) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<0>(VM::tp_dict, "items", [](VM* vm, ArgsView args) {
|
_vm->bind_method<0>(VM::tp_dict, "items", [](VM* vm, ArgsView args) {
|
||||||
return vm->heap.gcnew<DictItemsIter>(DictItemsIter::_type(vm), args[0]);
|
return vm->new_user_object<DictItemsIter>(args[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
_vm->bind_method<1>(VM::tp_dict, "update", [](VM* vm, ArgsView args) {
|
_vm->bind_method<1>(VM::tp_dict, "update", [](VM* vm, ArgsView args) {
|
||||||
@ -1495,11 +1495,11 @@ void init_builtins(VM* _vm) {
|
|||||||
return VAR(self.msg);
|
return VAR(self.msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
RangeIter::register_class(_vm, _vm->builtins);
|
_vm->register_user_class<RangeIter>(_vm->builtins, "_range_iter");
|
||||||
ArrayIter::register_class(_vm, _vm->builtins);
|
_vm->register_user_class<ArrayIter>(_vm->builtins, "_array_iter");
|
||||||
StringIter::register_class(_vm, _vm->builtins);
|
_vm->register_user_class<StringIter>(_vm->builtins, "_string_iter");
|
||||||
Generator::register_class(_vm, _vm->builtins);
|
_vm->register_user_class<Generator>(_vm->builtins, "generator");
|
||||||
DictItemsIter::register_class(_vm, _vm->builtins);
|
_vm->register_user_class<DictItemsIter>(_vm->builtins, "_dict_items_iter");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::post_init(){
|
void VM::post_init(){
|
||||||
|
@ -277,7 +277,7 @@ bool pkpy_is_voidp(pkpy_vm* vm_handle, int i){
|
|||||||
PK_ASSERT_NO_ERROR()
|
PK_ASSERT_NO_ERROR()
|
||||||
PK_PROTECTED(
|
PK_PROTECTED(
|
||||||
PyObject* item = stack_item(vm, i);
|
PyObject* item = stack_item(vm, i);
|
||||||
return is_type(item, VoidP::_type(vm));
|
return vm->is_user_type<VoidP>(item);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,6 @@ struct mt19937{
|
|||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
struct Random{
|
struct Random{
|
||||||
PY_CLASS(Random, random, Random)
|
|
||||||
mt19937 gen;
|
mt19937 gen;
|
||||||
|
|
||||||
Random(){
|
Random(){
|
||||||
@ -215,8 +214,8 @@ struct Random{
|
|||||||
|
|
||||||
void add_module_random(VM* vm){
|
void add_module_random(VM* vm){
|
||||||
PyObject* mod = vm->new_module("random");
|
PyObject* mod = vm->new_module("random");
|
||||||
Random::register_class(vm, mod);
|
vm->register_user_class<Random>(mod, "Random");
|
||||||
PyObject* instance = vm->heap.gcnew<Random>(Random::_type(vm));
|
PyObject* instance = vm->new_user_object<Random>();
|
||||||
mod->attr().set("seed", vm->getattr(instance, "seed"));
|
mod->attr().set("seed", vm->getattr(instance, "seed"));
|
||||||
mod->attr().set("random", vm->getattr(instance, "random"));
|
mod->attr().set("random", vm->getattr(instance, "random"));
|
||||||
mod->attr().set("uniform", vm->getattr(instance, "uniform"));
|
mod->attr().set("uniform", vm->getattr(instance, "uniform"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user