mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-05 19:20:17 +00:00
Compare commits
3 Commits
35f973059c
...
104785c94b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
104785c94b | ||
|
|
630a5d04fc | ||
|
|
212a705a4d |
@ -376,6 +376,11 @@ PK_API void py_bind(py_Ref obj, const char* sig, py_CFunction f);
|
||||
/// @param name name of the method.
|
||||
/// @param f function to bind.
|
||||
PK_API void py_bindmethod(py_Type type, const char* name, py_CFunction f);
|
||||
/// Bind a static method to type via "argc-based" style.
|
||||
/// @param type the target type.
|
||||
/// @param name name of the method.
|
||||
/// @param f function to bind.
|
||||
PK_API void py_bindstaticmethod(py_Type type, const char* name, py_CFunction f);
|
||||
/// Bind a function to the object via "argc-based" style.
|
||||
/// @param obj the target object.
|
||||
/// @param name name of the function.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
@ -188,15 +188,13 @@ c11_vector /* T=c11_sv */ c11_sv__split(c11_sv self, char sep) {
|
||||
int i = 0;
|
||||
for(int j = 0; j < self.size; j++) {
|
||||
if(data[j] == sep) {
|
||||
if(j > i) {
|
||||
c11_sv tmp = {data + i, j - i};
|
||||
c11_vector__push(c11_sv, &retval, tmp);
|
||||
}
|
||||
assert(j >= i);
|
||||
c11_sv tmp = {data + i, j - i};
|
||||
c11_vector__push(c11_sv, &retval, tmp);
|
||||
i = j + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(self.size > i) {
|
||||
if(i <= self.size) {
|
||||
c11_sv tmp = {data + i, self.size - i};
|
||||
c11_vector__push(c11_sv, &retval, tmp);
|
||||
}
|
||||
@ -204,6 +202,7 @@ c11_vector /* T=c11_sv */ c11_sv__split(c11_sv self, char sep) {
|
||||
}
|
||||
|
||||
c11_vector /* T=c11_sv */ c11_sv__split2(c11_sv self, c11_sv sep) {
|
||||
if(sep.size == 1) return c11_sv__split(self, sep.data[0]);
|
||||
c11_vector retval;
|
||||
c11_vector__ctor(&retval, sizeof(c11_sv));
|
||||
int start = 0;
|
||||
@ -212,11 +211,11 @@ c11_vector /* T=c11_sv */ c11_sv__split2(c11_sv self, c11_sv sep) {
|
||||
int i = c11_sv__index2(self, sep, start);
|
||||
if(i == -1) break;
|
||||
c11_sv tmp = {data + start, i - start};
|
||||
if(tmp.size != 0) c11_vector__push(c11_sv, &retval, tmp);
|
||||
c11_vector__push(c11_sv, &retval, tmp);
|
||||
start = i + sep.size;
|
||||
}
|
||||
c11_sv tmp = {data + start, self.size - start};
|
||||
if(tmp.size != 0) c11_vector__push(c11_sv, &retval, tmp);
|
||||
c11_vector__push(c11_sv, &retval, tmp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -860,8 +860,8 @@ void pk__add_module_linalg() {
|
||||
py_newvec2(_const(vec2, "DOWN"), (c11_vec2){{0, 1}});
|
||||
// clang-format on
|
||||
|
||||
py_bindmethod(vec2, "angle", vec2_angle_STATIC);
|
||||
py_bindmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC);
|
||||
py_bindstaticmethod(vec2, "angle", vec2_angle_STATIC);
|
||||
py_bindstaticmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC);
|
||||
|
||||
py_bindproperty(vec2, "x", vec2__x, NULL);
|
||||
py_bindproperty(vec2, "y", vec2__y, NULL);
|
||||
@ -884,9 +884,9 @@ void pk__add_module_linalg() {
|
||||
py_bindmethod(mat3x3, "inverse", mat3x3_inverse);
|
||||
py_bindmethod(mat3x3, "copy_", mat3x3_copy_);
|
||||
py_bindmethod(mat3x3, "inverse_", mat3x3_inverse_);
|
||||
py_bindmethod(mat3x3, "zeros", mat3x3_zeros_STATIC);
|
||||
py_bindmethod(mat3x3, "identity", mat3x3_identity_STATIC);
|
||||
py_bindmethod(mat3x3, "trs", mat3x3_trs_STATIC);
|
||||
py_bindstaticmethod(mat3x3, "zeros", mat3x3_zeros_STATIC);
|
||||
py_bindstaticmethod(mat3x3, "identity", mat3x3_identity_STATIC);
|
||||
py_bindstaticmethod(mat3x3, "trs", mat3x3_trs_STATIC);
|
||||
py_bindmethod(mat3x3, "copy_trs_", mat3x3_copy_trs_);
|
||||
py_bindmethod(mat3x3, "t", mat3x3_t);
|
||||
py_bindmethod(mat3x3, "r", mat3x3_r);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -117,7 +117,6 @@ static bool type__annotations__(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
void pk_object__register() {
|
||||
// TODO: use staticmethod
|
||||
py_bindmagic(tp_object, __new__, pk__object_new);
|
||||
|
||||
py_bindmagic(tp_object, __hash__, object__hash__);
|
||||
|
||||
@ -317,21 +317,25 @@ static bool str_replace(int argc, py_Ref argv) {
|
||||
static bool str_split(int argc, py_Ref argv) {
|
||||
c11_sv self = c11_string__sv(py_touserdata(&argv[0]));
|
||||
c11_vector res;
|
||||
bool discard_empty = false;
|
||||
if(argc > 2) return TypeError("split() takes at most 2 arguments");
|
||||
if(argc == 1) {
|
||||
// sep = ' '
|
||||
// sep = None
|
||||
res = c11_sv__split(self, ' ');
|
||||
discard_empty = true;
|
||||
}
|
||||
if(argc == 2) {
|
||||
// sep = argv[1]
|
||||
if(!py_checkstr(&argv[1])) return false;
|
||||
c11_sv sep = c11_string__sv(py_touserdata(&argv[1]));
|
||||
if(sep.size == 0) return ValueError("empty separator");
|
||||
res = c11_sv__split2(self, sep);
|
||||
}
|
||||
py_newlistn(py_retval(), res.length);
|
||||
py_newlist(py_retval());
|
||||
for(int i = 0; i < res.length; i++) {
|
||||
c11_sv item = c11__getitem(c11_sv, &res, i);
|
||||
py_newstrv(py_list_getitem(py_retval(), i), item);
|
||||
c11_sv part = c11__getitem(c11_sv, &res, i);
|
||||
if(discard_empty && part.size == 0) continue;
|
||||
py_newstrv(py_list_emplace(py_retval()), part);
|
||||
}
|
||||
c11_vector__dtor(&res);
|
||||
return true;
|
||||
|
||||
@ -54,6 +54,17 @@ void py_bindmethod(py_Type type, const char* name, py_CFunction f) {
|
||||
py_setdict(py_tpobject(type), py_name(name), &tmp);
|
||||
}
|
||||
|
||||
void py_bindstaticmethod(py_Type type, const char* name, py_CFunction f) {
|
||||
py_TValue tmp;
|
||||
py_newnativefunc(&tmp, f);
|
||||
bool ok = py_tpcall(tp_staticmethod, 1, &tmp);
|
||||
if(!ok) {
|
||||
py_printexc();
|
||||
c11__abort("py_bindstaticmethod(): failed to create staticmethod");
|
||||
}
|
||||
py_setdict(py_tpobject(type), py_name(name), py_retval());
|
||||
}
|
||||
|
||||
void py_bindfunc(py_Ref obj, const char* name, py_CFunction f) {
|
||||
py_TValue tmp;
|
||||
py_newnativefunc(&tmp, f);
|
||||
|
||||
@ -9,7 +9,10 @@ assert 'testing5' >= 'test' + 'ing1'
|
||||
assert 'abc' + 'def' == 'abcdef'
|
||||
assert 'abc' * 3 == 'abcabcabc'
|
||||
|
||||
assert repr('\\\n\t\'\r\b\x48') == r"'\\\n\t\'\r\bH'"
|
||||
assert repr('\\\n\t\'\r\b\x48') in [
|
||||
r"'\\\n\t\'\r\bH'",
|
||||
'"\\\\\\n\\t\'\\r\\x08H"',
|
||||
]
|
||||
|
||||
a = ''
|
||||
b = 'test'
|
||||
@ -46,13 +49,19 @@ assert t.startswith('this') == True;
|
||||
|
||||
assert t.split('w') == ['this is string example....', 'o', '!!!']
|
||||
assert "a,b,c".split(',') == ['a', 'b', 'c']
|
||||
assert 'a,'.split(',') == ['a']
|
||||
assert 'a,'.split(',') == ['a', '']
|
||||
assert 'foo!!bar!!baz'.split('!!') == ['foo', 'bar', 'baz']
|
||||
assert ' 4 3 '.split() == ['4', '3']
|
||||
assert ' 4 3 '.split(' ') == ['4', '3']
|
||||
assert ' 4 3 '.split(' ') == ['', '', '4', '3', '', '']
|
||||
assert 'aa bb cccc'.split('cc') == ['aa bb ', '', '']
|
||||
assert '.a.b.'.split('.') == ['', 'a', 'b', '']
|
||||
assert '.a...b.'.split('.') == ['', 'a', '', '', 'b', '']
|
||||
|
||||
x = 'aa bb cccc'
|
||||
assert x.split('cc') == ['aa bb ']
|
||||
try:
|
||||
'a'.split('')
|
||||
exit(1)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
assert '111'.count('1') == 3
|
||||
assert '111'.count('11') == 1
|
||||
|
||||
@ -315,16 +315,9 @@ val = vec2.angle(vec2(-1, 0), vec2(0, -1))
|
||||
assert 1.57 < val < 1.58
|
||||
|
||||
# test about staticmethod
|
||||
# class mymat3x3(mat3x3):
|
||||
# def f(self):
|
||||
# _0 = self.zeros()
|
||||
# _1 = super().zeros()
|
||||
# _2 = mat3x3.zeros()
|
||||
# return _0 == _1 == _2
|
||||
|
||||
# assert mymat3x3().f()
|
||||
|
||||
d = mat3x3.identity()
|
||||
d1 = mat3x3(1, 2, 3, 4, 5, 6, 7, 8, 9).identity()
|
||||
assert d == d1
|
||||
assert d.copy_(mat3x3.zeros()) is None
|
||||
assert d == mat3x3.zeros()
|
||||
|
||||
@ -405,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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user