blueloveTH vor 1 Jahr
Ursprung
Commit
f28335f1f7
5 geänderte Dateien mit 43 neuen und 17 gelöschten Zeilen
  1. 17 6
      src/interpreter/ceval.c
  2. 12 3
      src/interpreter/vm.c
  3. 1 0
      src/public/py_dict.c
  4. 4 1
      src/public/py_ops.c
  5. 9 7
      tests/47_set.py

+ 17 - 6
src/interpreter/ceval.c

@@ -54,7 +54,7 @@ static bool format_object(py_Ref obj, c11_sv spec);
 
 #define vectorcall_opcall(argc, kwargc)                                                            \
     do {                                                                                           \
-        FrameResult res = VM__vectorcall(self, (argc), (kwargc), true);                      \
+        FrameResult res = VM__vectorcall(self, (argc), (kwargc), true);                            \
         switch(res) {                                                                              \
             case RES_RETURN: PUSH(&self->last_retval); break;                                      \
             case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME;                             \
@@ -271,12 +271,12 @@ FrameResult VM__run_top_frame(VM* self) {
                     if(magic->type == tp_nativefunc) {
                         if(!magic->_cfunc(2, SECOND())) goto __ERROR;
                         POP();
-                        *TOP() = self->last_retval;
                     } else {
                         INSERT_THIRD();     // [?, a, b]
                         *THIRD() = *magic;  // [__getitem__, a, b]
                         if(!py_vectorcall(1, 0)) goto __ERROR;
                     }
+                    *TOP() = self->last_retval;
                     DISPATCH();
                 }
                 TypeError("'%t' object is not subscriptable", SECOND()->type);
@@ -423,6 +423,7 @@ FrameResult VM__run_top_frame(VM* self) {
                 py_newint(SP()++, 0);  // [complex, NULL, 0]
                 *SP()++ = tmp;         // [complex, NULL, 0, x]
                 if(!py_vectorcall(2, 0)) goto __ERROR;
+                PUSH(py_retval());
                 DISPATCH();
             }
             case OP_BUILD_BYTES: {
@@ -477,7 +478,9 @@ FrameResult VM__run_top_frame(VM* self) {
                 py_Name id_add = py_name("add");
                 for(int i = 0; i < byte.arg; i++) {
                     py_push(TOP());
-                    py_pushmethod(id_add);
+                    if(!py_pushmethod(id_add)) {
+                        c11__abort("OP_BUILD_SET: failed to load method 'add'");
+                    }
                     py_push(begin + i);
                     if(!py_vectorcall(1, 0)) goto __ERROR;
                 }
@@ -532,14 +535,14 @@ FrameResult VM__run_top_frame(VM* self) {
                     if(magic->type == tp_nativefunc) {
                         if(!magic->_cfunc(2, SECOND())) goto __ERROR;
                         POP();
-                        *TOP() = self->last_retval;
                     } else {
                         INSERT_THIRD();     // [?, b, a]
                         *THIRD() = *magic;  // [__contains__, a, b]
                         if(!py_vectorcall(1, 0)) goto __ERROR;
                     }
-                    bool res = py_tobool(TOP());
-                    if(byte.arg) py_newbool(TOP(), !res);
+                    bool res = py_tobool(py_retval());
+                    if(byte.arg) res = !res;
+                    py_newbool(SP()++, res);
                     DISPATCH();
                 }
                 TypeError("'%t' type does not support '__contains__'", SECOND()->type);
@@ -715,6 +718,14 @@ FrameResult VM__run_top_frame(VM* self) {
                 DISPATCH();
             }
             case OP_SET_ADD: {
+                // [set, iter, value]
+                py_push(THIRD());  // [| set]
+                if(!py_pushmethod(py_name("add"))) {
+                    c11__abort("OP_SET_ADD: failed to load method 'add'");
+                }  // [|add() set]
+                py_push(THIRD());
+                if(!py_vectorcall(1, 0)) goto __ERROR;
+                POP();
                 DISPATCH();
             }
             /////////

+ 12 - 3
src/interpreter/vm.c

@@ -135,8 +135,8 @@ void VM__ctor(VM* self) {
     // inject some builtin expections
 #define INJECT_BUILTIN_EXC(name)                                                                   \
     do {                                                                                           \
-        py_Type type = pk_newtype(#name, tp_Exception, &self->builtins, NULL, false, true);         \
-        py_setdict(&self->builtins, py_name(#name), py_tpobject(type));                             \
+        py_Type type = pk_newtype(#name, tp_Exception, &self->builtins, NULL, false, true);        \
+        py_setdict(&self->builtins, py_name(#name), py_tpobject(type));                            \
         validate(tp_##name, type);                                                                 \
     } while(0)
 
@@ -179,6 +179,15 @@ void VM__ctor(VM* self) {
     pk__add_module_math();
     pk__add_module_dis();
 
+    // add python builtins
+    do {
+        bool ok = py_exec(kPythonLibs__set, "<builtins>", EXEC_MODE, &self->builtins);
+        if(!ok) {
+            py_printexc();
+            c11__abort("failed to load python builtins!");
+        }
+    } while(0);
+
     self->main = *py_newmodule("__main__");
 }
 
@@ -562,7 +571,7 @@ void ManagedHeap__mark(ManagedHeap* self) {
 
 void pk_print_stack(VM* self, Frame* frame, Bytecode byte) {
     return;
-    if(frame == NULL) return;
+    if(frame == NULL || py_isnil(&self->main)) return;
 
     py_TValue* sp = self->stack.sp;
     c11_sbuf buf;

+ 1 - 0
src/public/py_dict.c

@@ -35,6 +35,7 @@ static void Dict__ctor(Dict* self, int capacity) {
     self->indices = malloc(self->capacity * sizeof(DictIndex));
     memset(self->indices, -1, self->capacity * sizeof(DictIndex));
     c11_vector__ctor(&self->entries, sizeof(DictEntry));
+    c11_vector__reserve(&self->entries, capacity);
 }
 
 static void Dict__dtor(Dict* self) {

+ 4 - 1
src/public/py_ops.c

@@ -71,7 +71,10 @@ int py_next(py_Ref val) {
     VM* vm = pk_current_vm;
     vm->is_stopiteration = false;
     py_Ref tmp = py_tpfindmagic(val->type, __next__);
-    if(!tmp) return TypeError("'%t' object is not an iterator", val->type);
+    if(!tmp) {
+        TypeError("'%t' object is not an iterator", val->type);
+        return -1;
+    }
     py_StackRef p0 = py_peek(0);
     if(py_call(tmp, 1, val)) return true;
     if(vm->curr_exception.type == tp_StopIteration) {

+ 9 - 7
tests/69_set.py → tests/47_set.py

@@ -1,6 +1,8 @@
 a = {1, 2, 3}
-a |= {2, 3, 4}
+assert a == a
+assert a == {i for i in range(1, 3+1)}
 
+a |= {2, 3, 4}
 assert a == {1, 2, 3, 4}
 
 a = {1, 2, 3}
@@ -79,10 +81,10 @@ assert {1,2,3}.isdisjoint({4,5,6})
 assert not {1,2,3}.isdisjoint({2,3,4})
 
 # unpacking builder
-a = {1, 2, 3}
-b = {*a, 4, 5, *a, *a}
-assert b == {1, 2, 3, 4, 5}
+# a = {1, 2, 3}
+# b = {*a, 4, 5, *a, *a}
+# assert b == {1, 2, 3, 4, 5}
 
-a = set()
-b = {*a, 1, 2, 3, *a, *a}
-assert b == {1, 2, 3}
+# a = set()
+# b = {*a, 1, 2, 3, *a, *a}
+# assert b == {1, 2, 3}