diff --git a/py/mpconfig.h b/py/mpconfig.h index 6deb442b8d..ada4aa2ea4 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -62,6 +62,18 @@ #define MICROPY_ENABLE_LEXER_UNIX (0) #endif +// Long int implementation +#define MICROPY_LONGINT_IMPL_NONE (0) +#define MICROPY_LONGINT_IMPL_LONGLONG (1) + +#ifndef MICROPY_LONGINT_IMPL +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) +#endif + +#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG +typedef long long mp_longint_impl_t; +#endif + // Whether to support float and complex types #ifndef MICROPY_ENABLE_FLOAT #define MICROPY_ENABLE_FLOAT (0) diff --git a/py/obj.h b/py/obj.h index 5a104d703c..a9a5827ee7 100644 --- a/py/obj.h +++ b/py/obj.h @@ -198,6 +198,8 @@ mp_obj_t mp_obj_new_none(void); mp_obj_t mp_obj_new_bool(bool value); mp_obj_t mp_obj_new_cell(mp_obj_t obj); mp_obj_t mp_obj_new_int(machine_int_t value); +mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value); +mp_obj_t mp_obj_new_int_from_long_str(const char *s); mp_obj_t mp_obj_new_str(qstr qstr); #if MICROPY_ENABLE_FLOAT mp_obj_t mp_obj_new_float(mp_float_t val); diff --git a/py/objint.c b/py/objint.c index 9cd5ebae29..26d3c0e337 100644 --- a/py/objint.c +++ b/py/objint.c @@ -11,8 +11,16 @@ typedef struct _mp_obj_int_t { mp_obj_base_t base; +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE + mp_longint_impl_t val; +#endif } mp_obj_int_t; +void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in); +mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in); + +// This dispatcher function is expected to be independent of the implementation +// of long int static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) { switch (n_args) { case 0: @@ -20,7 +28,7 @@ static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) case 1: // TODO allow string as arg and parse it - return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0])); + return mp_obj_new_int(mp_obj_get_int(args[0])); //case 2: // TODO, parse with given base @@ -33,9 +41,41 @@ static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) const mp_obj_type_t int_type = { { &mp_const_type }, "int", + .print = int_print, .make_new = int_make_new, + .binary_op = int_binary_op, }; +#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE +// This is called only for non-SMALL_INT +void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { +} + +// This is called only for non-SMALL_INT +mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + assert(0); +} + +// This is called only with strings whose value doesn't fit in SMALL_INT +mp_obj_t mp_obj_new_int_from_long_str(const char *s) { + assert(0); +} + +mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) { + // SMALL_INT accepts only signed numbers, of one bit less size + // then word size, which totals 2 bits less for unsigned numbers. + if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) { + return MP_OBJ_NEW_SMALL_INT(value); + } + // TODO: Raise exception + assert(0); +} + mp_obj_t mp_obj_new_int(machine_int_t value) { - return MP_OBJ_NEW_SMALL_INT(value); + if (MP_OBJ_FITS_SMALL_INT(value)) { + return MP_OBJ_NEW_SMALL_INT(value); + } + // TODO: Raise exception + assert(0); } +#endif