mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
96 lines
2.7 KiB
C
96 lines
2.7 KiB
C
#include "pocketpy/pocketpy.h"
|
|
#include "pocketpy/objects/object.h"
|
|
#include "pocketpy/objects/iterator.h"
|
|
#include "pocketpy/interpreter/vm.h"
|
|
|
|
int pk_arrayview(py_Ref self, py_TValue** p) {
|
|
if(self->type == tp_list) {
|
|
*p = py_list_data(self);
|
|
return py_list_len(self);
|
|
}
|
|
if(self->type == tp_tuple) {
|
|
*p = PyObject__slots(self->_obj);
|
|
return py_tuple_len(self);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool pk_wrapper__arrayequal(py_Type type, int argc, py_Ref argv) {
|
|
PY_CHECK_ARGC(2);
|
|
if(!py_istype(py_arg(1), type)) {
|
|
py_newnotimplemented(py_retval());
|
|
return true;
|
|
}
|
|
py_TValue *p0, *p1;
|
|
int lhs_length = pk_arrayview(py_arg(0), &p0);
|
|
int rhs_length = pk_arrayview(py_arg(1), &p1);
|
|
assert(lhs_length != -1 && rhs_length != -1);
|
|
if(lhs_length != rhs_length) {
|
|
py_newbool(py_retval(), false);
|
|
return true;
|
|
}
|
|
for(int i = 0; i < lhs_length; i++) {
|
|
int res = py_equal(p0 + i, p1 + i);
|
|
if(res == -1) return false;
|
|
if(!res) {
|
|
py_newbool(py_retval(), false);
|
|
return true;
|
|
}
|
|
}
|
|
py_newbool(py_retval(), true);
|
|
return true;
|
|
}
|
|
|
|
bool pk_arraycontains(py_Ref self, py_Ref val) {
|
|
py_TValue* p;
|
|
int length = pk_arrayview(self, &p);
|
|
if(length == -1) 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;
|
|
}
|
|
|
|
bool list_iterator__next__(int argc, py_Ref argv) {
|
|
PY_CHECK_ARGC(1);
|
|
list_iterator* ud = py_touserdata(argv);
|
|
if(ud->index < ud->vec->length) {
|
|
py_TValue* res = c11__at(py_TValue, ud->vec, ud->index);
|
|
py_assign(py_retval(), res);
|
|
ud->index++;
|
|
return true;
|
|
}
|
|
return StopIteration();
|
|
}
|
|
|
|
bool tuple_iterator__next__(int argc, py_Ref argv) {
|
|
PY_CHECK_ARGC(1);
|
|
tuple_iterator* ud = py_touserdata(argv);
|
|
if(ud->index < ud->length) {
|
|
py_assign(py_retval(), ud->p + ud->index);
|
|
ud->index++;
|
|
return true;
|
|
}
|
|
return StopIteration();
|
|
}
|
|
|
|
py_Type pk_list_iterator__register() {
|
|
py_Type type = pk_newtype("list_iterator", tp_object, NULL, NULL, false, true);
|
|
py_bindmagic(type, __iter__, pk_wrapper__self);
|
|
py_bindmagic(type, __next__, list_iterator__next__);
|
|
return type;
|
|
}
|
|
|
|
py_Type pk_tuple_iterator__register() {
|
|
py_Type type = pk_newtype("tuple_iterator", tp_object, NULL, NULL, false, true);
|
|
py_bindmagic(type, __iter__, pk_wrapper__self);
|
|
py_bindmagic(type, __next__, tuple_iterator__next__);
|
|
return type;
|
|
}
|