#include "pocketpy/pocketpy.h" #include "pocketpy/common/utils.h" #include "pocketpy/objects/object.h" #include "pocketpy/interpreter/vm.h" #include "pocketpy/common/sstream.h" typedef struct array_iterator { py_TValue* p; int length; int index; } array_iterator; py_TValue* pk_arrayview(py_Ref self, int* length) { if(self->type == tp_list) { *length = py_list_len(self); return py_list_data(self); } if(self->type == tp_tuple) { *length = py_tuple_len(self); return PyObject__slots(self->_obj); } return NULL; } int pk_arrayequal(py_TValue* lhs, int lhs_length, py_TValue* rhs, int rhs_length) { if(lhs_length != rhs_length) return false; for(int i = 0; i < lhs_length; i++) { int res = py_equal(lhs + i, rhs + i); if(res == -1) return -1; if(!res) return false; } return true; } bool pk_arrayiter(py_Ref val) { int length; py_TValue* p = pk_arrayview(val, &length); if(!p) return TypeError("expected list or tuple, got %t", val->type); array_iterator* ud = py_newobject(py_retval(), tp_array_iterator, 1, sizeof(array_iterator)); ud->p = p; ud->length = length; ud->index = 0; py_setslot(py_retval(), 0, val); // keep a reference to the object return true; } bool pk_arraycontains(py_Ref self, py_Ref val) { int length; py_TValue* p = pk_arrayview(self, &length); if(!p) return TypeError("expected list or tuple, got %t", self->type); for(int i = 0; i < length; i++) { int res = py_equal(p + i, val); if(res == -1) return false; if(res) { py_newbool(py_retval(), true); return true; } } py_newbool(py_retval(), false); return true; } static bool array_iterator__iter__(int argc, py_Ref argv) { PY_CHECK_ARGC(1); *py_retval() = *argv; return true; } static bool array_iterator__next__(int argc, py_Ref argv) { PY_CHECK_ARGC(1); array_iterator* ud = py_touserdata(argv); if(ud->index < ud->length) { *py_retval() = ud->p[ud->index++]; return true; } return StopIteration(); } py_Type pk_array_iterator__register() { py_Type type = pk_newtype("array_iterator", tp_object, NULL, NULL, false, true); py_bindmagic(type, __iter__, array_iterator__iter__); py_bindmagic(type, __next__, array_iterator__next__); return type; }