diff --git a/extmod/modujson.c b/extmod/modujson.c index bee432db2..9a73e4501 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -270,7 +270,7 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) { S_NEXT(s); } if (flt) { - next = mp_parse_num_decimal(vstr.buf, vstr.len, false, false, NULL); + next = mp_parse_num_float(vstr.buf, vstr.len, false, NULL); } else { next = mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL); } diff --git a/py/objcomplex.c b/py/objcomplex.c index 56c8353e9..157617e15 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -83,7 +83,7 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, si // a string, parse it size_t l; const char *s = mp_obj_str_get_data(args[0], &l); - return mp_parse_num_decimal(s, l, true, true, NULL); + return mp_parse_num_complex(s, l, NULL); } else if (mp_obj_is_type(args[0], &mp_type_complex)) { // a complex, just return it return args[0]; diff --git a/py/objfloat.c b/py/objfloat.c index 0855baac8..8e89b3da3 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -137,7 +137,7 @@ STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size mp_buffer_info_t bufinfo; if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_READ)) { // a textual representation, parse it - return mp_parse_num_decimal(bufinfo.buf, bufinfo.len, false, false, NULL); + return mp_parse_num_float(bufinfo.buf, bufinfo.len, false, NULL); } else if (mp_obj_is_float(args[0])) { // a float, just return it return args[0]; diff --git a/py/parse.c b/py/parse.c index 14f5f6c10..d58098af2 100644 --- a/py/parse.c +++ b/py/parse.c @@ -591,7 +591,7 @@ STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { mp_obj_t o = mp_parse_num_integer(lex->vstr.buf, lex->vstr.len, 0, lex); pn = make_node_const_object_optimised(parser, lex->tok_line, o); } else if (lex->tok_kind == MP_TOKEN_FLOAT_OR_IMAG) { - mp_obj_t o = mp_parse_num_decimal(lex->vstr.buf, lex->vstr.len, true, false, lex); + mp_obj_t o = mp_parse_num_float(lex->vstr.buf, lex->vstr.len, true, lex); pn = make_node_const_object(parser, lex->tok_line, o); } else if (lex->tok_kind == MP_TOKEN_STRING) { // Don't automatically intern all strings. Doc strings (which are usually large) diff --git a/py/parsenum.c b/py/parsenum.c index b90dfaaaf..5e8e5dfe8 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -178,7 +178,12 @@ typedef enum { PARSE_DEC_IN_EXP, } parse_dec_in_t; -mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex) { +#if MICROPY_PY_BUILTINS_COMPLEX +mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex) +#else +mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lexer_t *lex) +#endif +{ #if MICROPY_PY_BUILTINS_FLOAT // DEC_VAL_MAX only needs to be rough and is used to retain precision while not overflowing @@ -202,9 +207,9 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool const char *top = str + len; mp_float_t dec_val = 0; bool dec_neg = false; - unsigned int real_imag_state = REAL_IMAG_STATE_START; #if MICROPY_PY_BUILTINS_COMPLEX + unsigned int real_imag_state = REAL_IMAG_STATE_START; mp_float_t dec_real = 0; parse_start: #endif @@ -325,12 +330,16 @@ parse_start: } if (allow_imag && str < top && (*str | 0x20) == 'j') { + #if MICROPY_PY_BUILTINS_COMPLEX if (str == str_val_start) { // Convert "j" to "1j". dec_val = 1; } ++str; real_imag_state |= REAL_IMAG_STATE_HAVE_IMAG; + #else + raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("complex values not supported")), lex); + #endif } // negate value if needed @@ -369,20 +378,16 @@ parse_start: #endif // return the object + #if MICROPY_PY_BUILTINS_COMPLEX if (real_imag_state != REAL_IMAG_STATE_START) { return mp_obj_new_complex(dec_real, dec_val); } else if (force_complex) { return mp_obj_new_complex(dec_val, 0); } - #else - if (real_imag_state != REAL_IMAG_STATE_START || force_complex) { - raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("complex values not supported")), lex); - } #endif - else { - return mp_obj_new_float(dec_val); - } + + return mp_obj_new_float(dec_val); value_error: raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("invalid syntax for number")), lex); diff --git a/py/parsenum.h b/py/parsenum.h index a5bed731d..f444632d2 100644 --- a/py/parsenum.h +++ b/py/parsenum.h @@ -31,7 +31,21 @@ #include "py/obj.h" // these functions raise a SyntaxError if lex!=NULL, else a ValueError + mp_obj_t mp_parse_num_integer(const char *restrict str, size_t len, int base, mp_lexer_t *lex); + +#if MICROPY_PY_BUILTINS_COMPLEX mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex); +static inline mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lexer_t *lex) { + return mp_parse_num_decimal(str, len, allow_imag, false, lex); +} + +static inline mp_obj_t mp_parse_num_complex(const char *str, size_t len, mp_lexer_t *lex) { + return mp_parse_num_decimal(str, len, true, true, lex); +} +#else +mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lexer_t *lex); +#endif + #endif // MICROPY_INCLUDED_PY_PARSENUM_H diff --git a/py/persistentcode.c b/py/persistentcode.c index 6304d1ff0..fbef0b2c0 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -207,7 +207,7 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { return mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL); } else { assert(obj_type == MP_PERSISTENT_OBJ_FLOAT || obj_type == MP_PERSISTENT_OBJ_COMPLEX); - return mp_parse_num_decimal(vstr.buf, vstr.len, obj_type == MP_PERSISTENT_OBJ_COMPLEX, false, NULL); + return mp_parse_num_float(vstr.buf, vstr.len, obj_type == MP_PERSISTENT_OBJ_COMPLEX, NULL); } } }