mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
86 lines
2.4 KiB
C
86 lines
2.4 KiB
C
#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;
|
|
}
|