From fd938a7c29ed20d8b6753be6907f731a735ad84c Mon Sep 17 00:00:00 2001 From: "S. Mahmudul Hasan" Date: Sat, 14 Oct 2023 18:01:59 -0400 Subject: [PATCH] WIP: added deque iterator --- include/pocketpy/collections.h | 1 - include/pocketpy/common.h | 1 + include/pocketpy/iter.h | 15 +++++++++++++++ src/collections.cpp | 35 ++++++++++++++++++++++------------ src/iter.cpp | 15 +++++++++++++++ src/pocketpy.cpp | 1 + 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/include/pocketpy/collections.h b/include/pocketpy/collections.h index 7132e050..7920a899 100644 --- a/include/pocketpy/collections.h +++ b/include/pocketpy/collections.h @@ -6,7 +6,6 @@ #include "str.h" #include "iter.h" #include "cffi.h" -#include namespace pkpy { diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index 08fb1980..929f9c5e 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -21,6 +21,7 @@ #include #include #include +#include #define PK_VERSION "1.2.4" diff --git a/include/pocketpy/iter.h b/include/pocketpy/iter.h index 262b40ec..34f24498 100644 --- a/include/pocketpy/iter.h +++ b/include/pocketpy/iter.h @@ -29,6 +29,21 @@ struct ArrayIter{ 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; + + PyDequeIter(PyObject* ref, std::deque::iterator begin, std::deque::iterator 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); +}; + struct StringIter{ PY_CLASS(StringIter, builtins, "_string_iterator") PyObject* ref; diff --git a/src/collections.cpp b/src/collections.cpp index 65282943..0062ad54 100644 --- a/src/collections.cpp +++ b/src/collections.cpp @@ -20,6 +20,21 @@ namespace pkpy return VAR(self.dequeItems.size()); }); + vm->bind(type, "__repr__(self) -> str", + [](VM *vm, ArgsView args) + { + PyDeque &self = _CAST(PyDeque &, args[0]); + std::stringstream ss = self.getRepr(vm); + return VAR(ss.str()); + }); + + vm->bind(type, "__iter__(self) -> deque_iterator", + [](VM *vm, ArgsView args) + { + PyDeque &self = _CAST(PyDeque &, args[0]); + return vm->heap.gcnew(PyDequeIter::_type(vm), args[0], self.dequeItems.begin(), self.dequeItems.end()); + }); + vm->bind(type, "append(self, item) -> None", [](VM *vm, ArgsView args) { @@ -127,14 +142,6 @@ namespace pkpy return vm->None; }); - vm->bind(type, "__repr__(self) -> str", - [](VM *vm, ArgsView args) - { - PyDeque &self = _CAST(PyDeque &, args[0]); - std::stringstream ss = self.getRepr(vm); - return VAR(ss.str()); - }); - vm->bind(type, "pop(self) -> PyObject", [](VM *vm, ArgsView args) { @@ -197,17 +204,21 @@ namespace pkpy }); } - PyDeque::PyDeque(VM *vm, PyObject* iterable, PyObject* maxlen) + PyDeque::PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen) { - if(maxlen!=vm->None){ + if (maxlen != vm->None) + { this->maxlen = CAST(int, maxlen); this->bounded = true; - }else{ + } + else + { this->bounded = false; this->maxlen = -1; } - if(iterable!=vm->None){ + if (iterable != vm->None) + { auto _lock = vm->heap.gc_scope_lock(); PyObject *it = vm->py_iter(iterable); // strong ref PyObject *obj = vm->py_next(it); diff --git a/src/iter.cpp b/src/iter.cpp index eabc4790..57fa918c 100644 --- a/src/iter.cpp +++ b/src/iter.cpp @@ -26,6 +26,21 @@ namespace pkpy{ }); } + void PyDequeIter::_register(VM* vm, PyObject* mod, PyObject* type){ + // Iterator for the deque type + vm->_all_types[PK_OBJ_GET(Type, type)].subclass_enabled = false; + vm->bind_notimplemented_constructor(type); + + 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; + }); + } + void StringIter::_register(VM* vm, PyObject* mod, PyObject* type){ vm->_all_types[PK_OBJ_GET(Type, type)].subclass_enabled = false; vm->bind_notimplemented_constructor(type); diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 086e5772..5a265906 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1414,6 +1414,7 @@ void init_builtins(VM* _vm) { RangeIter::register_class(_vm, _vm->builtins); ArrayIter::register_class(_vm, _vm->builtins); + PyDequeIter::register_class(_vm, _vm->builtins); StringIter::register_class(_vm, _vm->builtins); Generator::register_class(_vm, _vm->builtins); }