blueloveTH 1 an în urmă
părinte
comite
391d26cdc5

+ 18 - 10
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);

+ 56 - 40
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;

+ 13 - 0
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){
+    
+}

+ 59 - 0
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);
+}

+ 6 - 0
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; }

+ 17 - 0
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);

+ 2 - 1
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);
-}
+}
+