blueloveTH 2 anni fa
parent
commit
e23571522e
6 ha cambiato i file con 54 aggiunte e 29 eliminazioni
  1. 0 13
      python/builtins.py
  2. 1 1
      src/common.h
  3. 4 4
      src/obj.h
  4. 33 6
      src/pocketpy.h
  5. 11 0
      src/vm.h
  6. 5 5
      tests/40_class.py

+ 0 - 13
python/builtins.py

@@ -11,15 +11,6 @@ def round(x, ndigits=0):
     else:
         return int(x * 10**ndigits - 0.5) / 10**ndigits
 
-def isinstance(obj, cls):
-    assert type(cls) is type
-    obj_t = type(obj)
-    while obj_t is not None:
-        if obj_t is cls:
-            return True
-        obj_t = obj_t.__base__
-    return False
-
 def abs(x):
     return x < 0 ? -x : x
 
@@ -138,10 +129,6 @@ def list::sort(self, reverse=False):
     if reverse:
         self.reverse()
 
-def list::extend(self, other):
-    for i in other:
-        self.append(i)
-
 def list::remove(self, value):
     for i in range(len(self)):
         if self[i] == value:

+ 1 - 1
src/common.h

@@ -30,7 +30,7 @@
 #include <chrono>
 
 #define PK_VERSION				"0.9.5"
-#define PK_EXTRA_CHECK 			1
+#define PK_EXTRA_CHECK 			0
 
 #if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
 #define PK_ENABLE_FILEIO 		0

+ 4 - 4
src/obj.h

@@ -37,7 +37,7 @@ struct Function {
     PyVar _module = nullptr;
     NameDict_ _closure = nullptr;
 
-    bool has_name(const Str& val) const {
+    bool has_name(StrName val) const {
         bool _0 = std::find(args.begin(), args.end(), val) != args.end();
         bool _1 = starred_arg == val;
         bool _2 = kwargs.contains(val);
@@ -109,11 +109,11 @@ struct Py_ : PyObject {
 
     inline void _init() noexcept {
         if constexpr (std::is_same_v<T, Type> || std::is_same_v<T, DummyModule>) {
-            _attr = new NameDict(16, kTypeAttrLoadFactor);
+            _attr = new NameDict(8, kTypeAttrLoadFactor);
         }else if constexpr(std::is_same_v<T, DummyInstance>){
-            _attr = new NameDict(4, kInstAttrLoadFactor);
+            _attr = new NameDict(8, kInstAttrLoadFactor);
         }else if constexpr(std::is_same_v<T, Function> || std::is_same_v<T, NativeFunc>){
-            _attr = new NameDict(4, kInstAttrLoadFactor);
+            _attr = new NameDict(8, kInstAttrLoadFactor);
         }else{
             _attr = nullptr;
         }

+ 33 - 6
src/pocketpy.h

@@ -62,12 +62,20 @@ void init_builtins(VM* _vm) {
         return vm->None;
     });
 
-    _vm->bind_builtin_func<0>("super", [](VM* vm, Args& args) {
-        const PyVar* self = vm->top_frame()->f_locals().try_get(m_self);
-        if(self == nullptr) vm->TypeError("super() can only be called in a class");
-        // base should be CURRENT_CLASS_BASE
-        Type base = vm->_all_types[(*self)->type.index].base;
-        return vm->new_object(vm->tp_super, Super(*self, base));
+    _vm->bind_builtin_func<2>("super", [](VM* vm, Args& args) {
+        vm->check_type(args[0], vm->tp_type);
+        Type type = OBJ_GET(Type, args[0]);
+        if(!vm->isinstance(args[1], type)){
+            vm->TypeError("super(type, obj): obj must be an instance or subtype of type");
+        }
+        Type base = vm->_all_types[type.index].base;
+        return vm->new_object(vm->tp_super, Super(args[1], base));
+    });
+
+    _vm->bind_builtin_func<2>("isinstance", [](VM* vm, Args& args) {
+        vm->check_type(args[1], vm->tp_type);
+        Type type = OBJ_GET(Type, args[1]);
+        return VAR(vm->isinstance(args[0], type));
     });
 
     _vm->bind_builtin_func<1>("id", [](VM* vm, Args& args) {
@@ -76,6 +84,17 @@ void init_builtins(VM* _vm) {
         return VAR(obj.bits);
     });
 
+    _vm->bind_builtin_func<1>("vars", [](VM* vm, Args& args) {
+        const PyVar& obj = args[0];
+        List ret;
+        if(!obj.is_tagged() && obj->is_attr_valid()){
+            for(StrName name: obj->attr().keys()){
+                ret.push_back(VAR(name.str()));
+            }
+        }
+        return VAR(ret);
+    });
+
     _vm->bind_builtin_func<1>("eval", [](VM* vm, Args& args) {
         CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE);
         return vm->_exec(code, vm->top_frame()->_module, vm->top_frame()->_locals);
@@ -406,6 +425,14 @@ void init_builtins(VM* _vm) {
         return vm->None;
     });
 
+    _vm->bind_method<1>("list", "extend", [](VM* vm, Args& args) {
+        List& self = CAST(List&, args[0]);
+        PyVar obj = vm->asList(args[1]);
+        const List& list = CAST(List&, obj);
+        self.insert(self.end(), list.begin(), list.end());
+        return vm->None;
+    });
+
     _vm->bind_method<0>("list", "reverse", [](VM* vm, Args& args) {
         List& self = CAST(List&, args[0]);
         std::reverse(self.begin(), self.end());

+ 11 - 0
src/vm.h

@@ -116,6 +116,17 @@ public:
         return nullptr;
     }
 
+    bool isinstance(const PyVar& obj, Type cls_t){
+        Type obj_t = OBJ_GET(Type, _t(obj));
+        do{
+            if(obj_t == cls_t) return true;
+            Type base = _all_types[obj_t.index].base;
+            if(base.index == -1) break;
+            obj_t = base;
+        }while(true);
+        return false;
+    }
+
     PyVar fast_call(StrName name, Args&& args){
         PyVar* val = find_name_in_mro(_t(args[0]).get(), name);
         if(val != nullptr) return call(*val, std::move(args));

+ 5 - 5
tests/40_class.py

@@ -17,7 +17,7 @@ assert A.__base__ is object
 
 class B(A):
     def __init__(self, a, b, c):
-        super().__init__(a, b)
+        super(B, self).__init__(a, b)
         self.c = c
 
     def add(self):
@@ -34,7 +34,7 @@ assert b.sub() == -4
 
 class C(B):
     def __init__(self, a, b, c, d):
-        super().__init__(a, b, c)
+        super(C, self).__init__(a, b, c)
         self.d = d
 
     def add(self):
@@ -51,14 +51,14 @@ assert c.sub() == -8
 
 class D(C):
     def __init__(self, a, b, c, d, e):
-        super().__init__(a, b, c, d)
+        super(D, self).__init__(a, b, c, d)
         self.e = e
 
     def add(self):
-        return super().add() + self.e
+        return super(D, self).add() + self.e
 
     def sub(self):
-        return super().sub() - self.e
+        return super(D, self).sub() - self.e
     
 assert D.__base__ is C