diff --git a/python/builtins.py b/python/builtins.py index 91e82eea..ce0bce9a 100644 --- a/python/builtins.py +++ b/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: diff --git a/src/common.h b/src/common.h index 06ad1327..01a3609e 100644 --- a/src/common.h +++ b/src/common.h @@ -30,7 +30,7 @@ #include #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 diff --git a/src/obj.h b/src/obj.h index 8e99ef9f..fb2a0e12 100644 --- a/src/obj.h +++ b/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 || std::is_same_v) { - _attr = new NameDict(16, kTypeAttrLoadFactor); + _attr = new NameDict(8, kTypeAttrLoadFactor); }else if constexpr(std::is_same_v){ - _attr = new NameDict(4, kInstAttrLoadFactor); + _attr = new NameDict(8, kInstAttrLoadFactor); }else if constexpr(std::is_same_v || std::is_same_v){ - _attr = new NameDict(4, kInstAttrLoadFactor); + _attr = new NameDict(8, kInstAttrLoadFactor); }else{ _attr = nullptr; } diff --git a/src/pocketpy.h b/src/pocketpy.h index 21b2d7f0..d5938f52 100644 --- a/src/pocketpy.h +++ b/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_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()); diff --git a/src/vm.h b/src/vm.h index d86aaf2c..22523e45 100644 --- a/src/vm.h +++ b/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)); diff --git a/tests/40_class.py b/tests/40_class.py index 751cc42d..5fb7176d 100644 --- a/tests/40_class.py +++ b/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