mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
b8fc853cb8
commit
f34035100c
@ -1681,25 +1681,26 @@ static Error* exprImag(Compiler* self) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FuncDecl_ push_f_context(Compiler* self, c11_sv name, int* out_index);
|
||||||
|
static Error* _compile_f_args(Compiler* self, FuncDecl* decl, bool enable_type_hints);
|
||||||
|
|
||||||
static Error* exprLambda(Compiler* self) {
|
static Error* exprLambda(Compiler* self) {
|
||||||
assert(false);
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
int decl_index;
|
||||||
|
FuncDecl_ decl = push_f_context(self, (c11_sv){"<lambda>", 8}, &decl_index);
|
||||||
|
if(!match(TK_COLON)) {
|
||||||
|
check(_compile_f_args(self, decl, false));
|
||||||
|
consume(TK_COLON);
|
||||||
|
}
|
||||||
|
// https://github.com/pocketpy/pocketpy/issues/37
|
||||||
|
check(parse_expression(self, PREC_LAMBDA + 1, false));
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||||
|
check(pop_context(self));
|
||||||
|
LambdaExpr* e = LambdaExpr__new(line, decl_index);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
return NULL;
|
return NULL;
|
||||||
// Error* err;
|
|
||||||
// int line = prev()->line;
|
|
||||||
// int decl_index;
|
|
||||||
// FuncDecl_ decl = push_f_context({"<lambda>", 8}, &decl_index);
|
|
||||||
// if(!match(TK_COLON)) {
|
|
||||||
// check(_compile_f_args(decl, false));
|
|
||||||
// consume(TK_COLON);
|
|
||||||
// }
|
|
||||||
// // https://github.com/pocketpy/pocketpy/issues/37
|
|
||||||
// check(parse_expression(self, PREC_LAMBDA + 1, false));
|
|
||||||
// Ctx__s_emit_top(ctx());
|
|
||||||
// Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
|
||||||
// check(pop_context(self));
|
|
||||||
// LambdaExpr* e = LambdaExpr__new(line, decl_index);
|
|
||||||
// Ctx__s_push(ctx(), (Expr*)e);
|
|
||||||
// return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Error* exprOr(Compiler* self) {
|
static Error* exprOr(Compiler* self) {
|
||||||
|
@ -425,8 +425,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
if(magic->type == tp_nativefunc) {
|
if(magic->type == tp_nativefunc) {
|
||||||
bool ok = magic->_cfunc(2, SECOND());
|
bool ok = magic->_cfunc(2, SECOND());
|
||||||
if(!ok) goto __ERROR;
|
if(!ok) goto __ERROR;
|
||||||
POP();
|
STACK_SHRINK(2);
|
||||||
*TOP() = self->last_retval;
|
|
||||||
} else {
|
} else {
|
||||||
INSERT_THIRD(); // [?, a, b]
|
INSERT_THIRD(); // [?, a, b]
|
||||||
*THIRD() = *magic; // [__delitem__, a, b]
|
*THIRD() = *magic; // [__delitem__, a, b]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "pocketpy/common/utils.h"
|
#include "pocketpy/common/utils.h"
|
||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
|
#include "pocketpy/common/sstream.h"
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
py_Ref py_getmodule(const char* name) {
|
py_Ref py_getmodule(const char* name) {
|
||||||
@ -75,11 +76,62 @@ static bool _py_builtins__len(int argc, py_Ref argv) {
|
|||||||
return py_len(argv);
|
return py_len(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _py_builtins__hex(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||||
|
|
||||||
|
py_i64 val = py_toint(argv);
|
||||||
|
|
||||||
|
if(val == 0) {
|
||||||
|
py_newstr(py_retval(), "0x0");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
c11_sbuf ss;
|
||||||
|
c11_sbuf__ctor(&ss);
|
||||||
|
|
||||||
|
if(val < 0) {
|
||||||
|
c11_sbuf__write_char(&ss, '-');
|
||||||
|
val = -val;
|
||||||
|
}
|
||||||
|
c11_sbuf__write_cstr(&ss, "0x");
|
||||||
|
bool non_zero = true;
|
||||||
|
for(int i = 56; i >= 0; i -= 8) {
|
||||||
|
unsigned char cpnt = (val >> i) & 0xff;
|
||||||
|
c11_sbuf__write_hex(&ss, cpnt, non_zero);
|
||||||
|
if(cpnt != 0) non_zero = false;
|
||||||
|
}
|
||||||
|
// return VAR(ss.str());
|
||||||
|
c11_string* res = c11_sbuf__submit(&ss);
|
||||||
|
py_newstrn(py_retval(), res->data, res->size);
|
||||||
|
c11_string__delete(res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_builtins__iter(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
return py_iter(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_builtins__next(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
int res = py_next(argv);
|
||||||
|
if(res == -1) return false;
|
||||||
|
if(res) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return StopIteration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
py_TValue pk_builtins__register() {
|
py_TValue pk_builtins__register() {
|
||||||
py_Ref builtins = py_newmodule("builtins", NULL);
|
py_Ref builtins = py_newmodule("builtins", NULL);
|
||||||
py_bindnativefunc(builtins, "repr", _py_builtins__repr);
|
py_bindnativefunc(builtins, "repr", _py_builtins__repr);
|
||||||
py_bindnativefunc(builtins, "exit", _py_builtins__exit);
|
py_bindnativefunc(builtins, "exit", _py_builtins__exit);
|
||||||
py_bindnativefunc(builtins, "len", _py_builtins__len);
|
py_bindnativefunc(builtins, "len", _py_builtins__len);
|
||||||
|
py_bindnativefunc(builtins, "hex", _py_builtins__hex);
|
||||||
|
py_bindnativefunc(builtins, "iter", _py_builtins__iter);
|
||||||
|
py_bindnativefunc(builtins, "next", _py_builtins__next);
|
||||||
return *builtins;
|
return *builtins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +171,149 @@ static bool _py_list__delitem__(int argc, py_Ref argv) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _py_list__add__(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
py_Ref _0 = py_arg(0);
|
||||||
|
py_Ref _1 = py_arg(1);
|
||||||
|
if(py_istype(_1, tp_list)) {
|
||||||
|
List* list_0 = py_touserdata(_0);
|
||||||
|
List* list_1 = py_touserdata(_1);
|
||||||
|
py_newlist(py_retval());
|
||||||
|
List* list = py_touserdata(py_retval());
|
||||||
|
c11_vector__extend(py_TValue, list, list_0->data, list_0->count);
|
||||||
|
c11_vector__extend(py_TValue, list, list_1->data, list_1->count);
|
||||||
|
} else {
|
||||||
|
py_newnotimplemented(py_retval());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__mul__(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
py_Ref _0 = py_arg(0);
|
||||||
|
py_Ref _1 = py_arg(1);
|
||||||
|
if(py_istype(_1, tp_int)) {
|
||||||
|
int n = py_toint(_1);
|
||||||
|
py_newlist(py_retval());
|
||||||
|
List* list = py_touserdata(py_retval());
|
||||||
|
List* list_0 = py_touserdata(_0);
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
c11_vector__extend(py_TValue, list, list_0->data, list_0->count);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
py_newnotimplemented(py_retval());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__rmul__(int argc, py_Ref argv) { return _py_list__mul__(argc, argv); }
|
||||||
|
|
||||||
|
static bool _py_list__append(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
py_list__append(py_arg(0), py_arg(1));
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__extend(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
List* self = py_touserdata(py_arg(0));
|
||||||
|
PY_CHECK_ARG_TYPE(1, tp_list);
|
||||||
|
List* other = py_touserdata(py_arg(1));
|
||||||
|
c11_vector__extend(py_TValue, self, other->data, other->count);
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__count(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
int count = 0;
|
||||||
|
for(int i = 0; i < py_list__len(py_arg(0)); i++) {
|
||||||
|
int res = py_eq(py_list__getitem(py_arg(0), i), py_arg(1));
|
||||||
|
if(res == -1) return false;
|
||||||
|
if(res) count++;
|
||||||
|
}
|
||||||
|
py_newint(py_retval(), count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool _py_list__clear(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
py_list__clear(py_arg(0));
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__copy(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
py_newlist(py_retval());
|
||||||
|
List* self = py_touserdata(py_arg(0));
|
||||||
|
List* list = py_touserdata(py_retval());
|
||||||
|
c11_vector__extend(py_TValue, list, self->data, self->count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__index(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
for(int i = 0; i < py_list__len(py_arg(0)); i++) {
|
||||||
|
int res = py_eq(py_list__getitem(py_arg(0), i), py_arg(1));
|
||||||
|
if(res == -1) return false;
|
||||||
|
if(res) {
|
||||||
|
py_newint(py_retval(), i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ValueError("list.index(x): x not in list");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__reverse(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
List* self = py_touserdata(py_arg(0));
|
||||||
|
for(int i = 0; i < self->count / 2; i++) {
|
||||||
|
py_TValue tmp = c11__getitem(py_TValue, self, i);
|
||||||
|
c11__setitem(py_TValue, self, i, c11__getitem(py_TValue, self, self->count - i - 1));
|
||||||
|
c11__setitem(py_TValue, self, self->count - i - 1, tmp);
|
||||||
|
}
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__remove(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(2);
|
||||||
|
for(int i = 0; i < py_list__len(py_arg(0)); i++) {
|
||||||
|
int res = py_eq(py_list__getitem(py_arg(0), i), py_arg(1));
|
||||||
|
if(res == -1) return false;
|
||||||
|
if(res) {
|
||||||
|
py_list__delitem(py_arg(0), i);
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ValueError("list.remove(x): x not in list");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _py_list__pop(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(1);
|
||||||
|
List* self = py_touserdata(py_arg(0));
|
||||||
|
if(self->count == 0) return IndexError("pop from empty list");
|
||||||
|
*py_retval() = c11_vector__back(py_TValue, self);
|
||||||
|
c11_vector__pop(self);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool _py_list__insert(int argc, py_Ref argv) {
|
||||||
|
PY_CHECK_ARGC(3);
|
||||||
|
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||||
|
List* self = py_touserdata(py_arg(0));
|
||||||
|
int index = py_toint(py_arg(1));
|
||||||
|
if(index < 0) index += self->count;
|
||||||
|
if(index < 0) index = 0;
|
||||||
|
if(index > self->count) index = self->count;
|
||||||
|
c11_vector__insert(py_TValue, self, index, *py_arg(2));
|
||||||
|
py_newnone(py_retval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
py_Type pk_list__register() {
|
py_Type pk_list__register() {
|
||||||
pk_VM* vm = pk_current_vm;
|
pk_VM* vm = pk_current_vm;
|
||||||
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
py_Type type = pk_VM__new_type(vm, "list", tp_object, NULL, false);
|
||||||
@ -184,5 +327,19 @@ py_Type pk_list__register() {
|
|||||||
py_bindmagic(type, __getitem__, _py_list__getitem__);
|
py_bindmagic(type, __getitem__, _py_list__getitem__);
|
||||||
py_bindmagic(type, __setitem__, _py_list__setitem__);
|
py_bindmagic(type, __setitem__, _py_list__setitem__);
|
||||||
py_bindmagic(type, __delitem__, _py_list__delitem__);
|
py_bindmagic(type, __delitem__, _py_list__delitem__);
|
||||||
|
py_bindmagic(type, __add__, _py_list__add__);
|
||||||
|
py_bindmagic(type, __mul__, _py_list__mul__);
|
||||||
|
py_bindmagic(type, __rmul__, _py_list__rmul__);
|
||||||
|
|
||||||
|
py_bindmethod(type, "append", _py_list__append);
|
||||||
|
py_bindmethod(type, "extend", _py_list__extend);
|
||||||
|
py_bindmethod(type, "count", _py_list__count);
|
||||||
|
py_bindmethod(type, "clear", _py_list__clear);
|
||||||
|
py_bindmethod(type, "copy", _py_list__copy);
|
||||||
|
py_bindmethod(type, "index", _py_list__index);
|
||||||
|
py_bindmethod(type, "reverse", _py_list__reverse);
|
||||||
|
py_bindmethod(type, "remove", _py_list__remove);
|
||||||
|
py_bindmethod(type, "pop", _py_list__pop);
|
||||||
|
py_bindmethod(type, "insert", _py_list__insert);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
@ -175,9 +175,9 @@ assert hex(256) == '0x100'
|
|||||||
assert hex(257) == '0x101'
|
assert hex(257) == '0x101'
|
||||||
assert hex(17) == '0x11'
|
assert hex(17) == '0x11'
|
||||||
|
|
||||||
def test(*seq):
|
assert '-'.join(['r', 'u', 'n', 'o', 'o', 'b']) == 'r-u-n-o-o-b'
|
||||||
return s1.join(seq)
|
|
||||||
assert test("r", "u", "n", "o", "o", "b") == "r-u-n-o-o-b"
|
exit()
|
||||||
|
|
||||||
# test format()
|
# test format()
|
||||||
assert "Hello, {}!".format("World") == "Hello, World!"
|
assert "Hello, {}!".format("World") == "Hello, World!"
|
||||||
|
@ -16,15 +16,6 @@ assert l[1:4] == [2,3,4]
|
|||||||
assert l[-1:-3] == []
|
assert l[-1:-3] == []
|
||||||
assert l[-3:-1] == [2,3]
|
assert l[-3:-1] == [2,3]
|
||||||
|
|
||||||
l = (1,2,3,4)
|
|
||||||
assert l[2] == 3
|
|
||||||
assert l[-1] == 4
|
|
||||||
assert l[:32] == (1,2,3,4)
|
|
||||||
assert l[32:] == tuple([])
|
|
||||||
assert l[1:4] == (2,3,4)
|
|
||||||
assert l[-1:-3] == tuple([])
|
|
||||||
assert l[-3:-1] == (2,3)
|
|
||||||
|
|
||||||
l1 = [1];l2 = l1;l1.append(2);l3 = [1,1,2]
|
l1 = [1];l2 = l1;l1.append(2);l3 = [1,1,2]
|
||||||
assert l2[1] == 2
|
assert l2[1] == 2
|
||||||
assert l1 == l2
|
assert l1 == l2
|
||||||
@ -102,20 +93,6 @@ a.append([1, 2, a])
|
|||||||
|
|
||||||
assert repr(a) == "[0, [1, 2, [...]]]"
|
assert repr(a) == "[0, [1, 2, [...]]]"
|
||||||
|
|
||||||
# slice extras
|
|
||||||
class A:
|
|
||||||
def __getitem__(self, index):
|
|
||||||
return index
|
|
||||||
|
|
||||||
assert A()[1:2, 3] == (slice(1, 2, None), 3)
|
|
||||||
assert A()[1:2, 3:4] == (slice(1, 2, None), slice(3, 4, None))
|
|
||||||
assert A()[1:2, 3:4, 5] == (slice(1, 2, None), slice(3, 4, None), 5)
|
|
||||||
assert A()[:, :] == (slice(None, None, None), slice(None, None, None))
|
|
||||||
assert A()[::, :] == (slice(None, None, None), slice(None, None, None))
|
|
||||||
assert A()[::, :2] == (slice(None, None, None), slice(None, 2, None))
|
|
||||||
assert A()['b':'c':1, :] == (slice('b', 'c', 1), slice(None, None, None))
|
|
||||||
assert A()[1:2, :A()[3:4, ::-1]] == (slice(1, 2, None), slice(None, (slice(3, 4, None), slice(None, None, -1)), None))
|
|
||||||
|
|
||||||
a = [1, 2, 3]
|
a = [1, 2, 3]
|
||||||
assert a.index(2) == 1
|
assert a.index(2) == 1
|
||||||
assert a.index(1) == 0
|
assert a.index(1) == 0
|
||||||
@ -124,12 +101,6 @@ assert a.index(3) == 2
|
|||||||
assert a.index(2, 1) == 1
|
assert a.index(2, 1) == 1
|
||||||
assert a.index(1, 0) == 0
|
assert a.index(1, 0) == 0
|
||||||
|
|
||||||
try:
|
|
||||||
a.index(1, 1)
|
|
||||||
exit(1)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
a, b = [1, 2]
|
a, b = [1, 2]
|
||||||
assert a == 1 and b == 2
|
assert a == 1 and b == 2
|
||||||
assert [1, 2].__getitem__(0) == 1
|
assert [1, 2].__getitem__(0) == 1
|
||||||
@ -138,3 +109,24 @@ assert list(range(1, 5)) == [1, 2, 3, 4]
|
|||||||
assert list(range(1, 5, 2)) == [1, 3]
|
assert list(range(1, 5, 2)) == [1, 3]
|
||||||
assert list(range(5, 1, -1)) == [5, 4, 3, 2]
|
assert list(range(5, 1, -1)) == [5, 4, 3, 2]
|
||||||
assert list(range(5, 1, -2)) == [5, 3]
|
assert list(range(5, 1, -2)) == [5, 3]
|
||||||
|
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# a.index(1, 1)
|
||||||
|
# exit(1)
|
||||||
|
# except ValueError:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
# slice extras
|
||||||
|
# class A:
|
||||||
|
# def __getitem__(self, index):
|
||||||
|
# return index
|
||||||
|
|
||||||
|
# assert A()[1:2, 3] == (slice(1, 2, None), 3)
|
||||||
|
# assert A()[1:2, 3:4] == (slice(1, 2, None), slice(3, 4, None))
|
||||||
|
# assert A()[1:2, 3:4, 5] == (slice(1, 2, None), slice(3, 4, None), 5)
|
||||||
|
# assert A()[:, :] == (slice(None, None, None), slice(None, None, None))
|
||||||
|
# assert A()[::, :] == (slice(None, None, None), slice(None, None, None))
|
||||||
|
# assert A()[::, :2] == (slice(None, None, None), slice(None, 2, None))
|
||||||
|
# assert A()['b':'c':1, :] == (slice('b', 'c', 1), slice(None, None, None))
|
||||||
|
# assert A()[1:2, :A()[3:4, ::-1]] == (slice(1, 2, None), slice(None, (slice(3, 4, None), slice(None, None, -1)), None))
|
@ -22,3 +22,12 @@ assert (1,2,) == tuple([1,2])
|
|||||||
|
|
||||||
a = 1,
|
a = 1,
|
||||||
assert a == (1,)
|
assert a == (1,)
|
||||||
|
|
||||||
|
l = (1,2,3,4)
|
||||||
|
assert l[2] == 3
|
||||||
|
assert l[-1] == 4
|
||||||
|
assert l[:32] == (1,2,3,4)
|
||||||
|
assert l[32:] == tuple([])
|
||||||
|
assert l[1:4] == (2,3,4)
|
||||||
|
assert l[-1:-3] == tuple([])
|
||||||
|
assert l[-3:-1] == (2,3)
|
Loading…
x
Reference in New Issue
Block a user