added more tests, called __init__ from pickle, added reverse iterator option

This commit is contained in:
S. Mahmudul Hasan 2023-10-18 19:49:12 -04:00
parent 14cd420cfb
commit 77feaad873
3 changed files with 94 additions and 59 deletions

View File

@ -4,76 +4,98 @@
#include "common.h" #include "common.h"
#include "frame.h" #include "frame.h"
namespace pkpy{ namespace pkpy
{
struct RangeIter{ struct RangeIter
PY_CLASS(RangeIter, builtins, "_range_iterator") {
Range r; PY_CLASS(RangeIter, builtins, "_range_iterator")
i64 current; Range r;
RangeIter(Range r) : r(r), current(r.start) {} 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{ struct ArrayIter
PY_CLASS(ArrayIter, builtins, "_array_iterator") {
PyObject* ref; PY_CLASS(ArrayIter, builtins, "_array_iterator")
PyObject** begin; PyObject *ref;
PyObject** end; PyObject **begin;
PyObject** current; PyObject **end;
PyObject **current;
ArrayIter(PyObject* ref, PyObject** begin, PyObject** end) ArrayIter(PyObject *ref, PyObject **begin, PyObject **end)
: ref(ref), begin(begin), end(end), current(begin) {} : ref(ref), begin(begin), end(end), current(begin) {}
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 PyDequeIter{ struct PyDequeIter
// Iterator for the deque type {
PY_CLASS(PyDequeIter, builtins, "_deque_iterator") // Iterator for the deque type
PyObject* ref; PY_CLASS(PyDequeIter, builtins, "_deque_iterator")
std::deque<PyObject*>::iterator begin; PyObject *ref;
std::deque<PyObject*>::iterator end; bool is_reversed;
std::deque<PyObject*>::iterator current; std::deque<PyObject *>::iterator begin;
std::deque<PyObject *>::iterator end;
std::deque<PyObject *>::iterator current;
std::deque<PyObject *>::reverse_iterator rbegin;
std::deque<PyObject *>::reverse_iterator rend;
std::deque<PyObject *>::reverse_iterator rcurrent;
PyDequeIter(PyObject* ref, std::deque<PyObject*>::iterator begin, std::deque<PyObject*>::iterator end) PyDequeIter(PyObject *ref, std::deque<PyObject *>::iterator begin, std::deque<PyObject *>::iterator end)
: ref(ref), begin(begin), end(end), current(begin) {} : ref(ref), begin(begin), end(end), current(begin)
{
this->is_reversed = false;
}
PyDequeIter(PyObject *ref, std::deque<PyObject *>::reverse_iterator rbegin, std::deque<PyObject *>::reverse_iterator rend)
: ref(ref), rbegin(rbegin), rend(rend), rcurrent(rbegin)
{
this->is_reversed = true;
}
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 StringIter{ struct StringIter
PY_CLASS(StringIter, builtins, "_string_iterator") {
PyObject* ref; PY_CLASS(StringIter, builtins, "_string_iterator")
Str* str; PyObject *ref;
int index; // byte index 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{ struct Generator
PY_CLASS(Generator, builtins, "generator") {
Frame frame; PY_CLASS(Generator, builtins, "generator")
int state; // 0,1,2 Frame frame;
List s_backup; int state; // 0,1,2
List s_backup;
Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) { Generator(Frame &&frame, ArgsView buffer) : frame(std::move(frame)), state(0)
for(PyObject* obj: buffer) s_backup.push_back(obj); {
} for (PyObject *obj : buffer)
s_backup.push_back(obj);
}
void _gc_mark() const{ void _gc_mark() const
frame._gc_mark(); {
for(PyObject* obj: s_backup) PK_OBJ_MARK(obj); frame._gc_mark();
} for (PyObject *obj : s_backup)
PK_OBJ_MARK(obj);
}
PyObject* next(VM* vm); PyObject *next(VM *vm);
static void _register(VM* vm, PyObject* mod, PyObject* type); static void _register(VM *vm, PyObject *mod, PyObject *type);
}; };
} // namespace pkpy } // namespace pkpy

View File

@ -152,8 +152,13 @@ class _Unpickler:
if newargs is not None: if newargs is not None:
newargs = [self.unwrap(i) for i in newargs] newargs = [self.unwrap(i) for i in newargs]
inst = new_f(cls, *newargs) inst = new_f(cls, *newargs)
if inst.__init__ is not None: # should be called with args if exists
inst.__init__(*newargs)
else: else:
inst = new_f(cls) inst = new_f(cls)
if inst.__init__ is not None:
inst.__init__() # no args
self.tag(index, inst) self.tag(index, inst)
# restore state # restore state
if state is not None: if state is not None:

View File

@ -34,10 +34,18 @@ namespace pkpy{
vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); 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){ vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
PyDequeIter& self = _CAST(PyDequeIter&, obj); PyDequeIter& self = _CAST(PyDequeIter&, obj);
if(self.current == self.end) return vm->StopIteration; if(self.is_reversed){
PyObject* ret = *self.current; if(self.rcurrent == self.rend) return vm->StopIteration;
++self.current; PyObject* ret = *self.rcurrent;
return ret; ++self.rcurrent;
return ret;
}
else{
if(self.current == self.end) return vm->StopIteration;
PyObject* ret = *self.current;
++self.current;
return ret;
}
}); });
} }