blob: 42bcc436f5c315a6c620165349fba748aa3a17a8 [file] [log] [blame]
Damien George66eaf842014-03-26 19:27:58 +00001#include <stdlib.h>
John R. Lenton39b174e2014-01-15 01:10:09 +00002#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) {
Damien Georgeea13f402014-04-05 18:32:08 +010020 nlr_raise(mp_obj_new_exception_msg(&mp_type_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);
Damien George3e1a5c12014-03-29 13:43:38 +000024 o->base.type = &mp_type_map;
John R. Lenton39b174e2014-01-15 01:10:09 +000025 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 Georged17926d2014-03-30 13:35:08 +010028 o->iters[i] = mp_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) {
Damien George3e1a5c12014-03-29 13:43:38 +000038 assert(MP_OBJ_IS_TYPE(self_in, &mp_type_map));
John R. Lenton39b174e2014-01-15 01:10:09 +000039 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++) {
Damien Georged17926d2014-03-30 13:35:08 +010043 mp_obj_t next = mp_iternext(self->iters[i]);
Damien George66eaf842014-03-26 19:27:58 +000044 if (next == MP_OBJ_NULL) {
John R. Lenton39b174e2014-01-15 01:10:09 +000045 m_del(mp_obj_t, nextses, self->n_iters);
Damien George66eaf842014-03-26 19:27:58 +000046 return MP_OBJ_NULL;
John R. Lenton39b174e2014-01-15 01:10:09 +000047 }
48 nextses[i] = next;
49 }
Damien Georged17926d2014-03-30 13:35:08 +010050 return mp_call_function_n_kw(self->fun, self->n_iters, 0, nextses);
John R. Lenton39b174e2014-01-15 01:10:09 +000051}
52
Damien George3e1a5c12014-03-29 13:43:38 +000053const mp_obj_type_t mp_type_map = {
Damien Georgec5966122014-02-15 16:10:44 +000054 { &mp_type_type },
Damien Georgea71c83a2014-02-15 11:34:50 +000055 .name = MP_QSTR_map,
John R. Lenton39b174e2014-01-15 01:10:09 +000056 .make_new = map_make_new,
57 .getiter = map_getiter,
58 .iternext = map_iternext,
59};