blob: 5bfd8a3370143d361845c1dc3670e60722441ba9 [file] [log] [blame]
John R. Lenton9daa7892014-01-14 23:55:01 +00001#include <stdlib.h>
2#include <assert.h>
3
4#include "misc.h"
5#include "mpconfig.h"
6#include "obj.h"
7#include "runtime.h"
8
9typedef struct _mp_obj_enumerate_t {
10 mp_obj_base_t base;
11 mp_obj_t iter;
12 machine_int_t cur;
13} mp_obj_enumerate_t;
14
15static mp_obj_t enumerate_getiter(mp_obj_t self_in) {
16 return self_in;
17}
18
19static mp_obj_t enumerate_iternext(mp_obj_t self_in);
20
21/* TODO: enumerate is one of the ones that can take args or kwargs.
22 Sticking to args for now */
23static mp_obj_t enumerate_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
24 /* NOTE: args are backwards */
25 assert(n_args > 0);
26 args += n_args - 1;
27 mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
28 o->base.type = &enumerate_type;
29 o->iter = rt_getiter(args[0]);
30 o->cur = n_args > 1 ? mp_obj_get_int(args[-1]) : 0;
31
32 return o;
33}
34
35const mp_obj_type_t enumerate_type = {
36 { &mp_const_type },
37 "enumerate",
38 .make_new = enumerate_make_new,
39 .iternext = enumerate_iternext,
40 .getiter = enumerate_getiter,
41};
42
43static mp_obj_t enumerate_iternext(mp_obj_t self_in) {
44 assert(MP_OBJ_IS_TYPE(self_in, &enumerate_type));
45 mp_obj_enumerate_t *self = self_in;
46 mp_obj_t next = rt_iternext(self->iter);
47 if (next == mp_const_stop_iteration) {
48 return mp_const_stop_iteration;
49 } else {
50 mp_obj_t items[] = {MP_OBJ_NEW_SMALL_INT(self->cur++), next};
51 return mp_obj_new_tuple(2, items);
52 }
53}