summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y102
1 files changed, 76 insertions, 26 deletions
diff --git a/parse.y b/parse.y
index a4142bbe20..1e9e2f1f71 100644
--- a/parse.y
+++ b/parse.y
@@ -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)) {