summaryrefslogtreecommitdiffstatshomepage
path: root/py/parse.c
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-01-11 02:33:29 +0200
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-01-12 22:04:21 +0200
commit80f60e1aee8c427c942a867b4c2cde48566bdc19 (patch)
treedbb6d8804bef97eb4089bf5817744be25e8da965 /py/parse.c
parent757ac81a69cc2143a6b170367b18c75ac60249e4 (diff)
downloadmicropython-80f60e1aee8c427c942a867b4c2cde48566bdc19.tar.gz
micropython-80f60e1aee8c427c942a867b4c2cde48566bdc19.zip
Parse long Python ints properly.
Long int is something which doesn't fit into SMALL_INT partion of machine_int_t. But it's also something which doesn't fit into machine_int_t in the first place.
Diffstat (limited to 'py/parse.c')
-rw-r--r--py/parse.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/py/parse.c b/py/parse.c
index a619c90507..e2c9520736 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -196,7 +196,7 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
} else if (tok->kind == MP_TOKEN_NUMBER) {
bool dec = false;
bool small_int = true;
- int int_val = 0;
+ machine_int_t int_val = 0;
int len = tok->len;
const char *str = tok->str;
int base = 10;
@@ -216,7 +216,9 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
i = 2;
}
}
+ bool overflow = false;
for (; i < len; i++) {
+ machine_int_t old_val = int_val;
if (unichar_isdigit(str[i]) && str[i] - '0' < base) {
int_val = base * int_val + str[i] - '0';
} else if (base == 16 && 'a' <= str[i] && str[i] <= 'f') {
@@ -230,10 +232,17 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
small_int = false;
break;
}
+ if (int_val < old_val) {
+ // If new value became less than previous, it's overflow
+ overflow = true;
+ } else if ((old_val ^ int_val) & WORD_MSBIT_HIGH) {
+ // If signed number changed sign - it's overflow
+ overflow = true;
+ }
}
if (dec) {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_DECIMAL, qstr_from_strn_copy(str, len));
- } else if (small_int && MP_FIT_SMALL_INT(int_val)) {
+ } else if (small_int && !overflow && MP_FIT_SMALL_INT(int_val)) {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, int_val);
} else {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_INTEGER, qstr_from_strn_copy(str, len));