summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-02-16 00:17:42 +0000
committerDamien George <damien.p.george@gmail.com>2014-02-16 00:17:42 +0000
commite5d371b5456020240d4c54dd8f7d8e938074ebd7 (patch)
treeb48dccf008a694f479d51d9159449ce1b91c8fbb /py
parent2e482cdb7b1e457053edcb8585414ecd1eba2cdc (diff)
downloadmicropython-e5d371b5456020240d4c54dd8f7d8e938074ebd7.tar.gz
micropython-e5d371b5456020240d4c54dd8f7d8e938074ebd7.zip
py: Pass keyword arguments to byte code.
Diffstat (limited to 'py')
-rw-r--r--py/objfun.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/py/objfun.c b/py/objfun.c
index 73fd751a0d..b2837be5f0 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -141,15 +141,18 @@ typedef struct _mp_obj_fun_bc_t {
};
uint n_state; // total state size for the executing function (incl args, locals, stack)
const byte *bytecode; // bytecode for the function
- mp_obj_t extra_args[]; // values of default args (if any), plus a slot at the end for var args (if it takes them)
+ mp_obj_t extra_args[]; // values of default args (if any), plus a slot at the end for var args and/or kw args (if it takes them)
} mp_obj_fun_bc_t;
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
mp_obj_fun_bc_t *self = self_in;
+ const mp_obj_t *kwargs = args + n_args;
mp_obj_t *extra_args = self->extra_args + self->n_def_args;
uint n_extra_args = 0;
+ // check positional arguments
+
if (n_args > self->n_args) {
// given more than enough arguments
if (!self->takes_var_args) {
@@ -171,8 +174,25 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
goto arg_error;
}
+ // check keyword arguments
+
if (n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
+ // keyword arguments given
+ if (!self->takes_kw_args) {
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
+ }
+ mp_obj_t dict = mp_obj_new_dict(n_kw);
+ for (uint i = 0; i < n_kw; i++) {
+ mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
+ }
+ extra_args[n_extra_args] = dict;
+ n_extra_args += 1;
+ } else {
+ // no keyword arguments given
+ if (self->takes_kw_args) {
+ extra_args[n_extra_args] = mp_obj_new_dict(0);
+ n_extra_args += 1;
+ }
}
mp_map_t *old_globals = rt_globals_get();
@@ -208,6 +228,9 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, uint n_args, mp_obj_t def_args_in,
if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) {
n_extra_args += 1;
}
+ if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
+ n_extra_args += 1;
+ }
mp_obj_fun_bc_t *o = m_new_obj_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args);
o->base.type = &fun_bc_type;
o->globals = rt_globals_get();