support vec* unpack

This commit is contained in:
blueloveTH 2024-11-14 19:16:27 +08:00
parent 212a705a4d
commit 630a5d04fc
6 changed files with 83 additions and 19 deletions

View File

@ -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

View File

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

File diff suppressed because one or more lines are too long

View File

@ -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'

View File

@ -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;

View File

@ -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