mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30: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__)
|
||||
|
||||
int c99_sizeof(VM*, const Str&);
|
||||
|
||||
inline PyObject* py_var(VM* vm, void* 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){
|
||||
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);
|
||||
}
|
||||
|
||||
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_<Tuple>) <= 64);
|
||||
|
||||
|
@ -4,14 +4,13 @@
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
static constexpr float kEpsilon = 1e-4f;
|
||||
inline static bool isclose(float a, float b){ return fabsf(a - b) < kEpsilon; }
|
||||
inline bool isclose(float a, float b){ return fabsf(a - b) < 1e-4f; }
|
||||
|
||||
struct Vec2{
|
||||
float x, y;
|
||||
Vec2() : x(0.0f), y(0.0f) {}
|
||||
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) { x += v.x; y += v.y; return *this; }
|
||||
@ -35,7 +34,7 @@ struct Vec3{
|
||||
float x, y, z;
|
||||
Vec3() : x(0.0f), y(0.0f), z(0.0f) {}
|
||||
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) { x += v.x; y += v.y; z += v.z; return *this; }
|
||||
@ -59,7 +58,7 @@ struct Vec4{
|
||||
float x, y, z, w;
|
||||
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(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) { 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)
|
||||
, _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_ones(){ for (int i=0; i<9; ++i) v[i] = 1.0f; }
|
||||
void set_identity(){ set_zeros(); _11 = _22 = _33 = 1.0f; }
|
||||
@ -208,7 +209,7 @@ struct Mat3x3{
|
||||
|
||||
bool inverse(Mat3x3& ret) const{
|
||||
float det = determinant();
|
||||
if (fabsf(det) < kEpsilon) return false;
|
||||
if (isclose(det, 0)) return false;
|
||||
float inv_det = 1.0f / det;
|
||||
ret._11 = (_22 * _33 - _23 * _32) * inv_det;
|
||||
ret._12 = (_13 * _32 - _12 * _33) * inv_det;
|
||||
@ -233,7 +234,7 @@ struct Mat3x3{
|
||||
|
||||
bool is_affine() const{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -274,7 +275,7 @@ struct PyVec2: Vec2 {
|
||||
|
||||
PyVec2() : Vec2() {}
|
||||
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);
|
||||
};
|
||||
@ -284,7 +285,7 @@ struct PyVec3: Vec3 {
|
||||
|
||||
PyVec3() : Vec3() {}
|
||||
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);
|
||||
};
|
||||
@ -294,7 +295,7 @@ struct PyVec4: Vec4{
|
||||
|
||||
PyVec4(): Vec4(){}
|
||||
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);
|
||||
};
|
||||
@ -304,7 +305,7 @@ struct PyMat3x3: Mat3x3{
|
||||
|
||||
PyMat3x3(): Mat3x3(){}
|
||||
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);
|
||||
};
|
||||
@ -340,5 +341,9 @@ inline void add_module_linalg(VM* vm){
|
||||
}
|
||||
|
||||
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
|
@ -3,15 +3,9 @@ from typing import overload
|
||||
def malloc(size: int) -> 'void_p': ...
|
||||
def free(ptr: 'void_p') -> None: ...
|
||||
def sizeof(type: str) -> int: ...
|
||||
def refl(name: str) -> '_refl': ...
|
||||
def memset(ptr: 'void_p', value: int, 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:
|
||||
def __add__(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_void_p(self) -> 'void_p': ...
|
||||
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_uchar(self, value: int) -> None: ...
|
||||
@ -60,11 +54,7 @@ class struct:
|
||||
@overload
|
||||
def __init__(self, size: int): ...
|
||||
@overload
|
||||
def __init__(self, p: 'void_p', size: int): ...
|
||||
@overload
|
||||
def __init__(self, s: str): ...
|
||||
@overload
|
||||
def __init__(self, b: bytes): ...
|
||||
def __init__(self, buffer: bytes): ...
|
||||
|
||||
def addr(self) -> 'void_p': ...
|
||||
def copy(self) -> 'struct': ...
|
||||
@ -72,9 +62,6 @@ class struct:
|
||||
def __eq__(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_uchar(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_void_p(self, value: 'void_p', offset=0) -> None: ...
|
||||
|
||||
char_ = refl("char")
|
||||
uchar_ = refl("uchar")
|
||||
short_ = refl("short")
|
||||
ushort_ = refl("ushort")
|
||||
int_ = refl("int")
|
||||
uint_ = refl("uint")
|
||||
long_ = refl("long")
|
||||
ulong_ = refl("ulong")
|
||||
longlong_ = refl("longlong")
|
||||
ulonglong_ = refl("ulonglong")
|
||||
float_ = refl("float")
|
||||
double_ = refl("double")
|
||||
bool_ = refl("bool")
|
||||
def char_(val: int) -> struct: ...
|
||||
def uchar_(val: int) -> struct: ...
|
||||
def short_(val: int) -> struct: ...
|
||||
def ushort_(val: int) -> struct: ...
|
||||
def int_(val: int) -> struct: ...
|
||||
def uint_(val: int) -> struct: ...
|
||||
def long_(val: int) -> struct: ...
|
||||
def ulong_(val: int) -> struct: ...
|
||||
def longlong_(val: int) -> struct: ...
|
||||
def ulonglong_(val: int) -> struct: ...
|
||||
def float_(val: float) -> struct: ...
|
||||
def double_(val: float) -> struct: ...
|
||||
def bool_(val: bool) -> struct: ...
|
||||
|
||||
char_p = void_p
|
||||
uchar_p = void_p
|
||||
@ -132,3 +119,12 @@ ulonglong_p = void_p
|
||||
float_p = void_p
|
||||
double_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):
|
||||
return self._a.items()
|
||||
|
||||
def pop(self, key):
|
||||
return self._a.pop(key)
|
||||
def pop(self, *args):
|
||||
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){
|
||||
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]);
|
||||
if(args.size() == 1+1){
|
||||
if(is_int(args[1])){
|
||||
int size = _CAST(int, args[1]);
|
||||
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)){
|
||||
const Bytes& b = _CAST(Bytes&, args[1]);
|
||||
return vm->heap.gcnew<C99Struct>(cls, (void*)b.data(), b.size());
|
||||
}
|
||||
vm->TypeError("expected int, str 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");
|
||||
vm->TypeError("expected int or bytes");
|
||||
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){
|
||||
C99Struct& self = _CAST(C99Struct&, args[0]);
|
||||
return VAR_T(VoidP, self.p);
|
||||
@ -142,18 +142,6 @@ namespace pkpy{
|
||||
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){
|
||||
C99Struct& self = _CAST(C99Struct&, lhs);
|
||||
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){
|
||||
VoidP& self = _CAST(VoidP&, args[0]);
|
||||
const Str& type = CAST(Str&, args[1]);
|
||||
int size = c99_sizeof(vm, type);
|
||||
int size = CAST(int, args[1]);
|
||||
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){
|
||||
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){
|
||||
const Str& type = CAST(Str&, args[0]);
|
||||
i64 size = c99_sizeof(vm, type);
|
||||
return VAR(size);
|
||||
});
|
||||
|
||||
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);
|
||||
auto it = _refl_types.find(type.sv());
|
||||
if(it != _refl_types.end()) return VAR(it->second.size);
|
||||
vm->ValueError("not a valid c99 type");
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
VoidP::register_class(vm, mod);
|
||||
C99Struct::register_class(vm, mod);
|
||||
C99ReflType::register_class(vm, mod);
|
||||
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*));
|
||||
|
||||
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){
|
||||
auto it = _refl_types.find(type.sv());
|
||||
if(it != _refl_types.end()) return it->second.size;
|
||||
vm->ValueError("not a valid c99 type");
|
||||
return 0;
|
||||
#define BIND_PRIMITIVE(T, name) \
|
||||
vm->bind_func<1>(mod, name "_", [](VM* vm, ArgsView args){ \
|
||||
T val = CAST(T, args[0]); \
|
||||
return VAR_T(C99Struct, &val, sizeof(T)); \
|
||||
}); \
|
||||
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
|
@ -352,6 +352,18 @@ void init_builtins(VM* _vm) {
|
||||
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<-1>("range", [](VM* vm, ArgsView args) {
|
||||
|
@ -1,23 +1,18 @@
|
||||
import c
|
||||
|
||||
c_int = c.refl("int")
|
||||
assert c_int.size() == c.sizeof("int")
|
||||
array = c.malloc(c.sizeof("int") * 10)
|
||||
|
||||
for i in range(10):
|
||||
off = c.sizeof("int") * i
|
||||
(array+off).write_int(i)
|
||||
|
||||
x = c_int()
|
||||
x.addr().write_int(0)
|
||||
x = c.int_(0)
|
||||
for i in range(10):
|
||||
off = c.sizeof("int") * i
|
||||
i = (array+off).read_int()
|
||||
x.addr().write_int(
|
||||
x.addr().read_int() + i
|
||||
)
|
||||
x.write_int(x.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)
|
||||
|
||||
|
@ -332,7 +332,10 @@ for i in range(3):
|
||||
for j in range(3):
|
||||
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])
|
||||
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
|
||||
|
||||
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'
|
||||
|
||||
# ------------------------------------------------
|
||||
@ -49,17 +40,15 @@ c_void_1.read_bytes(5)
|
||||
c_void_1.write_bytes(c_void_1.read_bytes(5))
|
||||
# ------------------------------------------------
|
||||
c_void_1 = c.malloc(32)
|
||||
my_struct2 = c.struct(c_void_1, 32)
|
||||
|
||||
data_str = "Hello, World!"
|
||||
my_struct3 = c.struct(data_str)
|
||||
my_struct2 = c_void_1.read_struct(32)
|
||||
assert my_struct2.size() == 32
|
||||
|
||||
data_bytes = bytes([1,2,3])
|
||||
my_struct4 = c.struct(data_bytes)
|
||||
|
||||
try:
|
||||
c.struct(True)
|
||||
raise Exception('c.struct 的构造方法未能触发 TypeError("expected int, str or bytes")')
|
||||
raise Exception('c.struct 的构造方法未能触发 TypeError("expected int or bytes")')
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
@ -75,18 +64,25 @@ assert my_struct1.size() == 16
|
||||
# 对 c.struct 的 copy 方法的测试不完全
|
||||
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])
|
||||
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)
|
||||
my_struct1 = c.struct(16)
|
||||
c_void_1.read_struct('long')
|
||||
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