diff options
author | Damien George <damien.p.george@gmail.com> | 2013-12-30 22:32:17 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2013-12-30 22:32:17 +0000 |
commit | 6baf76e28b17055fc6e5a6c9560e756d32eaad5d (patch) | |
tree | f4245858b6755d6731a7ec6c9f0a6fc49901eb5b /py/objclosure.c | |
parent | 8cc96a35e532ef999e5a3739deeb44f51a80744b (diff) | |
download | micropython-6baf76e28b17055fc6e5a6c9560e756d32eaad5d.tar.gz micropython-6baf76e28b17055fc6e5a6c9560e756d32eaad5d.zip |
py: make closures work.
Diffstat (limited to 'py/objclosure.c')
-rw-r--r-- | py/objclosure.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/py/objclosure.c b/py/objclosure.c index e699c5daaa..e3354d42d9 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <stdint.h> +#include <string.h> #include <assert.h> #include "nlr.h" @@ -11,14 +12,31 @@ typedef struct _mp_obj_closure_t { mp_obj_base_t base; mp_obj_t fun; - mp_obj_t vars; + uint n_closed; + mp_obj_t *closed; } mp_obj_closure_t; +// args are in reverse order in the array +mp_obj_t closure_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + mp_obj_closure_t *self = self_in; + + // concatenate args and closed-over-vars, in reverse order + // TODO perhaps cache this array so we don't need to create it each time we are called + mp_obj_t *args2 = m_new(mp_obj_t, self->n_closed + n_args); + memcpy(args2, args, n_args * sizeof(mp_obj_t)); + for (int i = 0; i < self->n_closed; i++) { + args2[n_args + i] = self->closed[self->n_closed - 1 - i]; + } + + // call the function with the new vars array + return rt_call_function_n(self->fun, n_args + self->n_closed, args2); +} + const mp_obj_type_t closure_type = { { &mp_const_type }, "closure", NULL, // print - NULL, // call_n + closure_call_n, // call_n NULL, // unary_op NULL, // binary_op NULL, // getiter @@ -30,6 +48,6 @@ mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple) { mp_obj_closure_t *o = m_new_obj(mp_obj_closure_t); o->base.type = &closure_type; o->fun = fun; - o->vars = closure_tuple; + mp_obj_tuple_get(closure_tuple, &o->n_closed, &o->closed); return o; } |