mirror of
https://github.com/pocketpy/pocketpy
synced 2026-03-24 14:10:18 +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 name name of the method.
|
||||||
/// @param f function to bind.
|
/// @param f function to bind.
|
||||||
PK_API void py_bindmethod(py_Type type, const char* name, py_CFunction f);
|
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.
|
/// Bind a function to the object via "argc-based" style.
|
||||||
/// @param obj the target object.
|
/// @param obj the target object.
|
||||||
/// @param name name of the function.
|
/// @param name name of the function.
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import overload
|
from typing import overload, Iterator
|
||||||
|
|
||||||
class _vecF[T]:
|
class _vecF[T]:
|
||||||
ONE: T
|
ONE: T
|
||||||
@ -17,6 +17,9 @@ class _vecF[T]:
|
|||||||
def length_squared(self) -> float: ...
|
def length_squared(self) -> float: ...
|
||||||
def normalize(self) -> T: ...
|
def normalize(self) -> T: ...
|
||||||
|
|
||||||
|
# dummy iter for unpacking
|
||||||
|
def __iter__(self) -> Iterator[float]: ...
|
||||||
|
|
||||||
class _vecI[T]:
|
class _vecI[T]:
|
||||||
ONE: T
|
ONE: T
|
||||||
ZERO: T
|
ZERO: T
|
||||||
@ -32,6 +35,9 @@ class _vecI[T]:
|
|||||||
|
|
||||||
def dot(self, other: T) -> int: ...
|
def dot(self, other: T) -> int: ...
|
||||||
|
|
||||||
|
# dummy iter for unpacking
|
||||||
|
def __iter__(self) -> Iterator[int]: ...
|
||||||
|
|
||||||
|
|
||||||
class vec2(_vecF['vec2']):
|
class vec2(_vecF['vec2']):
|
||||||
LEFT: vec2
|
LEFT: vec2
|
||||||
|
|||||||
@ -30,6 +30,7 @@ LiteralString = _PLACEHOLDER
|
|||||||
|
|
||||||
Iterable = _PLACEHOLDER
|
Iterable = _PLACEHOLDER
|
||||||
Generator = _PLACEHOLDER
|
Generator = _PLACEHOLDER
|
||||||
|
Iterator = _PLACEHOLDER
|
||||||
|
|
||||||
Hashable = _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;
|
int i = 0;
|
||||||
for(int j = 0; j < self.size; j++) {
|
for(int j = 0; j < self.size; j++) {
|
||||||
if(data[j] == sep) {
|
if(data[j] == sep) {
|
||||||
if(j > i) {
|
assert(j >= i);
|
||||||
c11_sv tmp = {data + i, j - i};
|
c11_sv tmp = {data + i, j - i};
|
||||||
c11_vector__push(c11_sv, &retval, tmp);
|
c11_vector__push(c11_sv, &retval, tmp);
|
||||||
}
|
|
||||||
i = j + 1;
|
i = j + 1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(self.size > i) {
|
if(i <= self.size) {
|
||||||
c11_sv tmp = {data + i, self.size - i};
|
c11_sv tmp = {data + i, self.size - i};
|
||||||
c11_vector__push(c11_sv, &retval, tmp);
|
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) {
|
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 retval;
|
||||||
c11_vector__ctor(&retval, sizeof(c11_sv));
|
c11_vector__ctor(&retval, sizeof(c11_sv));
|
||||||
int start = 0;
|
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);
|
int i = c11_sv__index2(self, sep, start);
|
||||||
if(i == -1) break;
|
if(i == -1) break;
|
||||||
c11_sv tmp = {data + start, i - start};
|
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;
|
start = i + sep.size;
|
||||||
}
|
}
|
||||||
c11_sv tmp = {data + start, self.size - start};
|
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;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
#include "pocketpy/objects/error.h"
|
#include "pocketpy/objects/error.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
static bool stack_unpack_sequence(VM* self, uint16_t arg);
|
|
||||||
static bool stack_format_object(VM* self, c11_sv spec);
|
static bool stack_format_object(VM* self, c11_sv spec);
|
||||||
|
|
||||||
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
|
#define CHECK_RETURN_FROM_EXCEPT_OR_FINALLY() \
|
||||||
@ -839,7 +838,71 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
}
|
}
|
||||||
////////
|
////////
|
||||||
case OP_UNPACK_SEQUENCE: {
|
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();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_UNPACK_EX: {
|
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;
|
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) {
|
static bool stack_format_object(VM* self, c11_sv spec) {
|
||||||
// format TOS via `spec` inplace
|
// format TOS via `spec` inplace
|
||||||
// spec: '!r:.2f', '.2f'
|
// spec: '!r:.2f', '.2f'
|
||||||
|
|||||||
@ -860,8 +860,8 @@ void pk__add_module_linalg() {
|
|||||||
py_newvec2(_const(vec2, "DOWN"), (c11_vec2){{0, 1}});
|
py_newvec2(_const(vec2, "DOWN"), (c11_vec2){{0, 1}});
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
py_bindmethod(vec2, "angle", vec2_angle_STATIC);
|
py_bindstaticmethod(vec2, "angle", vec2_angle_STATIC);
|
||||||
py_bindmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC);
|
py_bindstaticmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC);
|
||||||
|
|
||||||
py_bindproperty(vec2, "x", vec2__x, NULL);
|
py_bindproperty(vec2, "x", vec2__x, NULL);
|
||||||
py_bindproperty(vec2, "y", vec2__y, 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, "inverse", mat3x3_inverse);
|
||||||
py_bindmethod(mat3x3, "copy_", mat3x3_copy_);
|
py_bindmethod(mat3x3, "copy_", mat3x3_copy_);
|
||||||
py_bindmethod(mat3x3, "inverse_", mat3x3_inverse_);
|
py_bindmethod(mat3x3, "inverse_", mat3x3_inverse_);
|
||||||
py_bindmethod(mat3x3, "zeros", mat3x3_zeros_STATIC);
|
py_bindstaticmethod(mat3x3, "zeros", mat3x3_zeros_STATIC);
|
||||||
py_bindmethod(mat3x3, "identity", mat3x3_identity_STATIC);
|
py_bindstaticmethod(mat3x3, "identity", mat3x3_identity_STATIC);
|
||||||
py_bindmethod(mat3x3, "trs", mat3x3_trs_STATIC);
|
py_bindstaticmethod(mat3x3, "trs", mat3x3_trs_STATIC);
|
||||||
py_bindmethod(mat3x3, "copy_trs_", mat3x3_copy_trs_);
|
py_bindmethod(mat3x3, "copy_trs_", mat3x3_copy_trs_);
|
||||||
py_bindmethod(mat3x3, "t", mat3x3_t);
|
py_bindmethod(mat3x3, "t", mat3x3_t);
|
||||||
py_bindmethod(mat3x3, "r", mat3x3_r);
|
py_bindmethod(mat3x3, "r", mat3x3_r);
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
#include "pocketpy/common/utils.h"
|
|
||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
#include "pocketpy/common/sstream.h"
|
|
||||||
|
|
||||||
typedef struct array_iterator {
|
typedef struct array_iterator {
|
||||||
py_TValue* p;
|
py_TValue* p;
|
||||||
|
|||||||
@ -117,7 +117,6 @@ static bool type__annotations__(int argc, py_Ref argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pk_object__register() {
|
void pk_object__register() {
|
||||||
// TODO: use staticmethod
|
|
||||||
py_bindmagic(tp_object, __new__, pk__object_new);
|
py_bindmagic(tp_object, __new__, pk__object_new);
|
||||||
|
|
||||||
py_bindmagic(tp_object, __hash__, object__hash__);
|
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) {
|
static bool str_split(int argc, py_Ref argv) {
|
||||||
c11_sv self = c11_string__sv(py_touserdata(&argv[0]));
|
c11_sv self = c11_string__sv(py_touserdata(&argv[0]));
|
||||||
c11_vector res;
|
c11_vector res;
|
||||||
|
bool discard_empty = false;
|
||||||
if(argc > 2) return TypeError("split() takes at most 2 arguments");
|
if(argc > 2) return TypeError("split() takes at most 2 arguments");
|
||||||
if(argc == 1) {
|
if(argc == 1) {
|
||||||
// sep = ' '
|
// sep = None
|
||||||
res = c11_sv__split(self, ' ');
|
res = c11_sv__split(self, ' ');
|
||||||
|
discard_empty = true;
|
||||||
}
|
}
|
||||||
if(argc == 2) {
|
if(argc == 2) {
|
||||||
// sep = argv[1]
|
// sep = argv[1]
|
||||||
if(!py_checkstr(&argv[1])) return false;
|
if(!py_checkstr(&argv[1])) return false;
|
||||||
c11_sv sep = c11_string__sv(py_touserdata(&argv[1]));
|
c11_sv sep = c11_string__sv(py_touserdata(&argv[1]));
|
||||||
|
if(sep.size == 0) return ValueError("empty separator");
|
||||||
res = c11_sv__split2(self, sep);
|
res = c11_sv__split2(self, sep);
|
||||||
}
|
}
|
||||||
py_newlistn(py_retval(), res.length);
|
py_newlist(py_retval());
|
||||||
for(int i = 0; i < res.length; i++) {
|
for(int i = 0; i < res.length; i++) {
|
||||||
c11_sv item = c11__getitem(c11_sv, &res, i);
|
c11_sv part = c11__getitem(c11_sv, &res, i);
|
||||||
py_newstrv(py_list_getitem(py_retval(), i), item);
|
if(discard_empty && part.size == 0) continue;
|
||||||
|
py_newstrv(py_list_emplace(py_retval()), part);
|
||||||
}
|
}
|
||||||
c11_vector__dtor(&res);
|
c11_vector__dtor(&res);
|
||||||
return true;
|
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);
|
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) {
|
void py_bindfunc(py_Ref obj, const char* name, py_CFunction f) {
|
||||||
py_TValue tmp;
|
py_TValue tmp;
|
||||||
py_newnativefunc(&tmp, f);
|
py_newnativefunc(&tmp, f);
|
||||||
|
|||||||
@ -9,7 +9,10 @@ assert 'testing5' >= 'test' + 'ing1'
|
|||||||
assert 'abc' + 'def' == 'abcdef'
|
assert 'abc' + 'def' == 'abcdef'
|
||||||
assert 'abc' * 3 == 'abcabcabc'
|
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 = ''
|
a = ''
|
||||||
b = 'test'
|
b = 'test'
|
||||||
@ -46,13 +49,19 @@ assert t.startswith('this') == True;
|
|||||||
|
|
||||||
assert t.split('w') == ['this is string example....', 'o', '!!!']
|
assert t.split('w') == ['this is string example....', 'o', '!!!']
|
||||||
assert "a,b,c".split(',') == ['a', 'b', 'c']
|
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 '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 ' 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'
|
try:
|
||||||
assert x.split('cc') == ['aa bb ']
|
'a'.split('')
|
||||||
|
exit(1)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
assert '111'.count('1') == 3
|
assert '111'.count('1') == 3
|
||||||
assert '111'.count('11') == 1
|
assert '111'.count('11') == 1
|
||||||
|
|||||||
@ -315,16 +315,9 @@ val = vec2.angle(vec2(-1, 0), vec2(0, -1))
|
|||||||
assert 1.57 < val < 1.58
|
assert 1.57 < val < 1.58
|
||||||
|
|
||||||
# test about staticmethod
|
# 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()
|
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.copy_(mat3x3.zeros()) is None
|
||||||
assert d == mat3x3.zeros()
|
assert d == mat3x3.zeros()
|
||||||
|
|
||||||
@ -405,3 +398,12 @@ assert vec2(vec2i.LEFT) == vec2(-1, 0)
|
|||||||
assert vec2(vec2i.RIGHT) == vec2(1, 0)
|
assert vec2(vec2i.RIGHT) == vec2(1, 0)
|
||||||
assert vec3(vec3i.ONE) == vec3(1, 1, 1)
|
assert vec3(vec3i.ONE) == vec3(1, 1, 1)
|
||||||
assert vec3(vec3i.ZERO) == vec3(0, 0, 0)
|
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