blob: 8c0eadd32e32fcda87be833a4c77b28f2c6e90ba [file] [log] [blame]
Damien George66eaf842014-03-26 19:27:58 +00001#include <stdlib.h>
Damiend99b0522013-12-21 18:17:45 +00002
3#include "nlr.h"
4#include "misc.h"
5#include "mpconfig.h"
Damien George55baff42014-01-21 21:40:13 +00006#include "qstr.h"
Damiend99b0522013-12-21 18:17:45 +00007#include "obj.h"
Damien George71d31122014-04-17 18:18:55 +01008#include "runtime.h"
Damiend99b0522013-12-21 18:17:45 +00009
10/******************************************************************************/
11/* range iterator */
12
13typedef struct _mp_obj_range_it_t {
14 mp_obj_base_t base;
15 // TODO make these values generic objects or something
16 machine_int_t cur;
17 machine_int_t stop;
18 machine_int_t step;
19} mp_obj_range_it_t;
20
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020021STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) {
Damiend99b0522013-12-21 18:17:45 +000022 mp_obj_range_it_t *o = o_in;
23 if ((o->step > 0 && o->cur < o->stop) || (o->step < 0 && o->cur > o->stop)) {
24 mp_obj_t o_out = MP_OBJ_NEW_SMALL_INT(o->cur);
25 o->cur += o->step;
26 return o_out;
27 } else {
Damien Georgeea8d06c2014-04-17 23:19:36 +010028 return MP_OBJ_STOP_ITERATION;
Damiend99b0522013-12-21 18:17:45 +000029 }
30}
31
Paul Sokolovskyd5df6cd2014-02-12 18:15:40 +020032STATIC const mp_obj_type_t range_it_type = {
Damien Georgec5966122014-02-15 16:10:44 +000033 { &mp_type_type },
Damien Georgea71c83a2014-02-15 11:34:50 +000034 .name = MP_QSTR_iterator,
Paul Sokolovskyf7eaf602014-03-30 22:00:12 +030035 .getiter = mp_identity,
Damien George97209d32014-01-07 15:58:30 +000036 .iternext = range_it_iternext,
Damiend99b0522013-12-21 18:17:45 +000037};
38
39mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step) {
40 mp_obj_range_it_t *o = m_new_obj(mp_obj_range_it_t);
41 o->base.type = &range_it_type;
42 o->cur = cur;
43 o->stop = stop;
44 o->step = step;
45 return o;
46}
Damien George71d31122014-04-17 18:18:55 +010047
48/******************************************************************************/
49/* range */
50
51typedef struct _mp_obj_range_t {
52 mp_obj_base_t base;
53 // TODO make these values generic objects or something
54 machine_int_t start;
55 machine_int_t stop;
56 machine_int_t step;
57} mp_obj_range_t;
58
59STATIC mp_obj_t range_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
Damien Georgea3f94e02014-04-20 00:13:22 +010060 mp_arg_check_num(n_args, n_kw, 1, 3, false);
Damien George71d31122014-04-17 18:18:55 +010061
62 mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
63 o->base.type = &mp_type_range;
64 o->start = 0;
65 o->step = 1;
66
67 if (n_args == 1) {
68 o->stop = mp_obj_get_int(args[0]);
69 } else {
70 o->start = mp_obj_get_int(args[0]);
71 o->stop = mp_obj_get_int(args[1]);
72 if (n_args == 3) {
73 o->step = mp_obj_get_int(args[2]);
74 }
75 }
76
77 return o;
78}
79
80STATIC mp_obj_t range_getiter(mp_obj_t o_in) {
81 mp_obj_range_t *o = o_in;
82 return mp_obj_new_range_iterator(o->start, o->stop, o->step);
83}
84
85const mp_obj_type_t mp_type_range = {
86 { &mp_type_type },
87 .name = MP_QSTR_range,
88 .make_new = range_make_new,
89 .getiter = range_getiter,
90};