Skip to content

Instantly share code, notes, and snippets.

@nobu
Created July 2, 2009 00:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nobu/139187 to your computer and use it in GitHub Desktop.
Save nobu/139187 to your computer and use it in GitHub Desktop.
Index: parse.y
===================================================================
--- parse.y (revision 23932)
+++ parse.y (working copy)
@@ -6858,7 +6858,7 @@ parser_yylex(struct parser_params *parse
case '5': case '6': case '7': case '8': case '9':
{
- int is_float, seen_point, seen_e, nondigit;
+ int is_float, seen_point, seen_e, nondigit, decimal;
- is_float = seen_point = seen_e = nondigit = 0;
+ decimal = is_float = seen_point = seen_e = nondigit = 0;
lex_state = EXPR_END;
newtok();
@@ -6920,25 +6920,10 @@ parser_yylex(struct parser_params *parse
if (c == 'd' || c == 'D') {
/* decimal */
+ decimal++;
c = nextc();
- if (c != -1 && ISDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISDIGIT(c)) break;
- nondigit = 0;
- tokadd(c);
- } while ((c = nextc()) != -1);
- }
- pushback(c);
- tokfix();
- if (toklen() == start) {
+ if (c == -1 || !ISDIGIT(c)) {
yyerror("numeric literal without digits");
}
- else if (nondigit) goto trailing_uc;
- set_yylval_literal(rb_cstr_to_inum(tok(), 10, Qfalse));
- return tINTEGER;
+ goto decimal_number;
}
if (c == '_') {
@@ -6993,4 +6978,5 @@ parser_yylex(struct parser_params *parse
}
+ decimal_number:
for (;;) {
switch (c) {
@@ -7062,10 +7048,21 @@ parser_yylex(struct parser_params *parse
}
if (is_float) {
- double d = strtod(tok(), 0);
- if (errno == ERANGE) {
- rb_warningS("Float %s out of range", tok());
- errno = 0;
+ VALUE val;
+ if (decimal) {
+ rb_require_safe(rb_usascii_str_new_cstr("decimal.so"), 0);
+ val = rb_usascii_str_new(tok(), toklen());
+ val = rb_funcall2(Qnil, rb_intern("Decimal"), 1, &val);
+ set_yylval_literal(val);
+ return tFLOAT;
+ }
+ else {
+ double d = strtod(tok(), 0);
+ if (errno == ERANGE) {
+ rb_warningS("Float %s out of range", tok());
+ errno = 0;
+ }
+ val = DBL2NUM(d);
}
- set_yylval_literal(DBL2NUM(d));
+ set_yylval_literal(val);
return tFLOAT;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment