blob: f7508b204021589810800246626879342e665767 [file] [log] [blame]
John R. Lenton39b174e2014-01-15 01:10:09 +00001#include <stdlib.h>
2#include <assert.h>
3
Damien George7a9d0c42014-01-15 22:27:16 +00004#include "nlr.h"
John R. Lenton39b174e2014-01-15 01:10:09 +00005#include "misc.h"
6#include "mpconfig.h"
Damien George55baff42014-01-21 21:40:13 +00007#include "qstr.h"
John R. Lenton39b174e2014-01-15 01:10:09 +00008#include "obj.h"
9#include "runtime.h"
10
11typedef struct _mp_obj_map_t {
12 mp_obj_base_t base;
13 machine_uint_t n_iters;
14 mp_obj_t fun;
15 mp_obj_t iters[];
16} mp_obj_map_t;
17
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020018STATIC mp_obj_t map_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
Damien George20006db2014-01-18 14:10:48 +000019 if (n_args < 2 || n_kw != 0) {
20 nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "map must have at least 2 arguments and no keyword arguments"));
Damien George7a9d0c42014-01-15 22:27:16 +000021 }
John R. Lenton39b174e2014-01-15 01:10:09 +000022 assert(n_args >= 2);
Damien George7a9d0c42014-01-15 22:27:16 +000023 mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1);
John R. Lenton39b174e2014-01-15 01:10:09 +000024 o->base.type = &map_type;
25 o->n_iters = n_args - 1;
Damien George20006db2014-01-18 14:10:48 +000026 o->fun = args[0];
John R. Lenton39b174e2014-01-15 01:10:09 +000027 for (int i = 0; i < n_args - 1; i++) {
Damien George20006db2014-01-18 14:10:48 +000028 o->iters[i] = rt_getiter(args[i + 1]);
John R. Lenton39b174e2014-01-15 01:10:09 +000029 }
30 return o;
31}
32
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020033STATIC mp_obj_t map_getiter(mp_obj_t self_in) {
John R. Lenton39b174e2014-01-15 01:10:09 +000034 return self_in;
35}
36
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020037STATIC mp_obj_t map_iternext(mp_obj_t self_in) {
John R. Lenton39b174e2014-01-15 01:10:09 +000038 assert(MP_OBJ_IS_TYPE(self_in, &map_type));
39 mp_obj_map_t *self = self_in;
40 mp_obj_t *nextses = m_new(mp_obj_t, self->n_iters);
41
42 for (int i = 0; i < self->n_iters; i++) {
43 mp_obj_t next = rt_iternext(self->iters[i]);
44 if (next == mp_const_stop_iteration) {
45 m_del(mp_obj_t, nextses, self->n_iters);
46 return mp_const_stop_iteration;
47 }
48 nextses[i] = next;
49 }
Damien George20006db2014-01-18 14:10:48 +000050 return rt_call_function_n_kw(self->fun, self->n_iters, 0, nextses);
John R. Lenton39b174e2014-01-15 01:10:09 +000051}
52
53const mp_obj_type_t map_type = {
54 { &mp_const_type },
55 "map",
56 .make_new = map_make_new,
57 .getiter = map_getiter,
58 .iternext = map_iternext,
59};