BLUELOVETH il y a 3 ans
Parent
commit
d9a45ec60d
3 fichiers modifiés avec 53 ajouts et 15 suppressions
  1. 41 12
      src/cffi.h
  2. 1 0
      src/str.h
  3. 11 3
      src/vm.h

+ 41 - 12
src/cffi.h

@@ -269,28 +269,56 @@ struct Pointer{
 };
 
 
-struct Struct {
-    PY_CLASS(Struct, c, struct_)
+struct Value {
+    PY_CLASS(Value, c, value_)
 
     char* data;
     Pointer head;
 
     const TypeInfo* ctype() const { return head.ctype; }
 
-    Struct(const Pointer& head) {
-        data = new char[head.ctype->size];
-        memcpy(data, head.ptr, head.ctype->size);
-        this->head = Pointer(head.ctype, head.level, data);
+    Value(const TypeInfo* type) {
+        data = new char[type->size];
+        memset(data, 0, type->size);
+        this->head = Pointer(type, data);
     }
 
     static void _register(VM* vm, PyVar mod, PyVar type){
         vm->bind_static_method<-1>(type, "__new__", CPP_NOT_IMPLEMENTED());
 
-        vm->bind_method<0>(type, "__repr__", [](VM* vm, Args& args) {
-            Struct& self = CAST(Struct&, args[0]);
-            StrStream ss;
-            ss << self.ctype()->name << "(" << ")";
-            return VAR(ss.str());
+        vm->bind_method<0>(type, "ptr", [](VM* vm, Args& args) {
+            Value& self = CAST(Value&, args[0]);
+            return VAR_T(Pointer, self.head);
+        });
+
+        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){
     PyVar mod = vm->new_module("c");
     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));
 

+ 1 - 0
src/str.h

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

+ 11 - 3
src/vm.h

@@ -736,6 +736,11 @@ PyVar VM::call(const PyVar& _callable, Args args, const Args& kwargs, bool opCal
         if(opCall) return _py_op_call;
         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");
     return None;
 }
@@ -795,9 +800,12 @@ PyVarOrNull VM::getattr(const PyVar& obj, StrName name, bool throw_err, bool cla
             }
         }else{
             // this operation is expensive!!!
-            PyVar* interceptor = cls->attr().try_get(__getattr__);
-            if(interceptor != nullptr){
-                return call(*interceptor, two_args(obj, VAR(name.str())));
+            const Str& s = name.str();
+            if(s.empty() || s[0] != '_'){
+                PyVar* interceptor = cls->attr().try_get(__getattr__);
+                if(interceptor != nullptr){
+                    return call(*interceptor, two_args(obj, VAR(s)));
+                }
             }
         }
         cls = cls->attr(__base__).get();