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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
// 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) {
|
||||
|
@ -425,8 +425,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
if(magic->type == tp_nativefunc) {
|
||||
bool ok = magic->_cfunc(2, SECOND());
|
||||
if(!ok) goto __ERROR;
|
||||
POP();
|
||||
*TOP() = self->last_retval;
|
||||
STACK_SHRINK(2);
|
||||
} else {
|
||||
INSERT_THIRD(); // [?, a, b]
|
||||
*THIRD() = *magic; // [__delitem__, a, b]
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_Ref builtins = py_newmodule("builtins", NULL);
|
||||
py_bindnativefunc(builtins, "repr", _py_builtins__repr);
|
||||
py_bindnativefunc(builtins, "exit", _py_builtins__exit);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,149 @@ static bool _py_list__delitem__(int argc, py_Ref argv) {
|
||||
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() {
|
||||
pk_VM* vm = pk_current_vm;
|
||||
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, __setitem__, _py_list__setitem__);
|
||||
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;
|
||||
}
|
@ -175,9 +175,9 @@ assert hex(256) == '0x100'
|
||||
assert hex(257) == '0x101'
|
||||
assert hex(17) == '0x11'
|
||||
|
||||
def test(*seq):
|
||||
return s1.join(seq)
|
||||
assert test("r", "u", "n", "o", "o", "b") == "r-u-n-o-o-b"
|
||||
assert '-'.join(['r', 'u', 'n', 'o', 'o', 'b']) == 'r-u-n-o-o-b'
|
||||
|
||||
exit()
|
||||
|
||||
# test format()
|
||||
assert "Hello, {}!".format("World") == "Hello, World!"
|
||||
|
@ -16,15 +16,6 @@ assert l[1:4] == [2,3,4]
|
||||
assert l[-1:-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]
|
||||
assert l2[1] == 2
|
||||
assert l1 == l2
|
||||
@ -102,20 +93,6 @@ a.append([1, 2, a])
|
||||
|
||||
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]
|
||||
assert a.index(2) == 1
|
||||
assert a.index(1) == 0
|
||||
@ -124,12 +101,6 @@ assert a.index(3) == 2
|
||||
assert a.index(2, 1) == 1
|
||||
assert a.index(1, 0) == 0
|
||||
|
||||
try:
|
||||
a.index(1, 1)
|
||||
exit(1)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
a, b = [1, 2]
|
||||
assert a == 1 and b == 2
|
||||
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(5, 1, -1)) == [5, 4, 3, 2]
|
||||
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,
|
||||
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