diff --git a/include/pocketpy/iter.h b/include/pocketpy/iter.h index 34f24498..c6c5c26e 100644 --- a/include/pocketpy/iter.h +++ b/include/pocketpy/iter.h @@ -4,76 +4,98 @@ #include "common.h" #include "frame.h" -namespace pkpy{ +namespace pkpy +{ -struct RangeIter{ - PY_CLASS(RangeIter, builtins, "_range_iterator") - Range r; - i64 current; - RangeIter(Range r) : r(r), current(r.start) {} + struct RangeIter + { + PY_CLASS(RangeIter, builtins, "_range_iterator") + Range r; + i64 current; + RangeIter(Range r) : r(r), current(r.start) {} - static void _register(VM* vm, PyObject* mod, PyObject* type); -}; + static void _register(VM *vm, PyObject *mod, PyObject *type); + }; -struct ArrayIter{ - PY_CLASS(ArrayIter, builtins, "_array_iterator") - PyObject* ref; - PyObject** begin; - PyObject** end; - PyObject** current; + struct ArrayIter + { + PY_CLASS(ArrayIter, builtins, "_array_iterator") + PyObject *ref; + PyObject **begin; + PyObject **end; + PyObject **current; - ArrayIter(PyObject* ref, PyObject** begin, PyObject** end) - : ref(ref), begin(begin), end(end), current(begin) {} + ArrayIter(PyObject *ref, PyObject **begin, PyObject **end) + : ref(ref), begin(begin), end(end), current(begin) {} - void _gc_mark() const{ PK_OBJ_MARK(ref); } - static void _register(VM* vm, PyObject* mod, PyObject* type); -}; + void _gc_mark() const { PK_OBJ_MARK(ref); } + static void _register(VM *vm, PyObject *mod, PyObject *type); + }; -struct PyDequeIter{ - // Iterator for the deque type - PY_CLASS(PyDequeIter, builtins, "_deque_iterator") - PyObject* ref; - std::deque::iterator begin; - std::deque::iterator end; - std::deque::iterator current; + struct PyDequeIter + { + // Iterator for the deque type + PY_CLASS(PyDequeIter, builtins, "_deque_iterator") + PyObject *ref; + bool is_reversed; + std::deque::iterator begin; + std::deque::iterator end; + std::deque::iterator current; + std::deque::reverse_iterator rbegin; + std::deque::reverse_iterator rend; + std::deque::reverse_iterator rcurrent; - PyDequeIter(PyObject* ref, std::deque::iterator begin, std::deque::iterator end) - : ref(ref), begin(begin), end(end), current(begin) {} + PyDequeIter(PyObject *ref, std::deque::iterator begin, std::deque::iterator end) + : ref(ref), begin(begin), end(end), current(begin) + { + this->is_reversed = false; + } + PyDequeIter(PyObject *ref, std::deque::reverse_iterator rbegin, std::deque::reverse_iterator rend) + : ref(ref), rbegin(rbegin), rend(rend), rcurrent(rbegin) + { + this->is_reversed = true; + } - void _gc_mark() const{ PK_OBJ_MARK(ref); } - static void _register(VM* vm, PyObject* mod, PyObject* type); -}; + void _gc_mark() const { PK_OBJ_MARK(ref); } + static void _register(VM *vm, PyObject *mod, PyObject *type); + }; -struct StringIter{ - PY_CLASS(StringIter, builtins, "_string_iterator") - PyObject* ref; - Str* str; - int index; // byte index + struct StringIter + { + PY_CLASS(StringIter, builtins, "_string_iterator") + PyObject *ref; + Str *str; + int index; // byte index - StringIter(PyObject* ref) : ref(ref), str(&PK_OBJ_GET(Str, ref)), index(0) {} + StringIter(PyObject *ref) : ref(ref), str(&PK_OBJ_GET(Str, ref)), index(0) {} - void _gc_mark() const{ PK_OBJ_MARK(ref); } + void _gc_mark() const { PK_OBJ_MARK(ref); } - static void _register(VM* vm, PyObject* mod, PyObject* type); -}; + static void _register(VM *vm, PyObject *mod, PyObject *type); + }; -struct Generator{ - PY_CLASS(Generator, builtins, "generator") - Frame frame; - int state; // 0,1,2 - List s_backup; + struct Generator + { + PY_CLASS(Generator, builtins, "generator") + Frame frame; + int state; // 0,1,2 + List s_backup; - Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) { - for(PyObject* obj: buffer) s_backup.push_back(obj); - } + Generator(Frame &&frame, ArgsView buffer) : frame(std::move(frame)), state(0) + { + for (PyObject *obj : buffer) + s_backup.push_back(obj); + } - void _gc_mark() const{ - frame._gc_mark(); - for(PyObject* obj: s_backup) PK_OBJ_MARK(obj); - } + void _gc_mark() const + { + frame._gc_mark(); + for (PyObject *obj : s_backup) + PK_OBJ_MARK(obj); + } - PyObject* next(VM* vm); - static void _register(VM* vm, PyObject* mod, PyObject* type); -}; + PyObject *next(VM *vm); + static void _register(VM *vm, PyObject *mod, PyObject *type); + }; } // namespace pkpy \ No newline at end of file diff --git a/python/pickle.py b/python/pickle.py index bc23785f..bd0d7372 100644 --- a/python/pickle.py +++ b/python/pickle.py @@ -152,8 +152,13 @@ class _Unpickler: if newargs is not None: newargs = [self.unwrap(i) for i in newargs] inst = new_f(cls, *newargs) + if inst.__init__ is not None: # should be called with args if exists + inst.__init__(*newargs) else: inst = new_f(cls) + if inst.__init__ is not None: + inst.__init__() # no args + self.tag(index, inst) # restore state if state is not None: diff --git a/src/iter.cpp b/src/iter.cpp index 57fa918c..88b5dc6f 100644 --- a/src/iter.cpp +++ b/src/iter.cpp @@ -34,10 +34,18 @@ namespace pkpy{ vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ PyDequeIter& self = _CAST(PyDequeIter&, obj); - if(self.current == self.end) return vm->StopIteration; - PyObject* ret = *self.current; - ++self.current; - return ret; + if(self.is_reversed){ + if(self.rcurrent == self.rend) return vm->StopIteration; + PyObject* ret = *self.rcurrent; + ++self.rcurrent; + return ret; + } + else{ + if(self.current == self.end) return vm->StopIteration; + PyObject* ret = *self.current; + ++self.current; + return ret; + } }); }