mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
...
This commit is contained in:
parent
888982ef7a
commit
5a42d35f9d
@ -29,8 +29,6 @@ namespace pkpy {
|
|||||||
|
|
||||||
#define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), __VA_ARGS__)
|
#define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), __VA_ARGS__)
|
||||||
|
|
||||||
int c99_sizeof(VM*, const Str&);
|
|
||||||
|
|
||||||
inline PyObject* py_var(VM* vm, void* p);
|
inline PyObject* py_var(VM* vm, void* p);
|
||||||
inline PyObject* py_var(VM* vm, char* p);
|
inline PyObject* py_var(VM* vm, char* p);
|
||||||
|
|
||||||
@ -80,13 +78,6 @@ struct C99Struct{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
C99Struct(std::monostate _, const T& data): C99Struct(sizeof(T)){
|
|
||||||
static_assert(is_pod<T>::value);
|
|
||||||
static_assert(!std::is_pointer_v<T>);
|
|
||||||
memcpy(p, &data, this->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
C99Struct(void* p, int size): C99Struct(size){
|
C99Struct(void* p, int size): C99Struct(size){
|
||||||
if(p != nullptr) memcpy(this->p, p, size);
|
if(p != nullptr) memcpy(this->p, p, size);
|
||||||
}
|
}
|
||||||
@ -120,17 +111,6 @@ inline void add_refl_type(std::string_view name, size_t size){
|
|||||||
_refl_types[name] = std::move(type);
|
_refl_types[name] = std::move(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C99ReflType final: ReflType{
|
|
||||||
PY_CLASS(C99ReflType, c, _refl)
|
|
||||||
|
|
||||||
C99ReflType(const ReflType& type){
|
|
||||||
this->name = type.name;
|
|
||||||
this->size = type.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(Py_<C99Struct>) <= 64);
|
static_assert(sizeof(Py_<C99Struct>) <= 64);
|
||||||
static_assert(sizeof(Py_<Tuple>) <= 64);
|
static_assert(sizeof(Py_<Tuple>) <= 64);
|
||||||
|
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
static constexpr float kEpsilon = 1e-4f;
|
inline bool isclose(float a, float b){ return fabsf(a - b) < 1e-4f; }
|
||||||
inline static bool isclose(float a, float b){ return fabsf(a - b) < kEpsilon; }
|
|
||||||
|
|
||||||
struct Vec2{
|
struct Vec2{
|
||||||
float x, y;
|
float x, y;
|
||||||
Vec2() : x(0.0f), y(0.0f) {}
|
Vec2() : x(0.0f), y(0.0f) {}
|
||||||
Vec2(float x, float y) : x(x), y(y) {}
|
Vec2(float x, float y) : x(x), y(y) {}
|
||||||
Vec2(const Vec2& v) : x(v.x), y(v.y) {}
|
Vec2(const Vec2& v) = default;
|
||||||
|
|
||||||
Vec2 operator+(const Vec2& v) const { return Vec2(x + v.x, y + v.y); }
|
Vec2 operator+(const Vec2& v) const { return Vec2(x + v.x, y + v.y); }
|
||||||
Vec2& operator+=(const Vec2& v) { x += v.x; y += v.y; return *this; }
|
Vec2& operator+=(const Vec2& v) { x += v.x; y += v.y; return *this; }
|
||||||
@ -35,7 +34,7 @@ struct Vec3{
|
|||||||
float x, y, z;
|
float x, y, z;
|
||||||
Vec3() : x(0.0f), y(0.0f), z(0.0f) {}
|
Vec3() : x(0.0f), y(0.0f), z(0.0f) {}
|
||||||
Vec3(float x, float y, float z) : x(x), y(y), z(z) {}
|
Vec3(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||||
Vec3(const Vec3& v) : x(v.x), y(v.y), z(v.z) {}
|
Vec3(const Vec3& v) = default;
|
||||||
|
|
||||||
Vec3 operator+(const Vec3& v) const { return Vec3(x + v.x, y + v.y, z + v.z); }
|
Vec3 operator+(const Vec3& v) const { return Vec3(x + v.x, y + v.y, z + v.z); }
|
||||||
Vec3& operator+=(const Vec3& v) { x += v.x; y += v.y; z += v.z; return *this; }
|
Vec3& operator+=(const Vec3& v) { x += v.x; y += v.y; z += v.z; return *this; }
|
||||||
@ -59,7 +58,7 @@ struct Vec4{
|
|||||||
float x, y, z, w;
|
float x, y, z, w;
|
||||||
Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
|
Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
|
||||||
Vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
|
Vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
|
||||||
Vec4(const Vec4& v) : x(v.x), y(v.y), z(v.z), w(v.w) {}
|
Vec4(const Vec4& v) = default;
|
||||||
|
|
||||||
Vec4 operator+(const Vec4& v) const { return Vec4(x + v.x, y + v.y, z + v.z, w + v.w); }
|
Vec4 operator+(const Vec4& v) const { return Vec4(x + v.x, y + v.y, z + v.z, w + v.w); }
|
||||||
Vec4& operator+=(const Vec4& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
|
Vec4& operator+=(const Vec4& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
|
||||||
@ -97,6 +96,8 @@ struct Mat3x3{
|
|||||||
, _21(_21), _22(_22), _23(_23)
|
, _21(_21), _22(_22), _23(_23)
|
||||||
, _31(_31), _32(_32), _33(_33) {}
|
, _31(_31), _32(_32), _33(_33) {}
|
||||||
|
|
||||||
|
Mat3x3(const Mat3x3& other) = default;
|
||||||
|
|
||||||
void set_zeros(){ for (int i=0; i<9; ++i) v[i] = 0.0f; }
|
void set_zeros(){ for (int i=0; i<9; ++i) v[i] = 0.0f; }
|
||||||
void set_ones(){ for (int i=0; i<9; ++i) v[i] = 1.0f; }
|
void set_ones(){ for (int i=0; i<9; ++i) v[i] = 1.0f; }
|
||||||
void set_identity(){ set_zeros(); _11 = _22 = _33 = 1.0f; }
|
void set_identity(){ set_zeros(); _11 = _22 = _33 = 1.0f; }
|
||||||
@ -208,7 +209,7 @@ struct Mat3x3{
|
|||||||
|
|
||||||
bool inverse(Mat3x3& ret) const{
|
bool inverse(Mat3x3& ret) const{
|
||||||
float det = determinant();
|
float det = determinant();
|
||||||
if (fabsf(det) < kEpsilon) return false;
|
if (isclose(det, 0)) return false;
|
||||||
float inv_det = 1.0f / det;
|
float inv_det = 1.0f / det;
|
||||||
ret._11 = (_22 * _33 - _23 * _32) * inv_det;
|
ret._11 = (_22 * _33 - _23 * _32) * inv_det;
|
||||||
ret._12 = (_13 * _32 - _12 * _33) * inv_det;
|
ret._12 = (_13 * _32 - _12 * _33) * inv_det;
|
||||||
@ -233,7 +234,7 @@ struct Mat3x3{
|
|||||||
|
|
||||||
bool is_affine() const{
|
bool is_affine() const{
|
||||||
float det = _11 * _22 - _12 * _21;
|
float det = _11 * _22 - _12 * _21;
|
||||||
if(fabsf(det) < kEpsilon) return false;
|
if(!isclose(det, 0)) return false;
|
||||||
return _31 == 0.0f && _32 == 0.0f && _33 == 1.0f;
|
return _31 == 0.0f && _32 == 0.0f && _33 == 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +275,7 @@ struct PyVec2: Vec2 {
|
|||||||
|
|
||||||
PyVec2() : Vec2() {}
|
PyVec2() : Vec2() {}
|
||||||
PyVec2(const Vec2& v) : Vec2(v) {}
|
PyVec2(const Vec2& v) : Vec2(v) {}
|
||||||
PyVec2(const PyVec2& v) : Vec2(v) {}
|
PyVec2(const PyVec2& v) = default;
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
};
|
};
|
||||||
@ -284,7 +285,7 @@ struct PyVec3: Vec3 {
|
|||||||
|
|
||||||
PyVec3() : Vec3() {}
|
PyVec3() : Vec3() {}
|
||||||
PyVec3(const Vec3& v) : Vec3(v) {}
|
PyVec3(const Vec3& v) : Vec3(v) {}
|
||||||
PyVec3(const PyVec3& v) : Vec3(v) {}
|
PyVec3(const PyVec3& v) = default;
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
};
|
};
|
||||||
@ -294,7 +295,7 @@ struct PyVec4: Vec4{
|
|||||||
|
|
||||||
PyVec4(): Vec4(){}
|
PyVec4(): Vec4(){}
|
||||||
PyVec4(const Vec4& v): Vec4(v){}
|
PyVec4(const Vec4& v): Vec4(v){}
|
||||||
PyVec4(const PyVec4& v): Vec4(v){}
|
PyVec4(const PyVec4& v) = default;
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
};
|
};
|
||||||
@ -304,7 +305,7 @@ struct PyMat3x3: Mat3x3{
|
|||||||
|
|
||||||
PyMat3x3(): Mat3x3(){}
|
PyMat3x3(): Mat3x3(){}
|
||||||
PyMat3x3(const Mat3x3& other): Mat3x3(other){}
|
PyMat3x3(const Mat3x3& other): Mat3x3(other){}
|
||||||
PyMat3x3(const PyMat3x3& other): Mat3x3(other){}
|
PyMat3x3(const PyMat3x3& other) = default;
|
||||||
|
|
||||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||||
};
|
};
|
||||||
@ -340,5 +341,9 @@ inline void add_module_linalg(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(Py_<PyMat3x3>) <= 64);
|
static_assert(sizeof(Py_<PyMat3x3>) <= 64);
|
||||||
|
static_assert(std::is_trivially_copyable<PyVec2>::value);
|
||||||
|
static_assert(std::is_trivially_copyable<PyVec3>::value);
|
||||||
|
static_assert(std::is_trivially_copyable<PyVec4>::value);
|
||||||
|
static_assert(std::is_trivially_copyable<PyMat3x3>::value);
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -3,15 +3,9 @@ from typing import overload
|
|||||||
def malloc(size: int) -> 'void_p': ...
|
def malloc(size: int) -> 'void_p': ...
|
||||||
def free(ptr: 'void_p') -> None: ...
|
def free(ptr: 'void_p') -> None: ...
|
||||||
def sizeof(type: str) -> int: ...
|
def sizeof(type: str) -> int: ...
|
||||||
def refl(name: str) -> '_refl': ...
|
|
||||||
def memset(ptr: 'void_p', value: int, size: int) -> None: ...
|
def memset(ptr: 'void_p', value: int, size: int) -> None: ...
|
||||||
def memcpy(dst: 'void_p', src: 'void_p', size: int) -> None: ...
|
def memcpy(dst: 'void_p', src: 'void_p', size: int) -> None: ...
|
||||||
|
|
||||||
class _refl:
|
|
||||||
def __call__(self) -> 'struct': ...
|
|
||||||
def name(self) -> str: ...
|
|
||||||
def size(self) -> int: ...
|
|
||||||
|
|
||||||
class void_p:
|
class void_p:
|
||||||
def __add__(self, i: int) -> 'void_p': ...
|
def __add__(self, i: int) -> 'void_p': ...
|
||||||
def __sub__(self, i: int) -> 'void_p': ...
|
def __sub__(self, i: int) -> 'void_p': ...
|
||||||
@ -37,7 +31,7 @@ class void_p:
|
|||||||
def read_bool(self) -> bool: ...
|
def read_bool(self) -> bool: ...
|
||||||
def read_void_p(self) -> 'void_p': ...
|
def read_void_p(self) -> 'void_p': ...
|
||||||
def read_bytes(self, size: int) -> bytes: ...
|
def read_bytes(self, size: int) -> bytes: ...
|
||||||
def read_struct(self, type: str) -> 'struct': ...
|
def read_struct(self, size: int) -> 'struct': ...
|
||||||
|
|
||||||
def write_char(self, value: int) -> None: ...
|
def write_char(self, value: int) -> None: ...
|
||||||
def write_uchar(self, value: int) -> None: ...
|
def write_uchar(self, value: int) -> None: ...
|
||||||
@ -60,11 +54,7 @@ class struct:
|
|||||||
@overload
|
@overload
|
||||||
def __init__(self, size: int): ...
|
def __init__(self, size: int): ...
|
||||||
@overload
|
@overload
|
||||||
def __init__(self, p: 'void_p', size: int): ...
|
def __init__(self, buffer: bytes): ...
|
||||||
@overload
|
|
||||||
def __init__(self, s: str): ...
|
|
||||||
@overload
|
|
||||||
def __init__(self, b: bytes): ...
|
|
||||||
|
|
||||||
def addr(self) -> 'void_p': ...
|
def addr(self) -> 'void_p': ...
|
||||||
def copy(self) -> 'struct': ...
|
def copy(self) -> 'struct': ...
|
||||||
@ -72,9 +62,6 @@ class struct:
|
|||||||
def __eq__(self, other: 'struct') -> bool: ...
|
def __eq__(self, other: 'struct') -> bool: ...
|
||||||
def __ne__(self, other: 'struct') -> bool: ...
|
def __ne__(self, other: 'struct') -> bool: ...
|
||||||
|
|
||||||
def to_string(self) -> str: ...
|
|
||||||
def to_bytes(self) -> bytes: ...
|
|
||||||
|
|
||||||
def read_char(self, offset=0) -> int: ...
|
def read_char(self, offset=0) -> int: ...
|
||||||
def read_uchar(self, offset=0) -> int: ...
|
def read_uchar(self, offset=0) -> int: ...
|
||||||
def read_short(self, offset=0) -> int: ...
|
def read_short(self, offset=0) -> int: ...
|
||||||
@ -105,19 +92,19 @@ class struct:
|
|||||||
def write_bool(self, value: bool, offset=0) -> None: ...
|
def write_bool(self, value: bool, offset=0) -> None: ...
|
||||||
def write_void_p(self, value: 'void_p', offset=0) -> None: ...
|
def write_void_p(self, value: 'void_p', offset=0) -> None: ...
|
||||||
|
|
||||||
char_ = refl("char")
|
def char_(val: int) -> struct: ...
|
||||||
uchar_ = refl("uchar")
|
def uchar_(val: int) -> struct: ...
|
||||||
short_ = refl("short")
|
def short_(val: int) -> struct: ...
|
||||||
ushort_ = refl("ushort")
|
def ushort_(val: int) -> struct: ...
|
||||||
int_ = refl("int")
|
def int_(val: int) -> struct: ...
|
||||||
uint_ = refl("uint")
|
def uint_(val: int) -> struct: ...
|
||||||
long_ = refl("long")
|
def long_(val: int) -> struct: ...
|
||||||
ulong_ = refl("ulong")
|
def ulong_(val: int) -> struct: ...
|
||||||
longlong_ = refl("longlong")
|
def longlong_(val: int) -> struct: ...
|
||||||
ulonglong_ = refl("ulonglong")
|
def ulonglong_(val: int) -> struct: ...
|
||||||
float_ = refl("float")
|
def float_(val: float) -> struct: ...
|
||||||
double_ = refl("double")
|
def double_(val: float) -> struct: ...
|
||||||
bool_ = refl("bool")
|
def bool_(val: bool) -> struct: ...
|
||||||
|
|
||||||
char_p = void_p
|
char_p = void_p
|
||||||
uchar_p = void_p
|
uchar_p = void_p
|
||||||
@ -132,3 +119,12 @@ ulonglong_p = void_p
|
|||||||
float_p = void_p
|
float_p = void_p
|
||||||
double_p = void_p
|
double_p = void_p
|
||||||
bool_p = void_p
|
bool_p = void_p
|
||||||
|
|
||||||
|
class array(struct):
|
||||||
|
count: int
|
||||||
|
item_size: int
|
||||||
|
|
||||||
|
def __new__(cls, count: int, item_size: int): ...
|
||||||
|
def __getitem__(self, index: int) -> struct: ...
|
||||||
|
def __setitem__(self, index: int, value: struct) -> None: ...
|
||||||
|
def __len__(self) -> int: ...
|
||||||
|
27
python/c.py
Normal file
27
python/c.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
class array(struct):
|
||||||
|
item_count: int
|
||||||
|
item_size: int
|
||||||
|
|
||||||
|
def __new__(cls, item_count: int, item_size: int = 1):
|
||||||
|
obj = struct.__new__(cls, item_count * item_size)
|
||||||
|
obj._enable_instance_dict()
|
||||||
|
obj.item_count = item_count
|
||||||
|
obj.item_size = item_size
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def __getitem__(self, index: int) -> struct:
|
||||||
|
if index < 0 or index >= self.item_count:
|
||||||
|
raise IndexError("array index out of range")
|
||||||
|
p = self.addr() + self.item_size * index
|
||||||
|
return p.read_struct(self.item_size)
|
||||||
|
|
||||||
|
def __setitem__(self, index: int, value: struct) -> None:
|
||||||
|
if index < 0 or index >= self.item_count:
|
||||||
|
raise IndexError("array index out of range")
|
||||||
|
if value.size() != self.item_size:
|
||||||
|
raise ValueError(f"array item size mismatch: {value.size()} != {self.item_size}")
|
||||||
|
p = self.addr() + self.item_size * index
|
||||||
|
p.write_struct(value)
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
return self.item_count
|
@ -156,5 +156,5 @@ class defaultdict:
|
|||||||
def items(self):
|
def items(self):
|
||||||
return self._a.items()
|
return self._a.items()
|
||||||
|
|
||||||
def pop(self, key):
|
def pop(self, *args):
|
||||||
return self._a.pop(key)
|
return self._a.pop(*args)
|
||||||
|
133
src/cffi.cpp
133
src/cffi.cpp
@ -100,33 +100,33 @@ namespace pkpy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void C99Struct::_register(VM* vm, PyObject* mod, PyObject* type){
|
void C99Struct::_register(VM* vm, PyObject* mod, PyObject* type){
|
||||||
vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){
|
vm->bind_constructor<2>(type, [](VM* vm, ArgsView args){
|
||||||
Type cls = PK_OBJ_GET(Type, args[0]);
|
Type cls = PK_OBJ_GET(Type, args[0]);
|
||||||
if(args.size() == 1+1){
|
|
||||||
if(is_int(args[1])){
|
if(is_int(args[1])){
|
||||||
int size = _CAST(int, args[1]);
|
int size = _CAST(int, args[1]);
|
||||||
return vm->heap.gcnew<C99Struct>(cls, size);
|
return vm->heap.gcnew<C99Struct>(cls, size);
|
||||||
}
|
}
|
||||||
if(is_non_tagged_type(args[1], vm->tp_str)){
|
|
||||||
const Str& s = _CAST(Str&, args[1]);
|
|
||||||
return vm->heap.gcnew<C99Struct>(cls, (void*)s.data, s.size);
|
|
||||||
}
|
|
||||||
if(is_non_tagged_type(args[1], vm->tp_bytes)){
|
if(is_non_tagged_type(args[1], vm->tp_bytes)){
|
||||||
const Bytes& b = _CAST(Bytes&, args[1]);
|
const Bytes& b = _CAST(Bytes&, args[1]);
|
||||||
return vm->heap.gcnew<C99Struct>(cls, (void*)b.data(), b.size());
|
return vm->heap.gcnew<C99Struct>(cls, (void*)b.data(), b.size());
|
||||||
}
|
}
|
||||||
vm->TypeError("expected int, str or bytes");
|
vm->TypeError("expected int or bytes");
|
||||||
return vm->None;
|
|
||||||
}
|
|
||||||
if(args.size() == 1+2){
|
|
||||||
void* p = CAST(void*, args[1]);
|
|
||||||
int size = CAST(int, args[2]);
|
|
||||||
return vm->heap.gcnew<C99Struct>(cls, p, size);
|
|
||||||
}
|
|
||||||
vm->TypeError("expected 1 or 2 arguments");
|
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||||
|
C99Struct& self = _CAST(C99Struct&, obj);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "<struct object of " << self.size << " bytes>";
|
||||||
|
return VAR(ss.str());
|
||||||
|
});
|
||||||
|
|
||||||
|
vm->bind__hash__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
|
||||||
|
C99Struct& self = _CAST(C99Struct&, obj);
|
||||||
|
std::string_view view((char*)self.p, self.size);
|
||||||
|
return (i64)std::hash<std::string_view>()(view);
|
||||||
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||||
return VAR_T(VoidP, self.p);
|
return VAR_T(VoidP, self.p);
|
||||||
@ -142,18 +142,6 @@ namespace pkpy{
|
|||||||
return VAR_T(C99Struct, self);
|
return VAR_T(C99Struct, self);
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bind_method<0>(type, "to_string", [](VM* vm, ArgsView args){
|
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
|
||||||
return VAR(Str(self.p, self.size));
|
|
||||||
});
|
|
||||||
|
|
||||||
vm->bind_method<0>(type, "to_bytes", [](VM* vm, ArgsView args){
|
|
||||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
|
||||||
std::vector<char> buffer(self.size);
|
|
||||||
memcpy(buffer.data(), self.p, self.size);
|
|
||||||
return VAR(Bytes(std::move(buffer)));
|
|
||||||
});
|
|
||||||
|
|
||||||
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_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
|
||||||
@ -198,8 +186,7 @@ namespace pkpy{
|
|||||||
|
|
||||||
vm->bind_method<1>(type, "read_struct", [](VM* vm, ArgsView args){
|
vm->bind_method<1>(type, "read_struct", [](VM* vm, ArgsView args){
|
||||||
VoidP& self = _CAST(VoidP&, args[0]);
|
VoidP& self = _CAST(VoidP&, args[0]);
|
||||||
const Str& type = CAST(Str&, args[1]);
|
int size = CAST(int, args[1]);
|
||||||
int size = c99_sizeof(vm, type);
|
|
||||||
return VAR_T(C99Struct, self.ptr, size);
|
return VAR_T(C99Struct, self.ptr, size);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -211,30 +198,6 @@ namespace pkpy{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void C99ReflType::_register(VM* vm, PyObject* mod, PyObject* type){
|
|
||||||
vm->bind_notimplemented_constructor<C99ReflType>(type);
|
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__call__", [](VM* vm, ArgsView args){
|
|
||||||
C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
||||||
return VAR_T(C99Struct, nullptr, self.size);
|
|
||||||
});
|
|
||||||
|
|
||||||
vm->bind_method<0>(type, "__repr__", [](VM* vm, ArgsView args){
|
|
||||||
C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
||||||
return VAR("<ctype '" + Str(self.name) + "'>");
|
|
||||||
});
|
|
||||||
|
|
||||||
vm->bind_method<0>(type, "name", [](VM* vm, ArgsView args){
|
|
||||||
C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
||||||
return VAR(self.name);
|
|
||||||
});
|
|
||||||
|
|
||||||
vm->bind_method<0>(type, "size", [](VM* vm, ArgsView args){
|
|
||||||
C99ReflType& self = _CAST(C99ReflType&, args[0]);
|
|
||||||
return VAR(self.size);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_module_c(VM* vm){
|
void add_module_c(VM* vm){
|
||||||
PyObject* mod = vm->new_module("c");
|
PyObject* mod = vm->new_module("c");
|
||||||
|
|
||||||
@ -267,50 +230,44 @@ void add_module_c(VM* vm){
|
|||||||
|
|
||||||
vm->bind_func<1>(mod, "sizeof", [](VM* vm, ArgsView args){
|
vm->bind_func<1>(mod, "sizeof", [](VM* vm, ArgsView args){
|
||||||
const Str& type = CAST(Str&, args[0]);
|
const Str& type = CAST(Str&, args[0]);
|
||||||
i64 size = c99_sizeof(vm, type);
|
auto it = _refl_types.find(type.sv());
|
||||||
return VAR(size);
|
if(it != _refl_types.end()) return VAR(it->second.size);
|
||||||
});
|
vm->ValueError("not a valid c99 type");
|
||||||
|
return vm->None;
|
||||||
vm->bind_func<1>(mod, "refl", [](VM* vm, ArgsView args){
|
|
||||||
const Str& key = CAST(Str&, args[0]);
|
|
||||||
auto it = _refl_types.find(key.sv());
|
|
||||||
if(it == _refl_types.end()) vm->ValueError("reflection type not found");
|
|
||||||
const ReflType& rt = it->second;
|
|
||||||
return VAR_T(C99ReflType, rt);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
VoidP::register_class(vm, mod);
|
VoidP::register_class(vm, mod);
|
||||||
C99Struct::register_class(vm, mod);
|
C99Struct::register_class(vm, mod);
|
||||||
C99ReflType::register_class(vm, mod);
|
|
||||||
mod->attr().set("NULL", VAR_T(VoidP, nullptr));
|
mod->attr().set("NULL", VAR_T(VoidP, nullptr));
|
||||||
|
|
||||||
add_refl_type("char", sizeof(char));
|
|
||||||
add_refl_type("uchar", sizeof(unsigned char));
|
|
||||||
add_refl_type("short", sizeof(short));
|
|
||||||
add_refl_type("ushort", sizeof(unsigned short));
|
|
||||||
add_refl_type("int", sizeof(int));
|
|
||||||
add_refl_type("uint", sizeof(unsigned int));
|
|
||||||
add_refl_type("long", sizeof(long));
|
|
||||||
add_refl_type("ulong", sizeof(unsigned long));
|
|
||||||
add_refl_type("longlong", sizeof(long long));
|
|
||||||
add_refl_type("ulonglong", sizeof(unsigned long long));
|
|
||||||
add_refl_type("float", sizeof(float));
|
|
||||||
add_refl_type("double", sizeof(double));
|
|
||||||
add_refl_type("bool", sizeof(bool));
|
|
||||||
add_refl_type("void_p", sizeof(void*));
|
add_refl_type("void_p", sizeof(void*));
|
||||||
|
|
||||||
PyObject* void_p_t = mod->attr("void_p");
|
PyObject* void_p_t = mod->attr("void_p");
|
||||||
for(const char* t: {"char", "uchar", "short", "ushort", "int", "uint", "long", "ulong", "longlong", "ulonglong", "float", "double", "bool"}){
|
|
||||||
mod->attr().set(Str(t) + "_", VAR_T(C99ReflType, _refl_types[t]));
|
|
||||||
mod->attr().set(Str(t) + "_p", void_p_t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int c99_sizeof(VM* vm, const Str& type){
|
#define BIND_PRIMITIVE(T, name) \
|
||||||
auto it = _refl_types.find(type.sv());
|
vm->bind_func<1>(mod, name "_", [](VM* vm, ArgsView args){ \
|
||||||
if(it != _refl_types.end()) return it->second.size;
|
T val = CAST(T, args[0]); \
|
||||||
vm->ValueError("not a valid c99 type");
|
return VAR_T(C99Struct, &val, sizeof(T)); \
|
||||||
return 0;
|
}); \
|
||||||
|
add_refl_type(name, sizeof(T)); \
|
||||||
|
mod->attr().set(name "_p", void_p_t); \
|
||||||
|
|
||||||
|
BIND_PRIMITIVE(char, "char")
|
||||||
|
BIND_PRIMITIVE(unsigned char, "uchar")
|
||||||
|
BIND_PRIMITIVE(short, "short")
|
||||||
|
BIND_PRIMITIVE(unsigned short, "ushort")
|
||||||
|
BIND_PRIMITIVE(int, "int")
|
||||||
|
BIND_PRIMITIVE(unsigned int, "uint")
|
||||||
|
BIND_PRIMITIVE(long, "long")
|
||||||
|
BIND_PRIMITIVE(unsigned long, "ulong")
|
||||||
|
BIND_PRIMITIVE(long long, "longlong")
|
||||||
|
BIND_PRIMITIVE(unsigned long long, "ulonglong")
|
||||||
|
BIND_PRIMITIVE(float, "float")
|
||||||
|
BIND_PRIMITIVE(double, "double")
|
||||||
|
BIND_PRIMITIVE(bool, "bool")
|
||||||
|
|
||||||
|
// add array type
|
||||||
|
CodeObject_ code = vm->compile(kPythonLibs["c"], "c.py", EXEC_MODE);
|
||||||
|
vm->_exec(code, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -352,6 +352,18 @@ void init_builtins(VM* _vm) {
|
|||||||
return vm->heap.gcnew<DummyInstance>(t);
|
return vm->heap.gcnew<DummyInstance>(t);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_vm->bind_method<0>("object", "_enable_instance_dict", [](VM* vm, ArgsView args){
|
||||||
|
PyObject* self = args[0];
|
||||||
|
if(is_tagged(self)){
|
||||||
|
vm->TypeError("object: tagged object cannot enable instance dict");
|
||||||
|
}
|
||||||
|
if(self->is_attr_valid()){
|
||||||
|
vm->TypeError("object: instance dict is already enabled");
|
||||||
|
}
|
||||||
|
self->enable_instance_dict();
|
||||||
|
return vm->None;
|
||||||
|
});
|
||||||
|
|
||||||
_vm->bind_constructor<2>("type", PK_LAMBDA(vm->_t(args[1])));
|
_vm->bind_constructor<2>("type", PK_LAMBDA(vm->_t(args[1])));
|
||||||
|
|
||||||
_vm->bind_constructor<-1>("range", [](VM* vm, ArgsView args) {
|
_vm->bind_constructor<-1>("range", [](VM* vm, ArgsView args) {
|
||||||
|
@ -1,23 +1,18 @@
|
|||||||
import c
|
import c
|
||||||
|
|
||||||
c_int = c.refl("int")
|
|
||||||
assert c_int.size() == c.sizeof("int")
|
|
||||||
array = c.malloc(c.sizeof("int") * 10)
|
array = c.malloc(c.sizeof("int") * 10)
|
||||||
|
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
off = c.sizeof("int") * i
|
off = c.sizeof("int") * i
|
||||||
(array+off).write_int(i)
|
(array+off).write_int(i)
|
||||||
|
|
||||||
x = c_int()
|
x = c.int_(0)
|
||||||
x.addr().write_int(0)
|
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
off = c.sizeof("int") * i
|
off = c.sizeof("int") * i
|
||||||
i = (array+off).read_int()
|
i = (array+off).read_int()
|
||||||
x.addr().write_int(
|
x.write_int(x.read_int() + i)
|
||||||
x.addr().read_int() + i
|
|
||||||
)
|
|
||||||
|
|
||||||
assert x.addr().read_int() == (0+9)*10//2
|
assert x.read_int() == (0+9)*10//2
|
||||||
|
|
||||||
c.memset(array, 0, c.sizeof("int") * 10)
|
c.memset(array, 0, c.sizeof("int") * 10)
|
||||||
|
|
||||||
|
@ -332,7 +332,10 @@ for i in range(3):
|
|||||||
for j in range(3):
|
for j in range(3):
|
||||||
list_mat[i][j] = test_mat[i, j]
|
list_mat[i][j] = test_mat[i, j]
|
||||||
determinant = list_mat[0][0]*(list_mat[1][1]*list_mat[2][2] - list_mat[1][2]*list_mat[2][1]) - list_mat[0][1]*(list_mat[1][0]*list_mat[2][2] - list_mat[1][2]*list_mat[2][0]) + list_mat[0][2]*(list_mat[1][0]*list_mat[2][1] - list_mat[1][1]*list_mat[2][0])
|
determinant = list_mat[0][0]*(list_mat[1][1]*list_mat[2][2] - list_mat[1][2]*list_mat[2][1]) - list_mat[0][1]*(list_mat[1][0]*list_mat[2][2] - list_mat[1][2]*list_mat[2][0]) + list_mat[0][2]*(list_mat[1][0]*list_mat[2][1] - list_mat[1][1]*list_mat[2][0])
|
||||||
assert round(determinant, 3) == round(test_mat_copy.determinant(), 3)
|
_0 = determinant
|
||||||
|
_1 = test_mat_copy.determinant()
|
||||||
|
_0, _1 = round(_0, 2), round(_1, 2)
|
||||||
|
assert (_0 == _1), f'{_0} != {_1}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
import c
|
import c
|
||||||
|
|
||||||
c_int = c.refl("int")
|
|
||||||
assert c_int.name() == "int"
|
|
||||||
assert c_int.__repr__() == '<ctype \'int\'>'
|
|
||||||
# ------------------------------------------------
|
|
||||||
c_int_1 = c.refl("int")
|
|
||||||
c_struct_1 = c_int_1()
|
|
||||||
assert (c_int_1() == c_int_1())
|
|
||||||
assert (c_struct_1 == c_struct_1) == True
|
|
||||||
# ------------------------------------------------
|
|
||||||
assert c.void_p.from_hex('0x2568b60').hex() == '0x2568b60'
|
assert c.void_p.from_hex('0x2568b60').hex() == '0x2568b60'
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
@ -49,17 +40,15 @@ c_void_1.read_bytes(5)
|
|||||||
c_void_1.write_bytes(c_void_1.read_bytes(5))
|
c_void_1.write_bytes(c_void_1.read_bytes(5))
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
c_void_1 = c.malloc(32)
|
c_void_1 = c.malloc(32)
|
||||||
my_struct2 = c.struct(c_void_1, 32)
|
my_struct2 = c_void_1.read_struct(32)
|
||||||
|
assert my_struct2.size() == 32
|
||||||
data_str = "Hello, World!"
|
|
||||||
my_struct3 = c.struct(data_str)
|
|
||||||
|
|
||||||
data_bytes = bytes([1,2,3])
|
data_bytes = bytes([1,2,3])
|
||||||
my_struct4 = c.struct(data_bytes)
|
my_struct4 = c.struct(data_bytes)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
c.struct(True)
|
c.struct(True)
|
||||||
raise Exception('c.struct 的构造方法未能触发 TypeError("expected int, str or bytes")')
|
raise Exception('c.struct 的构造方法未能触发 TypeError("expected int or bytes")')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -75,18 +64,25 @@ assert my_struct1.size() == 16
|
|||||||
# 对 c.struct 的 copy 方法的测试不完全
|
# 对 c.struct 的 copy 方法的测试不完全
|
||||||
assert my_struct1.copy().size() == 16
|
assert my_struct1.copy().size() == 16
|
||||||
|
|
||||||
data_str = "Hello, World!"
|
|
||||||
my_struct3 = c.struct(data_str)
|
|
||||||
assert my_struct3.to_string() == data_str
|
|
||||||
|
|
||||||
data_bytes = bytes([1,2,3])
|
data_bytes = bytes([1,2,3])
|
||||||
my_struct4 = c.struct(data_bytes)
|
my_struct4 = c.struct(data_bytes)
|
||||||
assert my_struct4.to_bytes() == data_bytes
|
assert my_struct4.addr().read_bytes(
|
||||||
|
my_struct4.size()
|
||||||
|
) == data_bytes
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
# 此处测试并不完全
|
# 此处测试并不完全
|
||||||
c_void_1 = c.malloc(16)
|
c_void_1 = c.malloc(16)
|
||||||
my_struct1 = c.struct(16)
|
my_struct1 = c.struct(16)
|
||||||
c_void_1.read_struct('long')
|
|
||||||
c_void_1.write_struct(my_struct1)
|
c_void_1.write_struct(my_struct1)
|
||||||
|
assert c_void_1.read_struct(16) == my_struct1
|
||||||
|
|
||||||
|
from c import array, int_
|
||||||
|
a = array(10, item_size=4)
|
||||||
|
assert a.item_count == 10
|
||||||
|
assert a.item_size == 4
|
||||||
|
|
||||||
|
_ = hash(a)
|
||||||
|
a[4] = int_(123)
|
||||||
|
assert a[4] == int_(123)
|
Loading…
x
Reference in New Issue
Block a user