diff --git a/byterun/floats.c b/byterun/floats.c index c8684f9ad..c1f6ec5af 100644 --- a/byterun/floats.c +++ b/byterun/floats.c @@ -104,10 +104,23 @@ CAMLprim value format_float(value fmt, value arg) CAMLprim value float_of_string(value vs) { - char * s = String_val(vs); - char * ends; - double d = strtod((const char *) s, &ends); - if (ends != s + string_length(vs)) failwith("float_of_string"); + char parse_buffer[64]; + char * buf, * src, * dst, * end; + mlsize_t len; + double d; + + len = string_length(vs); + buf = len < sizeof(parse_buffer) ? parse_buffer : stat_alloc(len + 1); + src = String_val(vs); + dst = buf; + while (len--) { + char c = *src++; + if (c != '_') *dst++ = c; + } + *dst = 0; + d = strtod((const char *) buf, &end); + if (buf != parse_buffer) stat_free(buf); + if (end != dst) failwith("float_of_string"); return copy_double(d); } diff --git a/byterun/ints.c b/byterun/ints.c index 9dbf2b373..e9ad19401 100644 --- a/byterun/ints.c +++ b/byterun/ints.c @@ -46,9 +46,8 @@ static char * parse_sign_and_base(char * p, return p; } -static int parse_digit(char * p) +static int parse_digit(char c) { - int c = *p; if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'F') @@ -65,10 +64,12 @@ static long parse_long(char * p) int sign, base, d; p = parse_sign_and_base(p, &base, &sign); - d = parse_digit(p); + d = parse_digit(*p); if (d < 0 || d >= base) failwith("int_of_string"); for (p++, res = d; /*nothing*/; p++) { - d = parse_digit(p); + char c = *p; + if (c == '_') continue; + d = parse_digit(c); if (d < 0 || d >= base) break; res = base * res + d; } @@ -421,10 +422,12 @@ CAMLprim value int64_of_string(value s) int sign, base, d; p = parse_sign_and_base(String_val(s), &base, &sign); - d = parse_digit(p); + d = parse_digit(*p); if (d < 0 || d >= base) failwith("int_of_string"); for (p++, res = d; /*nothing*/; p++) { - d = parse_digit(p); + char c = *p; + if (c == '_') continue; + d = parse_digit(c); if (d < 0 || d >= base) break; res = base * res + d; } diff --git a/parsing/lexer.mll b/parsing/lexer.mll index 8e71d1a72..4701ee294 100644 --- a/parsing/lexer.mll +++ b/parsing/lexer.mll @@ -180,12 +180,18 @@ let identchar = ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9'] let symbolchar = ['!' '$' '%' '&' '*' '+' '-' '.' '/' ':' '<' '=' '>' '?' '@' '^' '|' '~'] -let decimal_literal = ['0'-'9']+ -let hex_literal = '0' ['x' 'X'] ['0'-'9' 'A'-'F' 'a'-'f']+ -let oct_literal = '0' ['o' 'O'] ['0'-'7']+ -let bin_literal = '0' ['b' 'B'] ['0'-'1']+ +let decimal_literal = + ['0'-'9'] ['0'-'9' '_']* +let hex_literal = + '0' ['x' 'X'] ['0'-'9' 'A'-'F' 'a'-'f']['0'-'9' 'A'-'F' 'a'-'f' '_']* +let oct_literal = + '0' ['o' 'O'] ['0'-'7'] ['0'-'7' '_']* +let bin_literal = + '0' ['b' 'B'] ['0'-'1'] ['0'-'1']* let float_literal = - ['0'-'9']+ ('.' ['0'-'9']* )? (['e' 'E'] ['+' '-']? ['0'-'9']+)? + ['0'-'9'] ['0'-'9' '_']* + ('.' ['0'-'9' '_']* )? + (['e' 'E'] ['+' '-']? ['0'-'9']+)? rule token = parse blank +