mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
...
This commit is contained in:
parent
fa5df75248
commit
40d6f1a19f
@ -108,6 +108,8 @@ py_Type pk_str_iterator__register();
|
||||
py_Type pk_bytes__register();
|
||||
py_Type pk_list__register();
|
||||
py_Type pk_tuple__register();
|
||||
py_Type pk_array_iterator__register();
|
||||
py_Type pk_slice__register();
|
||||
py_Type pk_function__register();
|
||||
py_Type pk_nativefunc__register();
|
||||
py_Type pk_range__register();
|
||||
|
@ -88,7 +88,7 @@ bool py_ismagicname(py_Name);
|
||||
// opaque types
|
||||
void py_newdict(py_Ref);
|
||||
void py_newset(py_Ref);
|
||||
void py_newslice(py_Ref, const py_Ref start, const py_Ref stop, const py_Ref step);
|
||||
void py_newslice(py_Ref);
|
||||
// old style argc-based function
|
||||
void py_newnativefunc(py_Ref out, py_CFunction);
|
||||
|
||||
@ -400,6 +400,7 @@ enum py_PredefinedTypes {
|
||||
tp_str_iterator,
|
||||
tp_list, // c11_vector
|
||||
tp_tuple, // N slots
|
||||
tp_array_iterator,
|
||||
tp_slice, // 3 slots (start, stop, step)
|
||||
tp_range,
|
||||
tp_range_iterator,
|
||||
|
@ -531,7 +531,10 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
case OP_BUILD_SLICE: {
|
||||
// [start, stop, step]
|
||||
py_TValue tmp;
|
||||
py_newslice(&tmp, THIRD(), SECOND(), TOP());
|
||||
py_newslice(&tmp);
|
||||
py_setslot(&tmp, 0, THIRD());
|
||||
py_setslot(&tmp, 1, SECOND());
|
||||
py_setslot(&tmp, 2, TOP());
|
||||
STACK_SHRINK(3);
|
||||
PUSH(&tmp);
|
||||
DISPATCH();
|
||||
|
@ -100,8 +100,9 @@ void pk_VM__ctor(pk_VM* self) {
|
||||
|
||||
validate(tp_list, pk_list__register());
|
||||
validate(tp_tuple, pk_tuple__register());
|
||||
validate(tp_array_iterator, pk_array_iterator__register());
|
||||
|
||||
validate(tp_slice, pk_VM__new_type(self, "slice", tp_object, NULL, false));
|
||||
validate(tp_slice, pk_slice__register());
|
||||
validate(tp_range, pk_range__register());
|
||||
validate(tp_range_iterator, pk_range_iterator__register());
|
||||
validate(tp_module, pk_VM__new_type(self, "module", tp_object, NULL, false));
|
||||
|
75
src/public/py_array.c
Normal file
75
src/public/py_array.c
Normal file
@ -0,0 +1,75 @@
|
||||
#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_arrayeq(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_eq(lhs + i, rhs + i);
|
||||
if(res == -1) return -1;
|
||||
if(!res) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_array_iterator__new__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
int length;
|
||||
py_TValue* p = pk_arrayview(py_arg(1), &length);
|
||||
if(!p) return TypeError("expected list or tuple, got %t", py_arg(1)->type);
|
||||
array_iterator* ud = py_newobject(py_retval(), tp_array_iterator, 1, sizeof(array_iterator));
|
||||
ud->p = p;
|
||||
ud->length = length;
|
||||
ud->index = 0;
|
||||
// keep a reference to the object
|
||||
py_setslot(py_retval(), 0, py_arg(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_array_iterator__iter__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
*py_retval() = *argv;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_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() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "array_iterator", tp_object, NULL, false);
|
||||
|
||||
py_bindmagic(type, __new__, _py_array_iterator__new__);
|
||||
py_bindmagic(type, __iter__, _py_array_iterator__iter__);
|
||||
py_bindmagic(type, __next__, _py_array_iterator__next__);
|
||||
|
||||
return type;
|
||||
}
|
@ -386,6 +386,11 @@ static bool _py_list__sort(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_list__iter__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
return py_tpcall(tp_array_iterator, 1, argv);
|
||||
}
|
||||
|
||||
py_Type pk_list__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
||||
@ -403,6 +408,7 @@ py_Type pk_list__register() {
|
||||
py_bindmagic(type, __mul__, _py_list__mul__);
|
||||
py_bindmagic(type, __rmul__, _py_list__rmul__);
|
||||
py_bindmagic(type, __repr__, _py_list__repr__);
|
||||
py_bindmagic(type, __iter__, _py_list__iter__);
|
||||
|
||||
py_bindmethod(type, "append", _py_list__append);
|
||||
py_bindmethod(type, "extend", _py_list__extend);
|
||||
|
@ -35,9 +35,9 @@ static bool _py_range__new__(int argc, py_Ref argv) {
|
||||
ud->stop = py_toint(py_arg(2));
|
||||
ud->step = py_toint(py_arg(3));
|
||||
break;
|
||||
default: return TypeError("range() expected at most 3 arguments, got %d", argc - 1);
|
||||
default: return TypeError("range() expected at most 4 arguments, got %d", argc);
|
||||
}
|
||||
if(ud->step == 0) return ValueError("range() arg 3 must not be zero");
|
||||
if(ud->step == 0) return ValueError("range() step must not be zero");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
55
src/public/py_slice.c
Normal file
55
src/public/py_slice.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
|
||||
|
||||
void py_newslice(py_Ref out){
|
||||
pk_VM* vm = pk_current_vm;
|
||||
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_slice, 3, 0);
|
||||
out->type = tp_slice;
|
||||
out->is_ptr = true;
|
||||
out->_obj = obj;
|
||||
}
|
||||
|
||||
static bool _py_slice__new__(int argc, py_Ref argv){
|
||||
PY_CHECK_ARGC(1+3);
|
||||
py_Ref slice = py_retval();
|
||||
py_newslice(slice);
|
||||
py_setslot(slice, 0, py_arg(1));
|
||||
py_setslot(slice, 1, py_arg(2));
|
||||
py_setslot(slice, 2, py_arg(3));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_slice__repr__(int argc, py_Ref argv){
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
c11_sbuf__write_cstr(&buf, "slice(");
|
||||
for(int i = 0; i < 3; i++) {
|
||||
py_TValue* val = py_getslot(argv, i);
|
||||
bool ok = py_repr(val);
|
||||
if(!ok) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return false;
|
||||
}
|
||||
c11_sbuf__write_sv(&buf, py_tosv(py_retval()));
|
||||
if(i != 2) c11_sbuf__write_cstr(&buf, ", ");
|
||||
}
|
||||
c11_sbuf__write_char(&buf, ')');
|
||||
c11_string* res = c11_sbuf__submit(&buf);
|
||||
py_newstrn(py_retval(), res->data, res->size);
|
||||
c11_string__delete(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_slice__register(){
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "slice", tp_object, NULL, false);
|
||||
|
||||
py_bindmagic(type, __new__, _py_slice__new__);
|
||||
py_bindmagic(type, __repr__, _py_slice__repr__);
|
||||
return type;
|
||||
}
|
@ -44,6 +44,12 @@ const char* py_tostrn(const py_Ref self, int* size) {
|
||||
return ud->data;
|
||||
}
|
||||
|
||||
c11_sv py_tosv(const py_Ref self) {
|
||||
assert(self->type == tp_str);
|
||||
c11_string* ud = PyObject__userdata(self->_obj);
|
||||
return c11_string__sv(ud);
|
||||
}
|
||||
|
||||
unsigned char* py_tobytes(const py_Ref self, int* size) {
|
||||
assert(self->type == tp_bytes);
|
||||
c11_bytes* ud = PyObject__userdata(self->_obj);
|
||||
|
@ -120,6 +120,11 @@ static bool _py_tuple__ne__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _py_tuple__iter__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
return py_tpcall(tp_array_iterator, 1, argv);
|
||||
}
|
||||
|
||||
py_Type pk_tuple__register() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
py_Type type = pk_VM__new_type(vm, "tuple", tp_object, NULL, false);
|
||||
@ -130,5 +135,6 @@ py_Type pk_tuple__register() {
|
||||
py_bindmagic(type, __getitem__, _py_tuple__getitem__);
|
||||
py_bindmagic(type, __eq__, _py_tuple__eq__);
|
||||
py_bindmagic(type, __ne__, _py_tuple__ne__);
|
||||
py_bindmagic(type, __iter__, _py_tuple__iter__);
|
||||
return type;
|
||||
}
|
||||
|
@ -88,13 +88,6 @@ void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
|
||||
py_setdict(obj, name, &tmp);
|
||||
}
|
||||
|
||||
void py_newslice(py_Ref out, const py_Ref start, const py_Ref stop, const py_Ref step) {
|
||||
py_newobject(out, tp_slice, 3, 0);
|
||||
py_setslot(out, 0, start);
|
||||
py_setslot(out, 1, stop);
|
||||
py_setslot(out, 2, step);
|
||||
}
|
||||
|
||||
void* py_newobject(py_Ref out, py_Type type, int slots, int udsize) {
|
||||
pk_ManagedHeap* heap = &pk_current_vm->heap;
|
||||
PyObject* obj = pk_ManagedHeap__gcnew(heap, type, slots, udsize);
|
||||
|
@ -35,28 +35,6 @@ const char* pk_opname(Opcode op) {
|
||||
return OP_NAMES[op];
|
||||
}
|
||||
|
||||
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_arrayeq(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_eq(lhs + i, rhs + i);
|
||||
if(res == -1) return -1;
|
||||
if(!res) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void disassemble(CodeObject* co) {
|
||||
c11_vector /*T=int*/ jumpTargets;
|
||||
c11_vector__ctor(&jumpTargets, sizeof(int));
|
||||
|
Loading…
x
Reference in New Issue
Block a user