summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/emitnative.c2
-rw-r--r--py/obj.h4
-rw-r--r--py/objint.c6
-rw-r--r--py/objint_longlong.c20
-rw-r--r--py/objint_mpz.c18
-rw-r--r--py/parsenum.c32
-rw-r--r--py/runtime.c9
-rw-r--r--py/runtime.h1
-rw-r--r--py/runtime0.h4
-rw-r--r--py/vm.c2
10 files changed, 52 insertions, 46 deletions
diff --git a/py/emitnative.c b/py/emitnative.c
index 261b1a2a51..057e42c756 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -704,7 +704,7 @@ STATIC void emit_native_load_const_int(emit_t *emit, qstr qst) {
DEBUG_printf("load_const_int %s\n", qstr_str(st));
// for viper: load integer, check fits in 32 bits
emit_native_pre(emit);
- emit_call_with_imm_arg(emit, MP_F_LOAD_CONST_INT, mp_obj_new_int_from_qstr, qst, REG_ARG_1);
+ emit_call_with_imm_arg(emit, MP_F_LOAD_CONST_INT, mp_load_const_int, qst, REG_ARG_1);
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
}
diff --git a/py/obj.h b/py/obj.h
index e4350b424f..74bdc79774 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -371,7 +371,7 @@ 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_qstr(qstr qst);
+mp_obj_t mp_obj_new_int_from_str_len(const char **str, uint len, bool neg, uint base);
mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception)
mp_obj_t mp_obj_new_str(const char* data, uint len, bool make_qstr_if_not_already);
mp_obj_t mp_obj_new_bytes(const byte* data, uint len);
@@ -445,7 +445,7 @@ void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj);
// int
// For long int, returns value truncated to machine_int_t
-machine_int_t mp_obj_int_get(mp_obj_t self_in);
+machine_int_t mp_obj_int_get(mp_const_obj_t self_in);
#if MICROPY_ENABLE_FLOAT
mp_float_t mp_obj_int_as_float(mp_obj_t self_in);
#endif
diff --git a/py/objint.c b/py/objint.c
index a3b3554008..328fb11e80 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -139,7 +139,7 @@ char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_const_ob
} else if (MP_OBJ_IS_TYPE(self_in, &mp_type_int)) {
// Not a small int.
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
- mp_obj_int_t *self = self_in;
+ const mp_obj_int_t *self = self_in;
// Get the value to format; mp_obj_get_int truncates to machine_int_t.
num = self->val;
#else
@@ -225,7 +225,7 @@ mp_obj_t mp_obj_int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
// This is called only with strings whose value doesn't fit in SMALL_INT
-mp_obj_t mp_obj_new_int_from_qstr(qstr qst) {
+mp_obj_t mp_obj_new_int_from_str_len(const char **str, uint len, bool neg, uint base) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "long int not supported in this build"));
return mp_const_none;
}
@@ -254,7 +254,7 @@ mp_obj_t mp_obj_new_int(machine_int_t value) {
return mp_const_none;
}
-machine_int_t mp_obj_int_get(mp_obj_t self_in) {
+machine_int_t mp_obj_int_get(mp_const_obj_t self_in) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
}
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index 1e0167b464..381246dfe4 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -162,26 +162,22 @@ mp_obj_t mp_obj_new_int_from_ll(long long val) {
return o;
}
-mp_obj_t mp_obj_new_int_from_qstr(qstr qst) {
- const char *s = qstr_str(qst);
- long long v;
- char *end;
- // TODO: this doesn't handle Python hacked 0o octal syntax
- v = strtoll(s, &end, 0);
- if (*end != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number"));
- }
+mp_obj_t mp_obj_new_int_from_str_len(const char **str, uint len, bool neg, uint base) {
+ // TODO this does not honor the given length of the string, but it all cases it should anyway be null terminated
+ // TODO check overflow
mp_obj_int_t *o = m_new_obj(mp_obj_int_t);
o->base.type = &mp_type_int;
- o->val = v;
+ char *endptr;
+ o->val = strtoll(*str, &endptr, base);
+ *str = endptr;
return o;
}
-machine_int_t mp_obj_int_get(mp_obj_t self_in) {
+machine_int_t mp_obj_int_get(mp_const_obj_t self_in) {
if (MP_OBJ_IS_SMALL_INT(self_in)) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
} else {
- mp_obj_int_t *self = self_in;
+ const mp_obj_int_t *self = self_in;
return self->val;
}
}
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 2df3232e9c..733dc096a6 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -260,26 +260,18 @@ mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
return mp_obj_new_int_from_ll(value);
}
-mp_obj_t mp_obj_new_int_from_qstr(qstr qst) {
+mp_obj_t mp_obj_new_int_from_str_len(const char **str, uint len, bool neg, uint base) {
mp_obj_int_t *o = mp_obj_int_new_mpz();
- uint len;
- const char* str = (const char*)qstr_data(qst, &len);
- int base = 0;
- int skip = mp_parse_num_base(str, len, &base);
- str += skip;
- len -= skip;
- uint n = mpz_set_from_str(&o->mpz, str, len, false, base);
- if (n != len) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number"));
- }
+ uint n = mpz_set_from_str(&o->mpz, *str, len, neg, base);
+ *str += n;
return o;
}
-machine_int_t mp_obj_int_get(mp_obj_t self_in) {
+machine_int_t mp_obj_int_get(mp_const_obj_t self_in) {
if (MP_OBJ_IS_SMALL_INT(self_in)) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
} else {
- mp_obj_int_t *self = self_in;
+ const mp_obj_int_t *self = self_in;
return mpz_as_int(&self->mpz);
}
}
diff --git a/py/parsenum.c b/py/parsenum.c
index d3cb821a13..842a9e9599 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -42,6 +42,7 @@
mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) {
const char *restrict top = str + len;
bool neg = false;
+ mp_obj_t ret_val;
// check radix base
if ((base != 0 && base < 2) || base > 36) {
@@ -96,16 +97,20 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) {
}
}
- // check we parsed something
- if (str == str_val_start) {
- goto value_error;
- }
-
// negate value if needed
if (neg) {
int_val = -int_val;
}
+ // create the small int
+ ret_val = MP_OBJ_NEW_SMALL_INT(int_val);
+
+have_ret_val:
+ // check we parsed something
+ if (str == str_val_start) {
+ goto value_error;
+ }
+
// skip trailing space
for (; str < top && unichar_isspace(*str); str++) {
}
@@ -116,14 +121,19 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, uint len, int base) {
}
// return the object
- return MP_OBJ_NEW_SMALL_INT(int_val);
-
-value_error:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid literal for int() with base %d: '%s'", base, str));
+ return ret_val;
overflow:
- // TODO reparse using bignum
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "overflow parsing integer"));
+ // reparse using long int
+ {
+ const char *s2 = str_val_start;
+ ret_val = mp_obj_new_int_from_str_len(&s2, top - str_val_start, neg, base);
+ str = s2;
+ goto have_ret_val;
+ }
+
+value_error:
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid syntax for integer with base %d: '%s'", base, str));
}
#define PARSE_DEC_IN_INTG (1)
diff --git a/py/runtime.c b/py/runtime.c
index ea75280ce4..f487807256 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -98,6 +98,13 @@ void mp_deinit(void) {
#endif
}
+mp_obj_t mp_load_const_int(qstr qstr) {
+ DEBUG_OP_printf("load '%s'\n", qstr_str(qstr));
+ uint len;
+ const byte* data = qstr_data(qstr, &len);
+ return mp_parse_num_integer((const char*)data, len, 0);
+}
+
mp_obj_t mp_load_const_dec(qstr qstr) {
DEBUG_OP_printf("load '%s'\n", qstr_str(qstr));
uint len;
@@ -1147,8 +1154,8 @@ void *m_malloc_fail(int num_bytes) {
// these must correspond to the respective enum
void *const mp_fun_table[MP_F_NUMBER_OF] = {
+ mp_load_const_int,
mp_load_const_dec,
- mp_obj_new_int_from_qstr,
mp_load_const_str,
mp_load_name,
mp_load_global,
diff --git a/py/runtime.h b/py/runtime.h
index a5d6743034..3c79b48ed0 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -77,6 +77,7 @@ void mp_delete_global(qstr qstr);
mp_obj_t mp_unary_op(int op, mp_obj_t arg);
mp_obj_t mp_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs);
+mp_obj_t mp_load_const_int(qstr qstr);
mp_obj_t mp_load_const_dec(qstr qstr);
mp_obj_t mp_load_const_str(qstr qstr);
mp_obj_t mp_load_const_bytes(qstr qstr);
diff --git a/py/runtime0.h b/py/runtime0.h
index 425122dbc2..542edf4a62 100644
--- a/py/runtime0.h
+++ b/py/runtime0.h
@@ -96,8 +96,8 @@ typedef enum {
} mp_binary_op_t;
typedef enum {
- MP_F_LOAD_CONST_DEC = 0,
- MP_F_LOAD_CONST_INT,
+ MP_F_LOAD_CONST_INT = 0,
+ MP_F_LOAD_CONST_DEC,
MP_F_LOAD_CONST_STR,
MP_F_LOAD_NAME,
MP_F_LOAD_GLOBAL,
diff --git a/py/vm.c b/py/vm.c
index f6aa74348d..bd94ade541 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -312,7 +312,7 @@ dispatch_loop:
ENTRY(MP_BC_LOAD_CONST_INT): {
DECODE_QSTR;
- PUSH(mp_obj_new_int_from_qstr(qst));
+ PUSH(mp_load_const_int(qst));
DISPATCH();
}