diff options
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 102 |
1 files changed, 76 insertions, 26 deletions
@@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 18:02:42 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -18,6 +18,8 @@ #include "node.h" #include "st.h" #include <stdio.h> +#include <string.h> +#include <errno.h> /* hack for bison */ #ifdef const @@ -801,6 +803,10 @@ call_args : command_call value_expr($1); $$ = NEW_LIST($1); } + | args ',' + { + $$ = $1; + } | args opt_block_arg { $$ = arg_blk_pass($1, $2); @@ -810,6 +816,10 @@ call_args : command_call $$ = arg_add($1, $4); $$ = arg_blk_pass($$, $5); } + | assocs ',' + { + $$ = NEW_LIST(NEW_HASH($1)); + } | assocs opt_block_arg { $$ = NEW_LIST(NEW_HASH($1)); @@ -825,6 +835,10 @@ call_args : command_call $$ = list_append($1, NEW_HASH($3)); $$ = arg_blk_pass($$, $4); } + | args ',' assocs ',' + { + $$ = list_append($1, NEW_HASH($3)); + } | args ',' assocs ',' tSTAR arg opt_block_arg { $$ = arg_add(list_append($1, NEW_HASH($3)), $6); @@ -1665,6 +1679,7 @@ yycompile(f) ruby__end__seen = 0; ruby_eval_tree = 0; newline_seen = 0; + heredoc_end = 0; ruby_sourcefile = f; ruby_in_compile = 1; n = yyparse(); @@ -1745,6 +1760,10 @@ normalize_newline(line) RSTRING(line)->ptr[RSTRING(line)->len-2] = '\n'; RSTRING(line)->len--; } +#ifdef __MACOS__ + else if (RSTRING(line)->ptr[RSTRING(line)->len-1] == '\r') + RSTRING(line)->ptr[RSTRING(line)->len-1] = '\n'; +#endif } static int @@ -2011,8 +2030,10 @@ parse_regx(term, paren) } /* fall through */ default: - if (c == paren) nest++; - if (c == term) nest--; + if (paren) { + if (c == paren) nest++; + if (c == term) nest--; + } if (c == '\n') { ruby_sourceline++; } @@ -2156,10 +2177,12 @@ parse_string(func, term, paren) } continue; } - if (c == paren) nest++; - if (c == term) { - nest--; - if (nest == 0) break; + if (paren) { + if (c == paren) nest++; + if (c == term) { + nest--; + if (nest == 0) break; + } } tokadd(c); } @@ -2234,10 +2257,12 @@ parse_qstring(term, paren) tokadd('\\'); } } - if (c == paren) nest++; - if (c == term) { - nest--; - if (nest == 0) break; + if (paren) { + if (c == paren) nest++; + if (c == term) { + nest--; + if (nest == 0) break; + } } tokadd(c); } @@ -2396,8 +2421,8 @@ arg_ambiguous() rb_warning("ambiguous first argument; make sure"); } -#ifndef atof -double atof(); +#ifndef strtod +double strtod (); #endif static int @@ -2440,7 +2465,7 @@ retry: for (i = 0; i < len; i++) { c = nextc(); if (c == '\n') { - ruby_sourceline++; + pushback(c); break; } } @@ -2598,7 +2623,7 @@ retry: return parse_string(c,c,c); case '\'': - return parse_qstring(c,c); + return parse_qstring(c,0); case '?': if (lex_state == EXPR_END) { @@ -2753,29 +2778,49 @@ retry: c = nextc(); if (c == 'x' || c == 'X') { /* hexadecimal */ - while (c = nextc()) { + c = nextc(); + if (!ISXDIGIT(c)) { + yyerror("hexadecimal number without hex-digits"); + } + do { if (c == '_') continue; if (!ISXDIGIT(c)) break; tokadd(c); - } + } while (c = nextc()); pushback(c); tokfix(); yylval.val = rb_str2inum(tok(), 16); return tINTEGER; } - else if (c >= '0' && c <= '7') { - /* octal */ + if (c == 'b' || c == 'B') { + /* binary */ + c = nextc(); + if (c != '0' && c != '1') { + yyerror("numeric constant with no digits"); + } do { + if (c == '_') continue; + if (c != '0'&& c != '1') break; tokadd(c); - while ((c = nextc()) == '_') - ; - } while (c >= '0' && c <= '9'); + } while (c = nextc()); + pushback(c); + tokfix(); + yylval.val = rb_str2inum(tok(), 2); + return tINTEGER; + } + if (c >= '0' && c <= '7' || c == '_') { + /* octal */ + do { + if (c == '_') continue; + if (c < '0' || c > '7') break; + tokadd(c); + } while (c = nextc()); pushback(c); tokfix(); yylval.val = rb_str2inum(tok(), 8); return tINTEGER; } - else if (c > '7' && c <= '9') { + if (c > '7' && c <= '9') { yyerror("Illegal octal digit"); } else if (c == '.') { @@ -2840,7 +2885,12 @@ retry: pushback(c); tokfix(); if (is_float) { - yylval.val = rb_float_new(atof(tok())); + double d = strtod(tok(), 0); + if (errno == ERANGE) { + rb_warn("Float %s out of range", tok()); + errno = 0; + } + yylval.val = rb_float_new(d); return tFLOAT; } yylval.val = rb_str2inum(tok(), 10); @@ -2985,7 +3035,7 @@ retry: rb_compile_error("unterminated quoted string meets end of file"); return 0; } - paren = term; + paren = 0; if (term == '(') term = ')'; else if (term == '[') term = ']'; else if (term == '{') term = '}'; @@ -3423,7 +3473,7 @@ block_append(head, tail) end = head->nd_end; } - if (RTEST(rb_verbose)) { + if (RTEST(ruby_verbose)) { NODE *nd = end->nd_head; newline: switch (nd_type(nd)) { |