This commit is contained in:
blueloveTH 2023-09-27 05:31:01 +08:00
parent 888982ef7a
commit 5a42d35f9d
10 changed files with 156 additions and 185 deletions

View File

@ -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);

View File

@ -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

View File

@ -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
View 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

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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)

View File

@ -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}'

View File

@ -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)