blueloveTH 1 éve
szülő
commit
83c54fbeac

+ 2 - 1
include/pocketpy/common/algorithm.h

@@ -40,7 +40,8 @@ extern "C" {
 bool c11__stable_sort(void* ptr,
                       int count,
                       int elem_size,
-                      int (*f_le)(const void* a, const void* b));
+                      int (*f_lt)(const void* a, const void* b, void* extra),
+                      void* extra);
 
 #ifdef __cplusplus
 }

+ 3 - 3
include/pocketpy/common/vector.h

@@ -75,10 +75,10 @@ c11_array c11_vector__submit(c11_vector* self);
         (self)->count--;                                                                           \
     } while(0)
 
-#define c11_vector__reverse(T, self, start, end)                                                   \
+#define c11__reverse(T, self)                                                                      \
     do {                                                                                           \
-        T* p = (T*)(self)->data + (start);                                                         \
-        T* q = (T*)(self)->data + (end);                                                           \
+        T* p = (T*)(self)->data;                                                                   \
+        T* q = (T*)(self)->data + (self)->count - 1;                                               \
         while(p < q) {                                                                             \
             T tmp = *p;                                                                            \
             *p = *q;                                                                               \

+ 7 - 1
include/pocketpy/interpreter/vm.h

@@ -91,7 +91,13 @@ py_Type pk_VM__new_type(pk_VM* self,
 pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bool opcall);
 
 const char* pk_opname(Opcode op);
-py_TValue* pk_arrayview(py_Ref self, int* size);
+
+py_TValue* pk_arrayview(py_Ref self, int* length);
+
+/// Assumes [a, b] are on the stack, performs a binary op.
+/// The result is stored in `self->last_retval`.
+/// The stack remains unchanged.
+bool pk_stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
 
 // type registration
 void pk_object__register();

+ 3 - 4
include/pocketpy/objects/codeobject.h

@@ -118,16 +118,15 @@ typedef struct FuncDecl {
 typedef FuncDecl* FuncDecl_;
 
 FuncDecl_ FuncDecl__rcnew(pk_SourceData_ src, c11_sv name);
-void FuncDecl__dtor(FuncDecl* self);
 void FuncDecl__add_kwarg(FuncDecl* self, int index, uint16_t key, const py_TValue* value);
-void FuncDecl__gc_mark(const FuncDecl* self);
 
 // runtime function
 typedef struct Function {
     FuncDecl_ decl;
-    PyObject* module;     // weak ref
-    PyObject* clazz;      // weak ref
+    PyObject* module;      // weak ref
+    PyObject* clazz;       // weak ref
     pk_NameDict* closure;  // strong ref
+    py_CFunction cfunc;    // wrapped C function
 } Function;
 
 void Function__ctor(Function* self, FuncDecl_ decl, PyObject* module);

+ 8 - 8
include/pocketpy/pocketpy.h

@@ -89,7 +89,7 @@ void py_newfunction2(py_Ref out,
                      const char* sig,
                      enum BindType bt,
                      const char* docstring,
-                     const py_Ref upvalue);
+                     int slots);
 // old style argc-based function
 void py_newnativefunc(py_Ref out, py_CFunction);
 
@@ -134,13 +134,13 @@ py_GlobalRef py_tpmagic(py_Type type, py_Name name);
 #define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpmagic((type), __magic__), (f))
 
 // new style decl-based bindings
-py_TmpRef py_bind(py_Ref obj, const char* sig, py_CFunction f);
-py_TmpRef py_bind2(py_Ref obj,
-                   const char* sig,
-                   py_CFunction f,
-                   enum BindType bt,
-                   const char* docstring,
-                   const py_Ref upvalue);
+void py_bind(py_Ref obj, const char* sig, py_CFunction f);
+void py_bind2(py_Ref obj,
+              const char* sig,
+              py_CFunction f,
+              enum BindType bt,
+              const char* docstring,
+              int slots);
 // old style argc-based bindings
 void py_bindmethod(py_Type type, const char* name, py_CFunction f);
 void py_bindmethod2(py_Type type, const char* name, py_CFunction f, enum BindType bt);

+ 6 - 4
src/common/algorithm.c

@@ -8,9 +8,10 @@ static bool merge(char* a,
                   char* b_end,
                   char* r,
                   int elem_size,
-                  int (*f_lt)(const void* a, const void* b)) {
+                  int (*f_lt)(const void* a, const void* b, void* extra),
+                  void* extra) {
     while(a < a_end && b < b_end) {
-        int res = f_lt(a, b);
+        int res = f_lt(a, b, extra);
         // check error
         if(res == -1) return false;
         if(res) {
@@ -34,14 +35,15 @@ static bool merge(char* a,
 bool c11__stable_sort(void* ptr_,
                       int count,
                       int elem_size,
-                      int (*f_lt)(const void* a, const void* b)) {
+                      int (*f_lt)(const void* a, const void* b, void* extra),
+                      void* extra) {
     // merge sort
     char *ptr = ptr_, *tmp = malloc(count * elem_size);
     for(int seg = 1; seg < count; seg *= 2) {
         for(char* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) {
             char *b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size;
             if(b_end > ptr + count * elem_size) b_end = ptr + count * elem_size;
-            bool ok = merge(a, a_end, b, b_end, tmp, elem_size, f_lt);
+            bool ok = merge(a, a_end, b, b_end, tmp, elem_size, f_lt, extra);
             if(!ok) {
                 free(tmp);
                 return false;

+ 17 - 7
src/interpreter/ceval.c

@@ -5,7 +5,6 @@
 #include "pocketpy/pocketpy.h"
 #include <stdbool.h>
 
-static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop);
 static bool stack_unpack_sequence(pk_VM* self, uint16_t arg);
 
 #define DISPATCH()                                                                                 \
@@ -94,6 +93,20 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 case tp_float: c11_sbuf__write_f64(&buf, p->_f64, -1); break;
                 case tp_bool: c11_sbuf__write_cstr(&buf, p->_bool ? "True" : "False"); break;
                 case tp_none_type: c11_sbuf__write_cstr(&buf, "None"); break;
+                case tp_list: {
+                    pk_sprintf(&buf, "list(%d)", py_list__len(p));
+                    break;
+                }
+                case tp_tuple: {
+                    pk_sprintf(&buf, "tuple(%d)", py_list__len(p));
+                    break;
+                }
+                case tp_function: {
+                    Function* ud = py_touserdata(p);
+                    c11_sbuf__write_cstr(&buf, ud->decl->code.name->data);
+                    c11_sbuf__write_cstr(&buf, "()");
+                    break;
+                }
                 case tp_type: {
                     pk_sprintf(&buf, "<class '%t'>", py_totype(p));
                     break;
@@ -541,7 +554,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
             case OP_BINARY_OP: {
                 py_Name op = byte.arg & 0xFF;
                 py_Name rop = byte.arg >> 8;
-                if(!stack_binaryop(self, op, rop)) goto __ERROR;
+                if(!pk_stack_binaryop(self, op, rop)) goto __ERROR;
                 POP();
                 *TOP() = self->last_retval;
                 DISPATCH();
@@ -728,10 +741,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
     return RES_RETURN;
 }
 
-/// Assumes [a, b] are on the stack, performs a binary op.
-/// The result is stored in `self->last_retval`.
-/// The stack remains unchanged.
-static bool stack_binaryop(pk_VM* self, py_Name op, py_Name rop) {
+bool pk_stack_binaryop(pk_VM* self, py_Name op, py_Name rop) {
     // [a, b]
     py_Ref magic = py_tpfindmagic(SECOND()->type, op);
     if(magic) {
@@ -760,7 +770,7 @@ bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
     pk_VM* self = pk_current_vm;
     PUSH(lhs);
     PUSH(rhs);
-    bool ok = stack_binaryop(self, op, rop);
+    bool ok = pk_stack_binaryop(self, op, rop);
     STACK_SHRINK(2);
     return ok;
 }

+ 21 - 15
src/interpreter/vm.c

@@ -307,12 +307,12 @@ bool __prepare_py_call(py_TValue* buffer,
 
     if(decl->starred_kwarg != -1) py_newdict(&buffer[decl->starred_kwarg]);
 
-    for(int j = 0; j < kwargc; j += 2) {
-        py_Name key = py_toint(&p1[j]);
+    for(int j = 0; j < kwargc; j++) {
+        py_Name key = py_toint(&p1[2 * j]);
         int index = c11_smallmap_n2i__get(&decl->kw_to_index, key, -1);
         // if key is an explicit key, set as local variable
         if(index >= 0) {
-            buffer[index] = p1[j + 1];
+            buffer[index] = p1[2 * j + 1];
         } else {
             // otherwise, set as **kwargs if possible
             if(decl->starred_kwarg == -1) {
@@ -336,6 +336,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
     // [callable, <self>, args..., kwargs...]
     //      ^p0                    ^p1      ^_sp
 
+#if 0
     // handle boundmethod, do a patch
     if(p0->type == tp_bound_method) {
         assert(false);
@@ -347,9 +348,9 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
         // p1[-(ARGC + 1)] = bm.self;
         // [unbound, self, args..., kwargs...]
     }
+#endif
 
     py_Ref argv = py_isnil(p0 + 1) ? p0 + 2 : p0 + 1;
-    int argc2 = argv - p0;
 
     if(p0->type == tp_function) {
         /*****************_py_call*****************/
@@ -368,14 +369,21 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
                 if(!ok) return RES_ERROR;
                 // copy buffer back to stack
                 self->stack.sp = argv + co->nlocals;
-                for(int j = 0; j < co->nlocals; j++)
-                    argv[j] = self->__vectorcall_buffer[j];
-                break;
+                memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
+                // submit the call
+                if(!fn->cfunc) {
+                    pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
+                    return opcall ? RES_CALL : pk_VM__run_top_frame(self);
+                } else {
+                    bool ok = fn->cfunc(co->nlocals, argv);
+                    self->stack.sp = p0;
+                    return ok ? RES_RETURN : RES_ERROR;
+                }
             }
             case FuncType_SIMPLE:
-                if(argc2 != fn->decl->args.count) {
+                if(p1 - argv != fn->decl->args.count) {
                     const char* fmt = "%s() takes %d positional arguments but %d were given";
-                    TypeError(fmt, co->name, fn->decl->args.count, argc2);
+                    TypeError(fmt, co->name->data, fn->decl->args.count, p1 - argv);
                     return RES_ERROR;
                 }
                 if(kwargc) {
@@ -387,7 +395,9 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
                 self->stack.sp = argv + co->nlocals;
                 // initialize local variables to PY_NIL
                 memset(p1, 0, (char*)self->stack.sp - (char*)p1);
-                break;
+                // submit the call
+                pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
+                return opcall ? RES_CALL : pk_VM__run_top_frame(self);
             case FuncType_GENERATOR:
                 assert(false);
                 break;
@@ -400,11 +410,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
             default: c11__unreachedable();
         };
 
-        // simple or normal
-        Frame* frame = Frame__new(co, fn->module, p0, p0, argv, co);
-        pk_VM__push_frame(self, frame);
-        if(opcall) return RES_CALL;
-        return pk_VM__run_top_frame(self);
+        c11__unreachedable();
         /*****************_py_call*****************/
     }
 

+ 8 - 7
src/objects/codeobject.c

@@ -13,6 +13,13 @@ bool Bytecode__is_forward_jump(const Bytecode* self) {
     return self->op >= OP_JUMP_FORWARD && self->op <= OP_LOOP_BREAK;
 }
 
+static void FuncDecl__dtor(FuncDecl* self) {
+    CodeObject__dtor(&self->code);
+    c11_vector__dtor(&self->args);
+    c11_vector__dtor(&self->kwargs);
+    c11_smallmap_n2i__dtor(&self->kw_to_index);
+}
+
 FuncDecl_ FuncDecl__rcnew(pk_SourceData_ src, c11_sv name) {
     FuncDecl* self = malloc(sizeof(FuncDecl));
     self->rc.count = 1;
@@ -33,13 +40,6 @@ FuncDecl_ FuncDecl__rcnew(pk_SourceData_ src, c11_sv name) {
     return self;
 }
 
-void FuncDecl__dtor(FuncDecl* self) {
-    CodeObject__dtor(&self->code);
-    c11_vector__dtor(&self->args);
-    c11_vector__dtor(&self->kwargs);
-    c11_smallmap_n2i__dtor(&self->kw_to_index);
-}
-
 void FuncDecl__add_kwarg(FuncDecl* self, int index, uint16_t key, const py_TValue* value) {
     c11_smallmap_n2i__set(&self->kw_to_index, key, index);
     FuncDeclKwArg item = {index, key, *value};
@@ -99,6 +99,7 @@ void Function__ctor(Function* self, FuncDecl_ decl, PyObject* module) {
     self->module = module;
     self->clazz = NULL;
     self->closure = NULL;
+    self->cfunc = NULL;
 }
 
 void Function__dtor(Function* self) {

+ 21 - 0
src/public/modules.c

@@ -121,6 +121,25 @@ static bool _py_builtins__next(int argc, py_Ref argv) {
     return py_exception("StopIteration", "");
 }
 
+static bool _py_builtins__sorted(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(3);
+    // convert _0 to list object
+    if(!py_tpcall(tp_list, 1, argv)) return false;
+    py_Ref retval = py_pushtmp();
+    py_Ref sort = py_pushtmp();
+    py_Ref self = py_pushtmp();
+    py_Ref key = py_pushtmp();
+    py_Ref reverse = py_pushtmp();
+    *self = *retval = *py_retval();
+    bool ok = py_getunboundmethod(self, py_name("sort"), sort, self);
+    if(!ok) return false;
+    *key = argv[1];
+    *reverse = argv[2];
+    if(!py_vectorcall(2, 0)) return false;
+    *py_retval() = *retval;
+    return true;
+}
+
 py_TValue pk_builtins__register() {
     py_Ref builtins = py_newmodule("builtins", NULL);
     py_bindnativefunc(builtins, "repr", _py_builtins__repr);
@@ -129,6 +148,8 @@ py_TValue pk_builtins__register() {
     py_bindnativefunc(builtins, "hex", _py_builtins__hex);
     py_bindnativefunc(builtins, "iter", _py_builtins__iter);
     py_bindnativefunc(builtins, "next", _py_builtins__next);
+
+    py_bind(builtins, "sorted(iterable, key=None, reverse=False)", _py_builtins__sorted);
     return *builtins;
 }
 

+ 49 - 7
src/public/py_list.c

@@ -107,6 +107,16 @@ static bool _py_list__new__(int argc, py_Ref argv) {
         return true;
     }
     if(argc == 2) {
+        int length;
+        py_TValue* p = pk_arrayview(py_arg(1), &length);
+        if(p) {
+            py_newlistn(py_retval(), length);
+            for(int i = 0; i < length; i++) {
+                py_list__setitem(py_retval(), i, p + i);
+            }
+            return true;
+        }
+
         py_Ref iter = py_pushtmp();
         py_Ref list = py_pushtmp();
         if(!py_iter(py_arg(1))) return false;
@@ -274,11 +284,7 @@ static bool _py_list__index(int argc, py_Ref argv) {
 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);
-    }
+    c11__reverse(py_TValue, self);
     py_newnone(py_retval());
     return true;
 }
@@ -319,10 +325,44 @@ static bool _py_list__insert(int argc, py_Ref argv) {
     return true;
 }
 
+static int _py_lt_with_key(py_TValue* a, py_TValue* b, py_TValue* key) {
+    if(!key) return py_lt(a, b);
+    pk_VM* vm = pk_current_vm;
+    // project a
+    py_push(key);
+    py_pushnil();
+    py_push(a);
+    if(!py_vectorcall(1, 0)) return -1;
+    py_push(py_retval());
+    // project b
+    py_push(key);
+    py_pushnil();
+    py_push(b);
+    if(!py_vectorcall(1, 0)) return -1;
+    py_push(py_retval());
+    // binary op
+    bool ok = pk_stack_binaryop(vm, __lt__, __gt__);
+    if(!ok) return -1;
+    py_shrink(2);
+    return py_tobool(py_retval());
+}
+
+// sort(self, key=None, reverse=False)
 static bool _py_list__sort(int argc, py_Ref argv) {
-    PY_CHECK_ARGC(1);
     List* self = py_touserdata(py_arg(0));
-    c11__stable_sort(self->data, self->count, sizeof(py_TValue), (int (*)(const void*, const void*))py_lt);
+
+    py_Ref key = py_arg(1);
+    if(py_isnone(key)) key = NULL;
+
+    c11__stable_sort(self->data,
+                     self->count,
+                     sizeof(py_TValue),
+                     (int (*)(const void*, const void*, void*))_py_lt_with_key,
+                     key);
+
+    PY_CHECK_ARG_TYPE(2, tp_bool);
+    bool reverse = py_tobool(py_arg(2));
+    if(reverse) c11__reverse(py_TValue, self);
     py_newnone(py_retval());
     return true;
 }
@@ -355,5 +395,7 @@ py_Type pk_list__register() {
     py_bindmethod(type, "pop", _py_list__pop);
     py_bindmethod(type, "insert", _py_list__insert);
     py_bindmethod(type, "sort", _py_list__sort);
+
+    py_bind(py_tpobject(type), "sort(self, key=None, reverse=False)", _py_list__sort);
     return type;
 }

+ 30 - 6
src/public/values.c

@@ -5,6 +5,7 @@
 #include "pocketpy/common/utils.h"
 #include "pocketpy/objects/object.h"
 #include "pocketpy/interpreter/vm.h"
+#include "pocketpy/compiler/compiler.h"
 
 void py_newint(py_Ref out, int64_t val) {
     out->type = tp_int;
@@ -41,9 +42,8 @@ void py_newellipsis(py_Ref out) {
 
 void py_newnil(py_Ref out) { out->type = 0; }
 
-
 void py_newfunction(py_Ref out, py_CFunction f, const char* sig) {
-    py_newfunction2(out, f, sig, BindType_FUNCTION, NULL, NULL);
+    py_newfunction2(out, f, sig, BindType_FUNCTION, NULL, 0);
 }
 
 void py_newfunction2(py_Ref out,
@@ -51,7 +51,23 @@ void py_newfunction2(py_Ref out,
                      const char* sig,
                      enum BindType bt,
                      const char* docstring,
-                     const py_Ref upvalue) {}
+                     int slots) {
+    char buffer[256];
+    snprintf(buffer, sizeof(buffer), "def %s: pass", sig);
+    // fn(a, b, *c, d=1) -> None
+    CodeObject code;
+    pk_SourceData_ source = pk_SourceData__rcnew(buffer, "<bind>", EXEC_MODE, false);
+    Error* err = pk_compile(source, &code);
+    if(err) abort();
+    if(code.func_decls.count != 1) abort();
+    FuncDecl_ decl = c11__getitem(FuncDecl_, &code.func_decls, 0);
+    // construct the function
+    Function* ud = py_newobject(out, tp_function, slots, sizeof(Function));
+    Function__ctor(ud, decl, NULL);
+    ud->cfunc = f;
+    CodeObject__dtor(&code);
+    PK_DECREF(source);
+}
 
 void py_newnativefunc(py_Ref out, py_CFunction f) {
     out->type = tp_nativefunc;
@@ -59,22 +75,30 @@ void py_newnativefunc(py_Ref out, py_CFunction f) {
     out->_cfunc = f;
 }
 
-void py_bindmethod(py_Type type, const char *name, py_CFunction f){
+void py_bindmethod(py_Type type, const char* name, py_CFunction f) {
     py_bindmethod2(type, name, f, BindType_FUNCTION);
 }
 
-void py_bindmethod2(py_Type type, const char *name, py_CFunction f, enum BindType bt){
+void py_bindmethod2(py_Type type, const char* name, py_CFunction f, enum BindType bt) {
     py_TValue tmp;
     py_newnativefunc(&tmp, f);
     py_setdict(py_tpobject(type), py_name(name), &tmp);
 }
 
-void py_bindnativefunc(py_Ref obj, const char *name, py_CFunction f){
+void py_bindnativefunc(py_Ref obj, const char* name, py_CFunction f) {
     py_TValue tmp;
     py_newnativefunc(&tmp, f);
     py_setdict(obj, py_name(name), &tmp);
 }
 
+void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
+    py_TValue tmp;
+    py_newfunction(&tmp, f, sig);
+    Function* ud = py_touserdata(&tmp);
+    py_Name name = py_name(ud->decl->code.name->data);
+    py_setdict(obj, name, &tmp);
+}
+
 void py_newslice(py_Ref out, const py_Ref start, const py_Ref stop, const py_Ref step) {
     py_newobject(out, tp_slice, 3, 0);
     py_setslot(out, 0, start);

+ 1 - 1
src/public/vm.c

@@ -219,7 +219,7 @@ bool py_callmethod(py_Ref self, py_Name name, int argc, py_Ref argv) { return -1
 
 bool py_vectorcall(uint16_t argc, uint16_t kwargc) {
     pk_VM* vm = pk_current_vm;
-    return pk_VM__vectorcall(vm, argc, kwargc, false) == RES_ERROR;
+    return pk_VM__vectorcall(vm, argc, kwargc, false) != RES_ERROR;
 }
 
 py_Ref py_retval() { return &pk_current_vm->last_retval; }

+ 36 - 8
tests/05_list.py

@@ -98,23 +98,51 @@ a = [0, 0, 0, 0, 1, 1, 3, -1]
 assert a.sort() == None
 assert a == [-1, 0, 0, 0, 0, 1, 1, 3]
 
+a = [3, 2, 2, 1]
+a.sort()
+assert a == [1, 2, 2, 3]
+
+# test reverse
+a = [3, 2, 2, 1]
+a.sort(reverse=True)
+assert a == [3, 2, 2, 1]
+
+a = [1, 3, 2, 2]
+a.sort(reverse=True)
+assert a == [3, 2, 2, 1]
+
+# test key
+key = lambda x: -x
+assert key(1) == -1
+a = [1, 3, 2, 2]
+a.sort(key=key)
+assert a == [3, 2, 2, 1]
+
+a = [1, 3, 2, 2]
+a.sort(key=key, reverse=True)
+assert a == [1, 2, 2, 3]
+
 # test sorted
+a = [8, 2, 4, 2, 9]
 assert sorted(a) == [2, 2, 4, 8, 9]
 assert sorted(a, reverse=True) == [9, 8, 4, 2, 2]
 
-assert sorted(a, key=lambda x:-x, reverse=True) == [2, 2, 4, 8, 9]
+def key(x): return -x;
+assert sorted(a, key=key) == [9, 8, 4, 2, 2]
+
+assert sorted(a, key=key, reverse=True) == [2, 2, 4, 8, 9]
 assert a == [8, 2, 4, 2, 9]
 
-b = [(1, 2), (3, 3), (5, 1)]
-b.sort(key=lambda x:x[1])
-assert b == [(5, 1), (1, 2), (3,3)]
+# b = [(1, 2), (3, 3), (5, 1)]
+# b.sort(key=lambda x:x[1])
+# assert b == [(5, 1), (1, 2), (3,3)]
 
 # test cyclic reference
-a = []
-a.append(0)
-a.append([1, 2, a])
+# a = []
+# a.append(0)
+# a.append([1, 2, a])
 
-assert repr(a) == "[0, [1, 2, [...]]]"
+# assert repr(a) == "[0, [1, 2, [...]]]"
 
 # try:
 #     a.index(1, 1)