Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
77757571
Commit
77757571
authored
Jan 07, 2014
by
Damien George
Browse files
Merge pull request #105 from chipaca/listsort
A more python-style list.sort. And keyword arguments.
parents
1e40840b
3391e190
Changes
6
Hide whitespace changes
Inline
Side-by-side
py/obj.h
View file @
77757571
...
@@ -42,13 +42,17 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
...
@@ -42,13 +42,17 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_native_t obj_name
#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_native_t obj_name
#define MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, n_args_max, (void *)fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, is_kw, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, is_kw, n_args_min, n_args_max, (void *)fun_name}
#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 0, 0, (mp_fun_0_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 0, 0, (mp_fun_0_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 1, 1, (mp_fun_1_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 1, 1, (mp_fun_1_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 2, 2, (mp_fun_2_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 2, 2, (mp_fun_2_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 3, 3, (mp_fun_3_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 3, 3, (mp_fun_3_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, 0, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
// Need to declare this here so we are not dependent on map.h
struct
_mp_map_t
;
// Type definitions for methods
// Type definitions for methods
...
@@ -58,10 +62,12 @@ typedef mp_obj_t (*mp_fun_2_t)(mp_obj_t, mp_obj_t);
...
@@ -58,10 +62,12 @@ typedef mp_obj_t (*mp_fun_2_t)(mp_obj_t, mp_obj_t);
typedef
mp_obj_t
(
*
mp_fun_3_t
)(
mp_obj_t
,
mp_obj_t
,
mp_obj_t
);
typedef
mp_obj_t
(
*
mp_fun_3_t
)(
mp_obj_t
,
mp_obj_t
,
mp_obj_t
);
typedef
mp_obj_t
(
*
mp_fun_t
)(
void
);
typedef
mp_obj_t
(
*
mp_fun_t
)(
void
);
typedef
mp_obj_t
(
*
mp_fun_var_t
)(
int
n
,
const
mp_obj_t
*
);
typedef
mp_obj_t
(
*
mp_fun_var_t
)(
int
n
,
const
mp_obj_t
*
);
typedef
mp_obj_t
(
*
mp_fun_kw_t
)(
mp_obj_t
*
,
struct
_mp_map_t
*
);
typedef
void
(
*
mp_print_fun_t
)(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o
);
typedef
void
(
*
mp_print_fun_t
)(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o
);
typedef
mp_obj_t
(
*
mp_make_new_fun_t
)(
mp_obj_t
type_in
,
int
n_args
,
const
mp_obj_t
*
args
);
// args are in reverse order in the array
typedef
mp_obj_t
(
*
mp_make_new_fun_t
)(
mp_obj_t
type_in
,
int
n_args
,
const
mp_obj_t
*
args
);
// args are in reverse order in the array
typedef
mp_obj_t
(
*
mp_call_n_fun_t
)(
mp_obj_t
fun
,
int
n_args
,
const
mp_obj_t
*
args
);
// args are in reverse order in the array
typedef
mp_obj_t
(
*
mp_call_n_fun_t
)(
mp_obj_t
fun
,
int
n_args
,
const
mp_obj_t
*
args
);
// args are in reverse order in the array
typedef
mp_obj_t
(
*
mp_call_n_kw_fun_t
)(
mp_obj_t
fun
,
int
n_args
,
int
n_kw
,
const
mp_obj_t
*
args
);
// args are in reverse order in the array
typedef
mp_obj_t
(
*
mp_unary_op_fun_t
)(
int
op
,
mp_obj_t
);
typedef
mp_obj_t
(
*
mp_unary_op_fun_t
)(
int
op
,
mp_obj_t
);
typedef
mp_obj_t
(
*
mp_binary_op_fun_t
)(
int
op
,
mp_obj_t
,
mp_obj_t
);
typedef
mp_obj_t
(
*
mp_binary_op_fun_t
)(
int
op
,
mp_obj_t
,
mp_obj_t
);
...
@@ -77,6 +83,7 @@ struct _mp_obj_type_t {
...
@@ -77,6 +83,7 @@ struct _mp_obj_type_t {
mp_make_new_fun_t
make_new
;
// to make an instance of the type
mp_make_new_fun_t
make_new
;
// to make an instance of the type
mp_call_n_fun_t
call_n
;
mp_call_n_fun_t
call_n
;
mp_call_n_kw_fun_t
call_n_kw
;
mp_unary_op_fun_t
unary_op
;
// can return NULL if op not supported
mp_unary_op_fun_t
unary_op
;
// can return NULL if op not supported
mp_binary_op_fun_t
binary_op
;
// can return NULL if op not supported
mp_binary_op_fun_t
binary_op
;
// can return NULL if op not supported
...
@@ -120,10 +127,6 @@ extern const mp_obj_t mp_const_empty_tuple;
...
@@ -120,10 +127,6 @@ extern const mp_obj_t mp_const_empty_tuple;
extern
const
mp_obj_t
mp_const_ellipsis
;
extern
const
mp_obj_t
mp_const_ellipsis
;
extern
const
mp_obj_t
mp_const_stop_iteration
;
// special object indicating end of iteration (not StopIteration exception!)
extern
const
mp_obj_t
mp_const_stop_iteration
;
// special object indicating end of iteration (not StopIteration exception!)
// Need to declare this here so we are not dependent on map.h
struct
_mp_map_t
;
// General API for objects
// General API for objects
mp_obj_t
mp_obj_new_none
(
void
);
mp_obj_t
mp_obj_new_none
(
void
);
...
@@ -146,8 +149,8 @@ mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun);
...
@@ -146,8 +149,8 @@ mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun);
mp_obj_t
mp_obj_new_gen_wrap
(
uint
n_locals
,
uint
n_stack
,
mp_obj_t
fun
);
mp_obj_t
mp_obj_new_gen_wrap
(
uint
n_locals
,
uint
n_stack
,
mp_obj_t
fun
);
mp_obj_t
mp_obj_new_gen_instance
(
const
byte
*
bytecode
,
uint
n_state
,
int
n_args
,
const
mp_obj_t
*
args
);
mp_obj_t
mp_obj_new_gen_instance
(
const
byte
*
bytecode
,
uint
n_state
,
int
n_args
,
const
mp_obj_t
*
args
);
mp_obj_t
mp_obj_new_closure
(
mp_obj_t
fun
,
mp_obj_t
closure_tuple
);
mp_obj_t
mp_obj_new_closure
(
mp_obj_t
fun
,
mp_obj_t
closure_tuple
);
mp_obj_t
mp_obj_new_tuple
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_tuple
(
uint
n
,
const
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_tuple_reverse
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_tuple_reverse
(
uint
n
,
const
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_list
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_list
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_list_reverse
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_list_reverse
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_dict
(
int
n_args
);
mp_obj_t
mp_obj_new_dict
(
int
n_args
);
...
@@ -236,7 +239,8 @@ void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *sto
...
@@ -236,7 +239,8 @@ void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *sto
// functions
// functions
typedef
struct
_mp_obj_fun_native_t
{
// need this so we can define const objects (to go in ROM)
typedef
struct
_mp_obj_fun_native_t
{
// need this so we can define const objects (to go in ROM)
mp_obj_base_t
base
;
mp_obj_base_t
base
;
machine_uint_t
n_args_min
;
// inclusive
bool
is_kw
:
1
;
machine_uint_t
n_args_min
:
(
sizeof
(
machine_uint_t
)
-
1
);
// inclusive
machine_uint_t
n_args_max
;
// inclusive
machine_uint_t
n_args_max
;
// inclusive
void
*
fun
;
void
*
fun
;
// TODO add mp_map_t *globals
// TODO add mp_map_t *globals
...
...
py/objfun.c
View file @
77757571
...
@@ -17,9 +17,13 @@
...
@@ -17,9 +17,13 @@
// mp_obj_fun_native_t defined in obj.h
// mp_obj_fun_native_t defined in obj.h
mp_obj_t
fun_native_call_n_kw
(
mp_obj_t
self_in
,
int
n_args
,
int
n_kw
,
const
mp_obj_t
*
args
);
// args are in reverse order in the array
// args are in reverse order in the array
mp_obj_t
fun_native_call_n
(
mp_obj_t
self_in
,
int
n_args
,
const
mp_obj_t
*
args
)
{
mp_obj_t
fun_native_call_n
(
mp_obj_t
self_in
,
int
n_args
,
const
mp_obj_t
*
args
)
{
mp_obj_fun_native_t
*
self
=
self_in
;
mp_obj_fun_native_t
*
self
=
self_in
;
if
(
self
->
is_kw
)
{
return
fun_native_call_n_kw
(
self_in
,
n_args
,
0
,
args
);
}
if
(
self
->
n_args_min
==
self
->
n_args_max
)
{
if
(
self
->
n_args_min
==
self
->
n_args_max
)
{
// function requires a fixed number of arguments
// function requires a fixed number of arguments
...
@@ -69,10 +73,29 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
...
@@ -69,10 +73,29 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
}
}
}
}
mp_obj_t
fun_native_call_n_kw
(
mp_obj_t
self_in
,
int
n_args
,
int
n_kw
,
const
mp_obj_t
*
args
)
{
mp_obj_fun_native_t
*
self
=
self_in
;
if
(
!
self
->
is_kw
)
{
nlr_jump
(
mp_obj_new_exception_msg
(
MP_QSTR_TypeError
,
"function does not take keyword arguments"
));
}
mp_obj_t
*
vargs
=
mp_obj_new_tuple_reverse
(
n_args
,
args
+
2
*
n_kw
);
mp_map_t
*
kw_args
=
mp_map_new
(
MP_MAP_QSTR
,
n_kw
);
for
(
int
i
=
0
;
i
<
2
*
n_kw
;
i
+=
2
)
{
qstr
name
=
mp_obj_str_get
(
args
[
i
+
1
]);
mp_qstr_map_lookup
(
kw_args
,
name
,
true
)
->
value
=
args
[
i
];
}
mp_obj_t
res
=
((
mp_fun_kw_t
)
self
->
fun
)(
vargs
,
kw_args
);
/* TODO clean up vargs and kw_args */
return
res
;
}
const
mp_obj_type_t
fun_native_type
=
{
const
mp_obj_type_t
fun_native_type
=
{
{
&
mp_const_type
},
{
&
mp_const_type
},
"function"
,
"function"
,
.
call_n
=
fun_native_call_n
,
.
call_n
=
fun_native_call_n
,
.
call_n_kw
=
fun_native_call_n_kw
,
};
};
mp_obj_t
rt_make_function_0
(
mp_fun_0_t
fun
)
{
mp_obj_t
rt_make_function_0
(
mp_fun_0_t
fun
)
{
...
...
py/objlist.c
View file @
77757571
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
#include
"mpconfig.h"
#include
"mpconfig.h"
#include
"mpqstr.h"
#include
"mpqstr.h"
#include
"obj.h"
#include
"obj.h"
#include
"map.h"
#include
"runtime0.h"
#include
"runtime0.h"
#include
"runtime.h"
#include
"runtime.h"
...
@@ -120,14 +121,15 @@ static mp_obj_t list_pop(int n_args, const mp_obj_t *args) {
...
@@ -120,14 +121,15 @@ static mp_obj_t list_pop(int n_args, const mp_obj_t *args) {
}
}
// TODO make this conform to CPython's definition of sort
// TODO make this conform to CPython's definition of sort
static
void
mp_quicksort
(
mp_obj_t
*
head
,
mp_obj_t
*
tail
,
mp_obj_t
key_fn
)
{
static
void
mp_quicksort
(
mp_obj_t
*
head
,
mp_obj_t
*
tail
,
mp_obj_t
key_fn
,
bool
reversed
)
{
int
op
=
reversed
?
RT_COMPARE_OP_MORE
:
RT_COMPARE_OP_LESS
;
while
(
head
<
tail
)
{
while
(
head
<
tail
)
{
mp_obj_t
*
h
=
head
-
1
;
mp_obj_t
*
h
=
head
-
1
;
mp_obj_t
*
t
=
tail
;
mp_obj_t
*
t
=
tail
;
mp_obj_t
v
=
rt_call_function_1
(
key_fn
,
tail
[
0
]);
// get pivot using key_fn
mp_obj_t
v
=
key_fn
==
NULL
?
tail
[
0
]
:
rt_call_function_1
(
key_fn
,
tail
[
0
]);
// get pivot using key_fn
for
(;;)
{
for
(;;)
{
do
++
h
;
while
(
rt_compare_op
(
RT_COMPARE_OP_LESS
,
rt_call_function_1
(
key_fn
,
h
[
0
]),
v
)
==
mp_const_true
);
do
++
h
;
while
(
rt_compare_op
(
op
,
key_fn
==
NULL
?
h
[
0
]
:
rt_call_function_1
(
key_fn
,
h
[
0
]),
v
)
==
mp_const_true
);
do
--
t
;
while
(
h
<
t
&&
rt_compare_op
(
RT_COMPARE_OP_LESS
,
v
,
rt_call_function_1
(
key_fn
,
t
[
0
]))
==
mp_const_true
);
do
--
t
;
while
(
h
<
t
&&
rt_compare_op
(
op
,
v
,
key_fn
==
NULL
?
t
[
0
]
:
rt_call_function_1
(
key_fn
,
t
[
0
]))
==
mp_const_true
);
if
(
h
>=
t
)
break
;
if
(
h
>=
t
)
break
;
mp_obj_t
x
=
h
[
0
];
mp_obj_t
x
=
h
[
0
];
h
[
0
]
=
t
[
0
];
h
[
0
]
=
t
[
0
];
...
@@ -136,16 +138,31 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn) {
...
@@ -136,16 +138,31 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn) {
mp_obj_t
x
=
h
[
0
];
mp_obj_t
x
=
h
[
0
];
h
[
0
]
=
tail
[
0
];
h
[
0
]
=
tail
[
0
];
tail
[
0
]
=
x
;
tail
[
0
]
=
x
;
mp_quicksort
(
head
,
t
,
key_fn
);
mp_quicksort
(
head
,
t
,
key_fn
,
reversed
);
head
=
h
+
1
;
head
=
h
+
1
;
}
}
}
}
static
mp_obj_t
list_sort
(
mp_obj_t
self_in
,
mp_obj_t
key_fn
)
{
static
mp_obj_t
list_sort
(
mp_obj_t
*
args
,
mp_map_t
*
kwargs
)
{
assert
(
MP_OBJ_IS_TYPE
(
self_in
,
&
list_type
));
mp_obj_t
*
args_items
=
NULL
;
mp_obj_list_t
*
self
=
self_in
;
machine_uint_t
args_len
=
0
;
qstr
key_idx
=
qstr_from_str_static
(
"key"
);
qstr
reverse_idx
=
qstr_from_str_static
(
"reverse"
);
assert
(
MP_OBJ_IS_TYPE
(
args
,
&
tuple_type
));
mp_obj_tuple_get
(
args
,
&
args_len
,
&
args_items
);
assert
(
args_len
>=
1
);
if
(
args_len
>
1
)
{
nlr_jump
(
mp_obj_new_exception_msg
(
MP_QSTR_TypeError
,
"list.sort takes no positional arguments"
));
}
mp_obj_list_t
*
self
=
args_items
[
0
];
if
(
self
->
len
>
1
)
{
if
(
self
->
len
>
1
)
{
mp_quicksort
(
self
->
items
,
self
->
items
+
self
->
len
-
1
,
key_fn
);
mp_map_elem_t
*
keyfun
=
mp_qstr_map_lookup
(
kwargs
,
key_idx
,
false
);
mp_map_elem_t
*
reverse
=
mp_qstr_map_lookup
(
kwargs
,
reverse_idx
,
false
);
mp_quicksort
(
self
->
items
,
self
->
items
+
self
->
len
-
1
,
keyfun
?
keyfun
->
value
:
NULL
,
reverse
&&
reverse
->
value
?
rt_is_true
(
reverse
->
value
)
:
false
);
}
}
return
mp_const_none
;
// return None, as per CPython
return
mp_const_none
;
// return None, as per CPython
}
}
...
@@ -259,7 +276,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(list_insert_obj, list_insert);
...
@@ -259,7 +276,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(list_insert_obj, list_insert);
static
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
list_pop_obj
,
1
,
2
,
list_pop
);
static
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
list_pop_obj
,
1
,
2
,
list_pop
);
static
MP_DEFINE_CONST_FUN_OBJ_2
(
list_remove_obj
,
list_remove
);
static
MP_DEFINE_CONST_FUN_OBJ_2
(
list_remove_obj
,
list_remove
);
static
MP_DEFINE_CONST_FUN_OBJ_1
(
list_reverse_obj
,
list_reverse
);
static
MP_DEFINE_CONST_FUN_OBJ_1
(
list_reverse_obj
,
list_reverse
);
static
MP_DEFINE_CONST_FUN_OBJ_
2
(
list_sort_obj
,
list_sort
);
static
MP_DEFINE_CONST_FUN_OBJ_
KW
(
list_sort_obj
,
list_sort
);
static
const
mp_method_t
list_type_methods
[]
=
{
static
const
mp_method_t
list_type_methods
[]
=
{
{
"append"
,
&
list_append_obj
},
{
"append"
,
&
list_append_obj
},
...
...
py/objtuple.c
View file @
77757571
...
@@ -109,7 +109,7 @@ const mp_obj_type_t tuple_type = {
...
@@ -109,7 +109,7 @@ const mp_obj_type_t tuple_type = {
static
const
mp_obj_tuple_t
empty_tuple_obj
=
{{
&
tuple_type
},
0
};
static
const
mp_obj_tuple_t
empty_tuple_obj
=
{{
&
tuple_type
},
0
};
const
mp_obj_t
mp_const_empty_tuple
=
(
mp_obj_t
)
&
empty_tuple_obj
;
const
mp_obj_t
mp_const_empty_tuple
=
(
mp_obj_t
)
&
empty_tuple_obj
;
mp_obj_t
mp_obj_new_tuple
(
uint
n
,
mp_obj_t
*
items
)
{
mp_obj_t
mp_obj_new_tuple
(
uint
n
,
const
mp_obj_t
*
items
)
{
if
(
n
==
0
)
{
if
(
n
==
0
)
{
return
mp_const_empty_tuple
;
return
mp_const_empty_tuple
;
}
}
...
@@ -122,7 +122,7 @@ mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items) {
...
@@ -122,7 +122,7 @@ mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items) {
return
o
;
return
o
;
}
}
mp_obj_t
mp_obj_new_tuple_reverse
(
uint
n
,
mp_obj_t
*
items
)
{
mp_obj_t
mp_obj_new_tuple_reverse
(
uint
n
,
const
mp_obj_t
*
items
)
{
if
(
n
==
0
)
{
if
(
n
==
0
)
{
return
mp_const_empty_tuple
;
return
mp_const_empty_tuple
;
}
}
...
...
py/runtime.c
View file @
77757571
...
@@ -689,10 +689,20 @@ mp_obj_t rt_call_function_n(mp_obj_t fun_in, int n_args, const mp_obj_t *args) {
...
@@ -689,10 +689,20 @@ mp_obj_t rt_call_function_n(mp_obj_t fun_in, int n_args, const mp_obj_t *args) {
// args are in reverse order in the array; keyword arguments come first, value then key
// args are in reverse order in the array; keyword arguments come first, value then key
// eg: (value1, key1, value0, key0, arg1, arg0)
// eg: (value1, key1, value0, key0, arg1, arg0)
mp_obj_t
rt_call_function_n_kw
(
mp_obj_t
fun
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
mp_obj_t
rt_call_function_n_kw
(
mp_obj_t
fun_in
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
// TODO
// TODO merge this and _n into a single, smarter thing
assert
(
0
);
DEBUG_OP_printf
(
"calling function %p(n_args=%d, n_kw=%d, args=%p)
\n
"
,
fun_in
,
n_args
,
n_kw
,
args
);
return
mp_const_none
;
if
(
MP_OBJ_IS_SMALL_INT
(
fun_in
))
{
nlr_jump
(
mp_obj_new_exception_msg
(
MP_QSTR_TypeError
,
"'int' object is not callable"
));
}
else
{
mp_obj_base_t
*
fun
=
fun_in
;
if
(
fun
->
type
->
call_n_kw
!=
NULL
)
{
return
fun
->
type
->
call_n_kw
(
fun_in
,
n_args
,
n_kw
,
args
);
}
else
{
nlr_jump
(
mp_obj_new_exception_msg_1_arg
(
MP_QSTR_TypeError
,
"'%s' object is not callable"
,
fun
->
type
->
name
));
}
}
}
}
// args contains: arg(n_args-1) arg(n_args-2) ... arg(0) self/NULL fun
// args contains: arg(n_args-1) arg(n_args-2) ... arg(0) self/NULL fun
...
...
tests/basics/tests/list_sort.py
0 → 100644
View file @
77757571
l
=
[
1
,
3
,
2
,
5
]
print
(
l
)
l
.
sort
()
print
(
l
)
l
.
sort
(
key
=
lambda
x
:
-
x
)
print
(
l
)
l
.
sort
(
key
=
lambda
x
:
-
x
,
reverse
=
True
)
print
(
l
)
l
.
sort
(
reverse
=
True
)
print
(
l
)
l
.
sort
(
reverse
=
False
)
print
(
l
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment