From 391d26cdc55de5e1e787205a7142565a80b06f8f Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 30 Jun 2024 15:26:39 +0800 Subject: [PATCH] some fix --- include/pocketpy/pocketpy.h | 28 +++++++---- src/interpreter/ceval.c | 96 +++++++++++++++++++++---------------- src/public/py_dict.c | 13 +++++ src/public/py_list.c | 59 +++++++++++++++++++++++ src/public/py_ops.c | 6 +++ src/public/values.c | 17 +++++++ src/public/vm.c | 3 +- 7 files changed, 171 insertions(+), 51 deletions(-) create mode 100644 src/public/py_dict.c create mode 100644 src/public/py_list.c diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 1030db71..95ddbf10 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -45,13 +45,25 @@ void py_newfloat(py_Ref, double); void py_newbool(py_Ref, bool); void py_newstr(py_Ref, const char*); void py_newstrn(py_Ref, const char*, int); +void py_newStr_(py_Ref, py_Str); // void py_newfstr(py_Ref, const char*, ...); void py_newbytes(py_Ref, const unsigned char*, int); void py_newnone(py_Ref); void py_newnull(py_Ref); -void py_newtuple(py_Ref, int count); +/// Create a tuple with n UNINITIALIZED elements. +/// You should initialize all elements before using it. +void py_newtuple(py_Ref, int n); +/// Create a list. void py_newlist(py_Ref); +/// Create a list with n UNINITIALIZED elements. +/// You should initialize all elements before using it. +void py_newlistn(py_Ref, int n); + +// 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); // new style decl-based function void py_newfunction(py_Ref out, py_CFunction, const char* sig); @@ -99,6 +111,7 @@ bool py_istype(const py_Ref, py_Type); /************* References *************/ #define py_arg(i) (py_Ref)((char*)argv+((i)<<4)) + py_Ref py_reg(int i); py_Ref py_getdict(const py_Ref self, py_Name name); @@ -119,6 +132,10 @@ bool py_setattr(py_Ref self, py_Name name, const py_Ref val); /// Deletes the attribute of the object. bool py_delattr(py_Ref self, py_Name name); +bool py_getitem(const py_Ref self, const py_Ref key, py_Ref out); +bool py_setitem(py_Ref self, const py_Ref key, const py_Ref val); +bool py_delitem(py_Ref self, const py_Ref key); + /// Equivalent to `*dst = *src`. void py_assign(py_Ref dst, const py_Ref src); @@ -193,18 +210,9 @@ void py_list__setitem(py_Ref self, int i, const py_Ref val); void py_list__delitem(py_Ref self, int i); int py_list__len(const py_Ref self); void py_list__append(py_Ref self, const py_Ref val); -void py_list__extend(py_Ref self, const py_Ref begin, const py_Ref end); void py_list__clear(py_Ref self); void py_list__insert(py_Ref self, int i, const py_Ref val); -// unchecked functions, if self is not a dict, the behavior is undefined -int py_dict__len(const py_Ref self); -bool py_dict__contains(const py_Ref self, const py_Ref key); -py_Ref py_dict__getitem(const py_Ref self, const py_Ref key); -void py_dict__setitem(py_Ref self, const py_Ref key, const py_Ref val); -void py_dict__delitem(py_Ref self, const py_Ref key); -void py_dict__clear(py_Ref self); - // internal functions typedef struct pk_TypeInfo pk_TypeInfo; pk_TypeInfo* pk_tpinfo(const py_Ref self); diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 53385d62..2dbfe86f 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -419,46 +419,62 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) { PUSH(&tmp); DISPATCH(); } - // case OP_BUILD_LIST: { - // PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); - // STACK_SHRINK(byte.arg); - // PUSH(_0); - // DISPATCH(); - // } - // case OP_BUILD_DICT: { - // if(byte.arg == 0) { - // PUSH(VAR(Dict())); - // DISPATCH() - // } - // PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); - // _0 = call(_t(tp_dict), _0); - // STACK_SHRINK(byte.arg); - // PUSH(_0); - // DISPATCH(); - // } - // case OP_BUILD_SET: { - // PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); - // _0 = call(builtins->attr()[pk_id_set], _0); - // STACK_SHRINK(byte.arg); - // PUSH(_0); - // DISPATCH(); - // } - // case OP_BUILD_SLICE: { - // PyVar _2 = POPX(); // step - // PyVar _1 = POPX(); // stop - // PyVar _0 = POPX(); // start - // PUSH(VAR(Slice(_0, _1, _2))); - // DISPATCH(); - // } - // case OP_BUILD_STRING: { - // SStream ss; - // ArgsView view = STACK_VIEW(byte.arg); - // for(PyVar obj: view) - // ss << py_str(obj); - // STACK_SHRINK(byte.arg); - // PUSH(VAR(ss.str())); - // DISPATCH(); - // } + case OP_BUILD_LIST: { + py_TValue tmp; + py_newlistn(&tmp, byte.arg); + py_TValue* begin = SP() - byte.arg; + for(int i = 0; i < byte.arg; i++) { + py_list__setitem(&tmp, i, begin + i); + } + SP() = begin; + PUSH(&tmp); + DISPATCH(); + } + case OP_BUILD_DICT: { + py_TValue* begin = SP() - byte.arg; + py_Ref tmp = py_pushtmp(); + py_newdict(tmp); + for(int i = 0; i < byte.arg; i += 2) { + if(!py_setitem(tmp, begin + i, begin + i + 1)) goto __ERROR; + } + SP() = begin; + PUSH(tmp); + DISPATCH(); + } + case OP_BUILD_SET: { + py_TValue* begin = SP() - byte.arg; + py_Ref tmp = py_pushtmp(); + py_newset(tmp); + for(int i = 0; i < byte.arg; i++) { + if(!py_callmethod(tmp, pk_id_add, 1, begin + i)) goto __ERROR; + } + SP() = begin; + PUSH(tmp); + DISPATCH(); + } + case OP_BUILD_SLICE: { + // [start, stop, step] + py_TValue tmp; + py_newslice(&tmp, THIRD(), SECOND(), TOP()); + STACK_SHRINK(3); + PUSH(&tmp); + DISPATCH(); + } + case OP_BUILD_STRING: { + py_TValue* begin = SP() - byte.arg; + py_Ref tmp = py_pushtmp(); + pk_SStream ss; + pk_SStream__ctor(&ss); + for(int i = 0; i < byte.arg; i++) { + if(!py_str(begin + i, tmp)) goto __ERROR; + py_Str* item = py_touserdata(tmp); + pk_SStream__write_Str(&ss, item); + } + SP() = begin; + py_newStr_(tmp, pk_SStream__submit(&ss)); + PUSH(tmp); + DISPATCH(); + } /**************************** */ case OP_RETURN_VALUE: { self->last_retval = byte.arg == BC_NOARG ? POPX() : self->None; diff --git a/src/public/py_dict.c b/src/public/py_dict.c new file mode 100644 index 00000000..b4e2c5f3 --- /dev/null +++ b/src/public/py_dict.c @@ -0,0 +1,13 @@ +#include "pocketpy/pocketpy.h" + +#include "pocketpy/common/utils.h" +#include "pocketpy/objects/object.h" +#include "pocketpy/interpreter/vm.h" + +void py_newdict(py_Ref out){ + +} + +void py_newset(py_Ref out){ + +} \ No newline at end of file diff --git a/src/public/py_list.c b/src/public/py_list.c new file mode 100644 index 00000000..621e94b4 --- /dev/null +++ b/src/public/py_list.c @@ -0,0 +1,59 @@ +#include "pocketpy/pocketpy.h" + +#include "pocketpy/common/utils.h" +#include "pocketpy/objects/object.h" +#include "pocketpy/interpreter/vm.h" + +typedef c11_vector List; + +void py_newlist(py_Ref out){ + pk_VM* vm = pk_current_vm; + PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_list, 0, sizeof(List)); + List* userdata = PyObject__value(obj); + c11_vector__ctor(userdata, sizeof(py_TValue)); + out->type = tp_list; + out->is_ptr = true; + out->_obj = obj; +} + +void py_newlistn(py_Ref out, int n) { + py_newlist(out); + List* userdata = py_touserdata(out); + c11_vector__reserve(userdata, n); + userdata->count = n; +} + +py_Ref py_list__getitem(const py_Ref self, int i){ + List* userdata = py_touserdata(self); + return c11__at(py_TValue, userdata, i); +} + +void py_list__setitem(py_Ref self, int i, const py_Ref val){ + List* userdata = py_touserdata(self); + c11__setitem(py_TValue, userdata, i, *val); +} + +void py_list__delitem(py_Ref self, int i){ + List* userdata = py_touserdata(self); + c11_vector__erase(py_TValue, userdata, i); +} + +int py_list__len(const py_Ref self){ + List* userdata = py_touserdata(self); + return userdata->count; +} + +void py_list__append(py_Ref self, const py_Ref val){ + List* userdata = py_touserdata(self); + c11_vector__push(py_TValue, userdata, *val); +} + +void py_list__clear(py_Ref self){ + List* userdata = py_touserdata(self); + c11_vector__clear(userdata); +} + +void py_list__insert(py_Ref self, int i, const py_Ref val){ + List* userdata = py_touserdata(self); + c11_vector__insert(py_TValue, userdata, i, *val); +} \ No newline at end of file diff --git a/src/public/py_ops.c b/src/public/py_ops.c index b20c4749..a6062318 100644 --- a/src/public/py_ops.c +++ b/src/public/py_ops.c @@ -25,3 +25,9 @@ bool py_getattr(const py_Ref self, py_Name name, py_Ref out) { return true; } bool py_setattr(py_Ref self, py_Name name, const py_Ref val) { return -1; } bool py_delattr(py_Ref self, py_Name name) { return -1; } + +bool py_getitem(const py_Ref self, const py_Ref key, py_Ref out) { return -1; } + +bool py_setitem(py_Ref self, const py_Ref key, const py_Ref val) { return -1; } + +bool py_delitem(py_Ref self, const py_Ref key) { return -1; } \ No newline at end of file diff --git a/src/public/values.c b/src/public/values.c index 972851a1..9205f4bc 100644 --- a/src/public/values.c +++ b/src/public/values.c @@ -39,6 +39,16 @@ void py_newstrn(py_Ref out, const char* data, int size) { out->_obj = obj; } +void py_newStr_(py_Ref out, py_Str input){ + pk_ManagedHeap* heap = &pk_current_vm->heap; + PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str)); + py_Str* userdata = PyObject__value(obj); + *userdata = input; + out->type = tp_str; + out->is_ptr = true; + out->_obj = obj; +} + void py_newbytes(py_Ref out, const unsigned char* data, int size) { pk_ManagedHeap* heap = &pk_current_vm->heap; // 4 bytes size + data @@ -85,6 +95,13 @@ void py_newnotimplemented(py_Ref out) { *out = vm->NotImplemented; } +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); diff --git a/src/public/vm.c b/src/public/vm.c index 3854f5a2..4b36afe5 100644 --- a/src/public/vm.c +++ b/src/public/vm.c @@ -70,4 +70,5 @@ bool py_getunboundmethod(const py_Ref self, py_Name name, bool fallback, py_Ref pk_TypeInfo* pk_tpinfo(const py_Ref self){ pk_VM* vm = pk_current_vm; return c11__at(pk_TypeInfo, &vm->types, self->type); -} \ No newline at end of file +} +