summaryrefslogtreecommitdiffstatshomepage
path: root/py/objfun.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/objfun.c')
-rw-r--r--py/objfun.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/py/objfun.c b/py/objfun.c
index 0db6459a39..3697c64303 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -17,9 +17,13 @@
// 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
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;
+ 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) {
// function requires a fixed number of arguments
@@ -69,16 +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 = {
- { &mp_const_type },
- "function",
- NULL, // print
- NULL, // make_new
- fun_native_call_n, // call_n
- NULL, // unary_op
- NULL, // binary_op
- NULL, // getiter
- NULL, // iternext
+ .base = { &mp_const_type },
+ .name = "function",
+ .call_n = fun_native_call_n,
+ .call_n_kw = fun_native_call_n_kw,
.methods = {
{NULL, NULL}, // end-of-list sentinel
},
@@ -172,15 +189,9 @@ mp_obj_t fun_bc_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
}
const mp_obj_type_t fun_bc_type = {
- { &mp_const_type },
- "function",
- NULL, // print
- NULL, // make_new
- fun_bc_call_n, // call_n
- NULL, // unary_op
- NULL, // binary_op
- NULL, // getiter
- NULL, // iternext
+ .base = { &mp_const_type },
+ .name = "function",
+ .call_n = fun_bc_call_n,
.methods = {
{NULL, NULL}, // end-of-list sentinel
},
@@ -286,15 +297,9 @@ mp_obj_t fun_asm_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
}
static const mp_obj_type_t fun_asm_type = {
- { &mp_const_type },
- "function",
- NULL, // print
- NULL, // make_new
- fun_asm_call_n, // call_n
- NULL, // unary_op
- NULL, // binary_op
- NULL, // getiter
- NULL, // iternext
+ .base = { &mp_const_type },
+ .name = "function",
+ .call_n = fun_asm_call_n,
.methods = {
{NULL, NULL}, // end-of-list sentinel
},