blueloveTH пре 1 година
родитељ
комит
630a5d04fc
6 измењених фајлова са 82 додато и 18 уклоњено
  1. 7 1
      include/typings/linalg.pyi
  2. 1 0
      python/typing.py
  3. 0 0
      src/common/_generated.c
  4. 65 14
      src/interpreter/ceval.c
  5. 0 3
      src/public/py_array.c
  6. 9 0
      tests/80_linalg.py

+ 7 - 1
include/typings/linalg.pyi

@@ -1,4 +1,4 @@
-from typing import overload
+from typing import overload, Iterator
 
 class _vecF[T]:
     ONE: T
@@ -17,6 +17,9 @@ class _vecF[T]:
     def length_squared(self) -> float: ...
     def normalize(self) -> T: ...
 
+    # dummy iter for unpacking
+    def __iter__(self) -> Iterator[float]: ...
+
 class _vecI[T]:
     ONE: T
     ZERO: T
@@ -32,6 +35,9 @@ class _vecI[T]:
 
     def dot(self, other: T) -> int: ...
 
+    # dummy iter for unpacking
+    def __iter__(self) -> Iterator[int]: ...
+
 
 class vec2(_vecF['vec2']):
     LEFT: vec2

+ 1 - 0
python/typing.py

@@ -30,6 +30,7 @@ LiteralString = _PLACEHOLDER
 
 Iterable = _PLACEHOLDER
 Generator = _PLACEHOLDER
+Iterator = _PLACEHOLDER
 
 Hashable = _PLACEHOLDER
 

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
src/common/_generated.c


+ 65 - 14
src/interpreter/ceval.c

@@ -8,7 +8,6 @@
 #include "pocketpy/objects/error.h"
 #include <stdbool.h>
 
-static bool stack_unpack_sequence(VM* self, uint16_t arg);
 static bool stack_format_object(VM* self, c11_sv spec);
 
 #define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY()                                                      \
@@ -839,7 +838,71 @@ FrameResult VM__run_top_frame(VM* self) {
             }
             ////////
             case OP_UNPACK_SEQUENCE: {
-                if(!stack_unpack_sequence(self, byte.arg)) goto __ERROR;
+                py_TValue* p;
+                int length;
+
+                switch(TOP()->type) {
+                    case tp_tuple: {
+                        length = py_tuple_len(TOP());
+                        p = py_tuple_data(TOP());
+                        break;
+                    }
+                    case tp_list: {
+                        length = py_list_len(TOP());
+                        p = py_list_data(TOP());
+                        break;
+                    }
+                    case tp_vec2i: {
+                        length = 2;
+                        if(byte.arg != length) break;
+                        c11_vec2i val = py_tovec2i(TOP());
+                        POP();
+                        py_newint(SP()++, val.x);
+                        py_newint(SP()++, val.y);
+                        DISPATCH();
+                    }
+                    case tp_vec2: {
+                        length = 2;
+                        if(byte.arg != length) break;
+                        c11_vec2 val = py_tovec2(TOP());
+                        POP();
+                        py_newfloat(SP()++, val.x);
+                        py_newfloat(SP()++, val.y);
+                        DISPATCH();
+                    }
+                    case tp_vec3i: {
+                        length = 3;
+                        if(byte.arg != length) break;
+                        c11_vec3i val = py_tovec3i(TOP());
+                        POP();
+                        py_newint(SP()++, val.x);
+                        py_newint(SP()++, val.y);
+                        py_newint(SP()++, val.z);
+                        DISPATCH();
+                    }
+                    case tp_vec3: {
+                        length = 3;
+                        if(byte.arg != length) break;
+                        c11_vec3 val = py_tovec3(TOP());
+                        POP();
+                        py_newfloat(SP()++, val.x);
+                        py_newfloat(SP()++, val.y);
+                        py_newfloat(SP()++, val.z);
+                        DISPATCH();
+                    }
+                    default: {
+                        TypeError("expected list or tuple to unpack, got %t", TOP()->type);
+                        goto __ERROR;
+                    }
+                }
+                if(length != byte.arg) {
+                    ValueError("expected %d values to unpack, got %d", byte.arg, length);
+                    goto __ERROR;
+                }
+                POP();
+                for(int i = 0; i < length; i++) {
+                    PUSH(p + i);
+                }
                 DISPATCH();
             }
             case OP_UNPACK_EX: {
@@ -1141,18 +1204,6 @@ bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) {
     return ok;
 }
 
-static bool stack_unpack_sequence(VM* self, uint16_t arg) {
-    py_TValue* p;
-    int length = pk_arrayview(TOP(), &p);
-    if(length == -1) return TypeError("expected list or tuple to unpack, got %t", TOP()->type);
-    if(length != arg) return ValueError("expected %d values to unpack, got %d", arg, length);
-    POP();
-    for(int i = 0; i < length; i++) {
-        PUSH(p + i);
-    }
-    return true;
-}
-
 static bool stack_format_object(VM* self, c11_sv spec) {
     // format TOS via `spec` inplace
     // spec: '!r:.2f', '.2f'

+ 0 - 3
src/public/py_array.c

@@ -1,9 +1,6 @@
 #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;

+ 9 - 0
tests/80_linalg.py

@@ -398,3 +398,12 @@ assert vec2(vec2i.LEFT) == vec2(-1, 0)
 assert vec2(vec2i.RIGHT) == vec2(1, 0)
 assert vec3(vec3i.ONE) == vec3(1, 1, 1)
 assert vec3(vec3i.ZERO) == vec3(0, 0, 0)
+
+x, y = vec2i(1, 2)
+assert x == 1 and y == 2
+x, y, z = vec3i(1, 2, 3)
+assert x == 1 and y == 2 and z == 3
+x, y = vec2(3.0, 4.0)
+assert x == 3.0 and y == 4.0
+x, y, z = vec3(1.0, 2.0, 3.0)
+assert x == 1.0 and y == 2.0 and z == 3.0

Неке датотеке нису приказане због велике количине промена