1/*
2 * This file is part of the MicroPython project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27#include <stdbool.h>
28#include <stdlib.h>
29
30#include "py/runtime.h"
31#include "py/parsenumbase.h"
32#include "py/parsenum.h"
33#include "py/smallint.h"
34
35#if MICROPY_PY_BUILTINS_FLOAT
36#include <math.h>
37#endif
38
39STATIC NORETURN void raise_exc(mp_obj_t exc, mp_lexer_t *lex) {
40 // if lex!=NULL then the parser called us and we need to convert the
41 // exception's type from ValueError to SyntaxError and add traceback info
42 if (lex != NULL) {
43 ((mp_obj_base_t *)MP_OBJ_TO_PTR(exc))->type = &mp_type_SyntaxError;
44 mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTRnull);
45 }
46 nlr_raise(exc);
47}
48
49mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, mp_lexer_t *lex) {
50 const byte *restrict str = (const byte *)str_;
51 const byte *restrict top = str + len;
52 bool neg = false;
53 mp_obj_t ret_val;
54
55 // check radix base
56 if ((base != 0 && base < 2) || base > 36) {
57 // this won't be reached if lex!=NULL
58 mp_raise_ValueError(MP_ERROR_TEXT("int() arg 2 must be >= 2 and <= 36"));
59 }
60
61 // skip leading space
62 for (; str < top && unichar_isspace(*str); str++) {
63 }
64
65 // parse optional sign
66 if (str < top) {
67 if (*str == '+') {
68 str++;
69 } else if (*str == '-') {
70 str++;
71 neg = true;
72 }
73 }
74
75 // parse optional base prefix
76 str += mp_parse_num_base((const char *)str, top - str, &base);
77
78 // string should be an integer number
79 mp_int_t int_val = 0;
80 const byte *restrict str_val_start = str;
81 for (; str < top; str++) {
82 // get next digit as a value
83 mp_uint_t dig = *str;
84 if ('0' <= dig && dig <= '9') {
85 dig -= '0';
86 } else if (dig == '_') {
87 continue;
88 } else {
89 dig |= 0x20; // make digit lower-case
90 if ('a' <= dig && dig <= 'z') {
91 dig -= 'a' - 10;
92 } else {
93 // unknown character
94 break;
95 }
96 }
97 if (dig >= (mp_uint_t)base) {
98 break;
99 }
100
101 // add next digi and check for overflow
102 if (mp_small_int_mul_overflow(int_val, base)) {
103 goto overflow;
104 }
105 int_val = int_val * base + dig;
106 if (!MP_SMALL_INT_FITS(int_val)) {
107 goto overflow;
108 }
109 }
110
111 // negate value if needed
112 if (neg) {
113 int_val = -int_val;
114 }
115
116 // create the small int
117 ret_val = MP_OBJ_NEW_SMALL_INT(int_val);
118
119have_ret_val:
120 // check we parsed something
121 if (str == str_val_start) {
122 goto value_error;
123 }
124
125 // skip trailing space
126 for (; str < top && unichar_isspace(*str); str++) {
127 }
128
129 // check we reached the end of the string
130 if (str != top) {
131 goto value_error;
132 }
133
134 // return the object
135 return ret_val;
136
137overflow:
138 // reparse using long int
139 {
140 const char *s2 = (const char *)str_val_start;
141 ret_val = mp_obj_new_int_from_str_len(&s2, top - str_val_start, neg, base);
142 str = (const byte *)s2;
143 goto have_ret_val;
144 }
145
146value_error:
147 {
148 #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
149 mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError,
150 MP_ERROR_TEXT("invalid syntax for integer"));
151 raise_exc(exc, lex);
152 #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
153 mp_obj_t exc = mp_obj_new_exception_msg_varg(&mp_type_ValueError,
154 MP_ERROR_TEXT("invalid syntax for integer with base %d"), base);
155 raise_exc(exc, lex);
156 #else
157 vstr_t vstr;
158 mp_print_t print;
159 vstr_init_print(&vstr, 50, &print);
160 mp_printf(&print, "invalid syntax for integer with base %d: ", base);
161 mp_str_print_quoted(&print, str_val_start, top - str_val_start, true);
162 mp_obj_t exc = mp_obj_new_exception_arg1(&mp_type_ValueError,
163 mp_obj_new_str_from_vstr(&mp_type_str, &vstr));
164 raise_exc(exc, lex);
165 #endif
166 }
167}
168
169typedef enum {
170 PARSE_DEC_IN_INTG,
171 PARSE_DEC_IN_FRAC,
172 PARSE_DEC_IN_EXP,
173} parse_dec_in_t;
174
175mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex) {
176 #if MICROPY_PY_BUILTINS_FLOAT
177
178// DEC_VAL_MAX only needs to be rough and is used to retain precision while not overflowing
179// SMALL_NORMAL_VAL is the smallest power of 10 that is still a normal float
180// EXACT_POWER_OF_10 is the largest value of x so that 10^x can be stored exactly in a float
181// Note: EXACT_POWER_OF_10 is at least floor(log_5(2^mantissa_length)). Indeed, 10^n = 2^n * 5^n
182// so we only have to store the 5^n part in the mantissa (the 2^n part will go into the float's
183// exponent).
184 #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
185#define DEC_VAL_MAX 1e20F
186#define SMALL_NORMAL_VAL (1e-37F)
187#define SMALL_NORMAL_EXP (-37)
188#define EXACT_POWER_OF_10 (9)
189 #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
190#define DEC_VAL_MAX 1e200
191#define SMALL_NORMAL_VAL (1e-307)
192#define SMALL_NORMAL_EXP (-307)
193#define EXACT_POWER_OF_10 (22)
194 #endif
195
196 const char *top = str + len;
197 mp_float_t dec_val = 0;
198 bool dec_neg = false;
199 bool imag = false;
200
201 // skip leading space
202 for (; str < top && unichar_isspace(*str); str++) {
203 }
204
205 // parse optional sign
206 if (str < top) {
207 if (*str == '+') {
208 str++;
209 } else if (*str == '-') {
210 str++;
211 dec_neg = true;
212 }
213 }
214
215 const char *str_val_start = str;
216
217 // determine what the string is
218 if (str < top && (str[0] | 0x20) == 'i') {
219 // string starts with 'i', should be 'inf' or 'infinity' (case insensitive)
220 if (str + 2 < top && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') {
221 // inf
222 str += 3;
223 dec_val = (mp_float_t)INFINITY;
224 if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') {
225 // infinity
226 str += 5;
227 }
228 }
229 } else if (str < top && (str[0] | 0x20) == 'n') {
230 // string starts with 'n', should be 'nan' (case insensitive)
231 if (str + 2 < top && (str[1] | 0x20) == 'a' && (str[2] | 0x20) == 'n') {
232 // NaN
233 str += 3;
234 dec_val = MICROPY_FLOAT_C_FUN(nan)("");
235 }
236 } else {
237 // string should be a decimal number
238 parse_dec_in_t in = PARSE_DEC_IN_INTG;
239 bool exp_neg = false;
240 int exp_val = 0;
241 int exp_extra = 0;
242 while (str < top) {
243 unsigned int dig = *str++;
244 if ('0' <= dig && dig <= '9') {
245 dig -= '0';
246 if (in == PARSE_DEC_IN_EXP) {
247 // don't overflow exp_val when adding next digit, instead just truncate
248 // it and the resulting float will still be correct, either inf or 0.0
249 // (use INT_MAX/2 to allow adding exp_extra at the end without overflow)
250 if (exp_val < (INT_MAX / 2 - 9) / 10) {
251 exp_val = 10 * exp_val + dig;
252 }
253 } else {
254 if (dec_val < DEC_VAL_MAX) {
255 // dec_val won't overflow so keep accumulating
256 dec_val = 10 * dec_val + dig;
257 if (in == PARSE_DEC_IN_FRAC) {
258 --exp_extra;
259 }
260 } else {
261 // dec_val might overflow and we anyway can't represent more digits
262 // of precision, so ignore the digit and just adjust the exponent
263 if (in == PARSE_DEC_IN_INTG) {
264 ++exp_extra;
265 }
266 }
267 }
268 } else if (in == PARSE_DEC_IN_INTG && dig == '.') {
269 in = PARSE_DEC_IN_FRAC;
270 } else if (in != PARSE_DEC_IN_EXP && ((dig | 0x20) == 'e')) {
271 in = PARSE_DEC_IN_EXP;
272 if (str < top) {
273 if (str[0] == '+') {
274 str++;
275 } else if (str[0] == '-') {
276 str++;
277 exp_neg = true;
278 }
279 }
280 if (str == top) {
281 goto value_error;
282 }
283 } else if (allow_imag && (dig | 0x20) == 'j') {
284 imag = true;
285 break;
286 } else if (dig == '_') {
287 continue;
288 } else {
289 // unknown character
290 str--;
291 break;
292 }
293 }
294
295 // work out the exponent
296 if (exp_neg) {
297 exp_val = -exp_val;
298 }
299
300 // apply the exponent, making sure it's not a subnormal value
301 exp_val += exp_extra;
302 if (exp_val < SMALL_NORMAL_EXP) {
303 exp_val -= SMALL_NORMAL_EXP;
304 dec_val *= SMALL_NORMAL_VAL;
305 }
306
307 // At this point, we need to multiply the mantissa by its base 10 exponent. If possible,
308 // we would rather manipulate numbers that have an exact representation in IEEE754. It
309 // turns out small positive powers of 10 do, whereas small negative powers of 10 don't.
310 // So in that case, we'll yield a division of exact values rather than a multiplication
311 // of slightly erroneous values.
312 if (exp_val < 0 && exp_val >= -EXACT_POWER_OF_10) {
313 dec_val /= MICROPY_FLOAT_C_FUN(pow)(10, -exp_val);
314 } else {
315 dec_val *= MICROPY_FLOAT_C_FUN(pow)(10, exp_val);
316 }
317 }
318
319 // negate value if needed
320 if (dec_neg) {
321 dec_val = -dec_val;
322 }
323
324 // check we parsed something
325 if (str == str_val_start) {
326 goto value_error;
327 }
328
329 // skip trailing space
330 for (; str < top && unichar_isspace(*str); str++) {
331 }
332
333 // check we reached the end of the string
334 if (str != top) {
335 goto value_error;
336 }
337
338 // return the object
339 #if MICROPY_PY_BUILTINS_COMPLEX
340 if (imag) {
341 return mp_obj_new_complex(0, dec_val);
342 } else if (force_complex) {
343 return mp_obj_new_complex(dec_val, 0);
344 }
345 #else
346 if (imag || force_complex) {
347 raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("complex values not supported")), lex);
348 }
349 #endif
350 else {
351 return mp_obj_new_float(dec_val);
352 }
353
354value_error:
355 raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("invalid syntax for number")), lex);
356
357 #else
358 raise_exc(mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("decimal numbers not supported")), lex);
359 #endif
360}
361