|
|
@@ -2,23 +2,13 @@
|
|
|
|
|
|
#include "vm.h"
|
|
|
|
|
|
-// struct Point2{
|
|
|
-// int x;
|
|
|
-// int y;
|
|
|
-// };
|
|
|
-
|
|
|
-// std::map<std::string_view, int> _Point2_members = {
|
|
|
-// {"x", offsetof(Point2, x)},
|
|
|
-// {"y", offsetof(Point2, y)},
|
|
|
-// };
|
|
|
-
|
|
|
struct CType{
|
|
|
PY_CLASS(c, type_)
|
|
|
|
|
|
const char* name; // must be a literal
|
|
|
const int size;
|
|
|
const int index;
|
|
|
- constexpr CType(const char name[], int size, int index=-1) : name(name), size(size), index(index) {}
|
|
|
+ constexpr CType(const char name[], int size, int index) : name(name), size(size), index(index) {}
|
|
|
|
|
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
|
|
vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
|
|
@@ -200,7 +190,20 @@ struct StructMemberInfo {
|
|
|
|
|
|
struct StructMetaInfo {
|
|
|
Str name;
|
|
|
- std::map<std::string_view, StructMemberInfo> members;
|
|
|
+ std::map<StrName, StructMemberInfo> members;
|
|
|
+};
|
|
|
+
|
|
|
+struct Point2{
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+};
|
|
|
+
|
|
|
+static const StructMetaInfo _Point2_info = {
|
|
|
+ "Point2",
|
|
|
+ {
|
|
|
+ {StrName("x"), {offsetof(Point2, x), C_TYPE_T("int_")}},
|
|
|
+ {StrName("y"), {offsetof(Point2, y), C_TYPE_T("int_")}},
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
struct Struct {
|
|
|
@@ -210,47 +213,38 @@ struct Struct {
|
|
|
int8_t* _data; // store any `struct`
|
|
|
|
|
|
Struct(const StructMetaInfo* info, int8_t* data) : info(info), _data(data) {}
|
|
|
+ Struct(){
|
|
|
+ info = &_Point2_info;
|
|
|
+ _data = new int8_t[sizeof(Point2)];
|
|
|
+ }
|
|
|
~Struct(){ delete[] _data; }
|
|
|
|
|
|
- int8_t* address(std::string_view name){
|
|
|
+ Pointer address(VM* vm, StrName name){
|
|
|
auto it = info->members.find(name);
|
|
|
- if(it == info->members.end()) return nullptr;
|
|
|
- return _data + it->second.offset;
|
|
|
+ if(it == info->members.end()) vm->AttributeError("struct " + info->name + " has no member " + name.str());
|
|
|
+ const StructMemberInfo& info = it->second;
|
|
|
+ return {_data+info.offset, info.type};
|
|
|
+ }
|
|
|
+
|
|
|
+ PyVarOrNull __getattr__(VM* vm, StrName name){
|
|
|
+ return address(vm, name).get(vm);
|
|
|
+ }
|
|
|
+
|
|
|
+ void __setattr__(VM* vm, StrName name, const PyVar& val){
|
|
|
+ address(vm, name).set(vm, val);
|
|
|
}
|
|
|
|
|
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
|
|
- vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
|
|
|
+ vm->bind_static_method<-1>(type, "__new__", [](VM* vm, pkpy::Args& args) {
|
|
|
+ return vm->new_object<Struct>();
|
|
|
+ });
|
|
|
|
|
|
vm->bind_method<0>(type, "__repr__", [](VM* vm, pkpy::Args& args) {
|
|
|
Struct& self = vm->py_cast<Struct>(args[0]);
|
|
|
StrStream ss;
|
|
|
- ss << "<c._struct '" << self.info->name << "'>";
|
|
|
+ ss << self.info->name << "(" << ")";
|
|
|
return vm->PyStr(ss.str());
|
|
|
});
|
|
|
-
|
|
|
-#define MEMBER_LOOKUP() \
|
|
|
- Struct& self = vm->py_cast<Struct>(args[0]); \
|
|
|
- std::string_view name = vm->PyStr_AS_C(args[1]); \
|
|
|
- auto it = self.info->members.find(name); \
|
|
|
- if(it == self.info->members.end()){ \
|
|
|
- vm->AttributeError(args[0], name.data()); \
|
|
|
- return vm->None; \
|
|
|
- } \
|
|
|
- const StructMemberInfo& info = it->second; \
|
|
|
- Pointer p = Pointer(self._data+info.offset, info.type); \
|
|
|
-
|
|
|
- vm->bind_method<1>(type, "__getattr__", [](VM* vm, pkpy::Args& args) {
|
|
|
- MEMBER_LOOKUP()
|
|
|
- return p.get(vm);
|
|
|
- });
|
|
|
-
|
|
|
- vm->bind_method<2>(type, "__setattr__", [](VM* vm, pkpy::Args& args) {
|
|
|
- MEMBER_LOOKUP()
|
|
|
- p.set(vm, args[2]);
|
|
|
- return vm->None;
|
|
|
- });
|
|
|
-
|
|
|
-#undef MEMBER_LOOKUP
|
|
|
}
|
|
|
};
|
|
|
|