From 71d3112f7e34d0bdd70012463cf31871bea57c45 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 17 Apr 2014 18:18:55 +0100 Subject: [PATCH] py: Make built-in 'range' a class. Addresses issue #487. --- py/builtin.c | 11 ------- py/builtin.h | 1 - py/builtintables.c | 2 +- py/obj.h | 3 +- py/objrange.c | 77 +++++++++++++++++++++++++++------------------- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/py/builtin.c b/py/builtin.c index 5e20154520..217dcc186d 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -362,17 +362,6 @@ STATIC mp_obj_t mp_builtin_print(uint n_args, const mp_obj_t *args, mp_map_t *kw MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_print_obj, 0, mp_builtin_print); -STATIC mp_obj_t mp_builtin_range(uint n_args, const mp_obj_t *args) { - assert(1 <= n_args && n_args <= 3); - switch (n_args) { - case 1: return mp_obj_new_range(0, mp_obj_get_int(args[0]), 1); - case 2: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), 1); - default: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2])); - } -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_range_obj, 1, 3, mp_builtin_range); - STATIC mp_obj_t mp_builtin_repr(mp_obj_t o_in) { vstr_t *vstr = vstr_new(); mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, vstr, o_in, PRINT_REPR); diff --git a/py/builtin.h b/py/builtin.h index 9b2b9c9424..5f5c888f8a 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -31,7 +31,6 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_oct_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_ord_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_pow_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_print_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_range_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_repr_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sorted_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj); diff --git a/py/builtintables.c b/py/builtintables.c index c4c96ed35a..940647d25f 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -34,6 +34,7 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = { #if MICROPY_ENABLE_PROPERTY { MP_OBJ_NEW_QSTR(MP_QSTR_property), (mp_obj_t)&mp_type_property }, #endif + { MP_OBJ_NEW_QSTR(MP_QSTR_range), (mp_obj_t)&mp_type_range }, { MP_OBJ_NEW_QSTR(MP_QSTR_set), (mp_obj_t)&mp_type_set }, { MP_OBJ_NEW_QSTR(MP_QSTR_str), (mp_obj_t)&mp_type_str }, { MP_OBJ_NEW_QSTR(MP_QSTR_super), (mp_obj_t)&mp_type_super }, @@ -75,7 +76,6 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ord), (mp_obj_t)&mp_builtin_ord_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_pow), (mp_obj_t)&mp_builtin_pow_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_print), (mp_obj_t)&mp_builtin_print_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_range), (mp_obj_t)&mp_builtin_range_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_repr), (mp_obj_t)&mp_builtin_repr_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sorted), (mp_obj_t)&mp_builtin_sorted_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sum), (mp_obj_t)&mp_builtin_sum_obj }, diff --git a/py/obj.h b/py/obj.h index 9efec60de0..7e1b7e598a 100644 --- a/py/obj.h +++ b/py/obj.h @@ -272,6 +272,7 @@ extern const mp_obj_type_t mp_type_map; // map (the python builtin, not the dict extern const mp_obj_type_t mp_type_enumerate; extern const mp_obj_type_t mp_type_filter; extern const mp_obj_type_t mp_type_dict; +extern const mp_obj_type_t mp_type_range; extern const mp_obj_type_t mp_type_set; extern const mp_obj_type_t mp_type_slice; extern const mp_obj_type_t mp_type_zip; @@ -346,8 +347,6 @@ mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, uint n_args, const mp_obj_t *args); mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg); mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) -mp_obj_t mp_obj_new_range(int start, int stop, int step); -mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step); mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_args, mp_obj_t def_args, const byte *code); mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); diff --git a/py/objrange.c b/py/objrange.c index 64d92457b7..45f83580d1 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -5,38 +5,7 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" - -/******************************************************************************/ -/* range */ - -typedef struct _mp_obj_range_t { - mp_obj_base_t base; - // TODO make these values generic objects or something - machine_int_t start; - machine_int_t stop; - machine_int_t step; -} mp_obj_range_t; - -STATIC mp_obj_t range_getiter(mp_obj_t o_in) { - mp_obj_range_t *o = o_in; - return mp_obj_new_range_iterator(o->start, o->stop, o->step); -} - -STATIC const mp_obj_type_t range_type = { - { &mp_type_type} , - .name = MP_QSTR_range, - .getiter = range_getiter, -}; - -// range is a class and instances are immutable sequence objects -mp_obj_t mp_obj_new_range(int start, int stop, int step) { - mp_obj_range_t *o = m_new_obj(mp_obj_range_t); - o->base.type = &range_type; - o->start = start; - o->stop = stop; - o->step = step; - return o; -} +#include "runtime.h" /******************************************************************************/ /* range iterator */ @@ -75,3 +44,47 @@ mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step) { o->step = step; return o; } + +/******************************************************************************/ +/* range */ + +typedef struct _mp_obj_range_t { + mp_obj_base_t base; + // TODO make these values generic objects or something + machine_int_t start; + machine_int_t stop; + machine_int_t step; +} mp_obj_range_t; + +STATIC mp_obj_t range_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + mp_check_nargs(n_args, 1, 3, n_kw, false); + + mp_obj_range_t *o = m_new_obj(mp_obj_range_t); + o->base.type = &mp_type_range; + o->start = 0; + o->step = 1; + + if (n_args == 1) { + o->stop = mp_obj_get_int(args[0]); + } else { + o->start = mp_obj_get_int(args[0]); + o->stop = mp_obj_get_int(args[1]); + if (n_args == 3) { + o->step = mp_obj_get_int(args[2]); + } + } + + return o; +} + +STATIC mp_obj_t range_getiter(mp_obj_t o_in) { + mp_obj_range_t *o = o_in; + return mp_obj_new_range_iterator(o->start, o->stop, o->step); +} + +const mp_obj_type_t mp_type_range = { + { &mp_type_type }, + .name = MP_QSTR_range, + .make_new = range_make_new, + .getiter = range_getiter, +};