This commit is contained in:
blueloveTH 2024-07-07 11:58:06 +08:00
parent b8fc853cb8
commit f34035100c
7 changed files with 262 additions and 52 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,4 +21,13 @@ assert (1,) == tuple([1])
assert (1,2,) == tuple([1,2])
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)