This commit is contained in:
BLUELOVETH 2023-03-11 14:19:23 +00:00
parent 0a2453a20a
commit d9a45ec60d
3 changed files with 53 additions and 15 deletions

View File

@ -269,28 +269,56 @@ struct Pointer{
}; };
struct Struct { struct Value {
PY_CLASS(Struct, c, struct_) PY_CLASS(Value, c, value_)
char* data; char* data;
Pointer head; Pointer head;
const TypeInfo* ctype() const { return head.ctype; } const TypeInfo* ctype() const { return head.ctype; }
Struct(const Pointer& head) { Value(const TypeInfo* type) {
data = new char[head.ctype->size]; data = new char[type->size];
memcpy(data, head.ptr, head.ctype->size); memset(data, 0, type->size);
this->head = Pointer(head.ctype, head.level, data); this->head = Pointer(type, data);
} }
static void _register(VM* vm, PyVar mod, PyVar type){ 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__", CPP_NOT_IMPLEMENTED());
vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) { vm->bind_method<0>(type, "ptr", [](VM* vm, Args& args) {
Struct& self = CAST(Struct&, args[0]); Value& self = CAST(Value&, args[0]);
StrStream ss; return VAR_T(Pointer, self.head);
ss << self.ctype()->name << "(" << ")"; });
return VAR(ss.str());
vm->bind_method<1>(type, "__getattr__", [](VM* vm, Args& args) {
Value& self = CAST(Value&, args[0]);
const Str& name = CAST(Str&, args[1]);
return self.head._to(vm, name).get(vm);
});
}
};
struct CType{
PY_CLASS(CType, c, ctype)
const TypeInfo* type;
CType() : type(&_type_infos["void"]) {}
CType(const TypeInfo* type) : type(type) {}
static void _register(VM* vm, PyVar mod, PyVar type){
vm->bind_static_method<1>(type, "__new__", [](VM* vm, Args& args) {
const Str& name = CAST(Str&, args[0]);
auto it = _type_infos.find(name);
if (it == _type_infos.end()) vm->TypeError("unknown type: " + name.escape(true));
return VAR_T(CType, &it->second);
});
vm->bind_method<0>(type, "__call__", [](VM* vm, Args& args) {
CType& self = CAST(CType&, args[0]);
return VAR_T(Value, self.type);
}); });
} }
}; };
@ -298,7 +326,8 @@ struct Struct {
void add_module_c(VM* vm){ void add_module_c(VM* vm){
PyVar mod = vm->new_module("c"); PyVar mod = vm->new_module("c");
PyVar ptr_t = Pointer::register_class(vm, mod); PyVar ptr_t = Pointer::register_class(vm, mod);
Struct::register_class(vm, mod); Value::register_class(vm, mod);
CType::register_class(vm, mod);
vm->setattr(mod, "nullptr", VAR_T(Pointer)); vm->setattr(mod, "nullptr", VAR_T(Pointer));

View File

@ -204,6 +204,7 @@ const StrName __len__ = StrName::get("__len__");
const StrName __get__ = StrName::get("__get__"); const StrName __get__ = StrName::get("__get__");
const StrName __getattr__ = StrName::get("__getattr__"); const StrName __getattr__ = StrName::get("__getattr__");
const StrName __setattr__ = StrName::get("__setattr__"); const StrName __setattr__ = StrName::get("__setattr__");
const StrName __call__ = StrName::get("__call__");
const StrName m_eval = StrName::get("eval"); const StrName m_eval = StrName::get("eval");
const StrName m_self = StrName::get("self"); const StrName m_self = StrName::get("self");

View File

@ -736,6 +736,11 @@ PyVar VM::call(const PyVar& _callable, Args args, const Args& kwargs, bool opCal
if(opCall) return _py_op_call; if(opCall) return _py_op_call;
return _exec(); return _exec();
} }
PyVarOrNull call_f = getattr(_callable, __call__, false, true);
if(call_f != nullptr){
return call(call_f, std::move(args), kwargs, false);
}
TypeError(OBJ_NAME(_t(*callable)).escape(true) + " object is not callable"); TypeError(OBJ_NAME(_t(*callable)).escape(true) + " object is not callable");
return None; return None;
} }
@ -795,9 +800,12 @@ PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err, bool cla
} }
}else{ }else{
// this operation is expensive!!! // this operation is expensive!!!
PyVar* interceptor = cls->attr().try_get(__getattr__); const Str& s = name.str();
if(interceptor != nullptr){ if(s.empty() || s[0] != '_'){
return call(*interceptor, two_args(obj, VAR(name.str()))); PyVar* interceptor = cls->attr().try_get(__getattr__);
if(interceptor != nullptr){
return call(*interceptor, two_args(obj, VAR(s)));
}
} }
} }
cls = cls->attr(__base__).get(); cls = cls->attr(__base__).get();