summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-08 04:25:36 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-08 04:25:36 +0000
commitd458cea6403e6b4403215d41438d2ca7567035ba (patch)
tree870170f499b11a9d840ab7969f00d2d4e7d4623b /parse.y
parent46e4dcf09d288c0771c4aa4bae9babb21e89bf58 (diff)
merge revision(s) 18356:
* parse.y (deferred_nodes, compstmt, arg, fixup_nodes, range_op): fix up fixnum range literal in conditional as automagical line number comparison. [ruby-core:12124], [ruby-dev:35731] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@21385 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y58
1 files changed, 44 insertions, 14 deletions
diff --git a/parse.y b/parse.y
index 452d209..101ac19 100644
--- a/parse.y
+++ b/parse.y
@@ -124,6 +124,8 @@ static int compile_for_eval = 0;
static ID cur_mid = 0;
static int command_start = Qtrue;
+static NODE *deferred_nodes;
+
static NODE *cond();
static NODE *logop();
static int cond_negative();
@@ -181,6 +183,8 @@ static NODE *dyna_init();
static void top_local_init();
static void top_local_setup();
+static void fixup_nodes();
+
#define RE_OPTION_ONCE 0x80
#define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
@@ -394,6 +398,7 @@ bodystmt : compstmt
compstmt : stmts opt_terms
{
void_stmts($1);
+ fixup_nodes(&deferred_nodes);
$$ = $1;
}
;
@@ -1080,26 +1085,20 @@ arg : lhs '=' arg
{
value_expr($1);
value_expr($3);
+ $$ = NEW_DOT2($1, $3);
if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
- $1->nd_lit = rb_range_new($1->nd_lit, $3->nd_lit, Qfalse);
- $$ = $1;
- }
- else {
- $$ = NEW_DOT2($1, $3);
+ deferred_nodes = list_append(deferred_nodes, $$);
}
}
| arg tDOT3 arg
{
value_expr($1);
value_expr($3);
+ $$ = NEW_DOT3($1, $3);
if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
- $1->nd_lit = rb_range_new($1->nd_lit, $3->nd_lit, Qtrue);
- $$ = $1;
- }
- else {
- $$ = NEW_DOT3($1, $3);
+ deferred_nodes = list_append(deferred_nodes, $$);
}
}
| arg '+' arg
@@ -2689,6 +2688,7 @@ yycompile(f, line)
lex_strterm = 0;
ruby_current_node = 0;
ruby_sourcefile = rb_source_filename(f);
+ deferred_nodes = 0;
n = yyparse();
ruby_debug_lines = 0;
compile_for_eval = 0;
@@ -2700,6 +2700,7 @@ yycompile(f, line)
in_single = 0;
in_def = 0;
cur_mid = 0;
+ deferred_nodes = 0;
vp = ruby_dyna_vars;
ruby_dyna_vars = vars;
@@ -5376,6 +5377,36 @@ warning_unless_e_option(node, str)
if (!e_option_supplied()) parser_warning(node, str);
}
+static void
+fixup_nodes(rootnode)
+ NODE **rootnode;
+{
+ NODE *node, *next, *head;
+
+ for (node = *rootnode; node; node = next) {
+ enum node_type type;
+ VALUE val;
+
+ next = node->nd_next;
+ head = node->nd_head;
+ rb_gc_force_recycle((VALUE)node);
+ *rootnode = next;
+ switch (type = nd_type(head)) {
+ case NODE_DOT2:
+ case NODE_DOT3:
+ val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
+ type == NODE_DOT3 ? Qtrue : Qfalse);
+ rb_gc_force_recycle((VALUE)head->nd_beg);
+ rb_gc_force_recycle((VALUE)head->nd_end);
+ nd_set_type(head, NODE_LIT);
+ head->nd_lit = val;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
static NODE *cond0();
static NODE*
@@ -5384,21 +5415,19 @@ range_op(node)
{
enum node_type type;
- if (!e_option_supplied()) return node;
if (node == 0) return 0;
- value_expr(node);
- node = cond0(node);
type = nd_type(node);
if (type == NODE_NEWLINE) {
node = node->nd_next;
type = nd_type(node);
}
+ value_expr(node);
if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
warn_unless_e_option(node, "integer literal in conditional range");
return call_op(node,tEQ,1,NEW_GVAR(rb_intern("$.")));
}
- return node;
+ return cond0(node);
}
static int
@@ -5919,6 +5948,7 @@ rb_gc_mark_parser()
rb_gc_mark(lex_lastline);
rb_gc_mark(lex_input);
rb_gc_mark((VALUE)lex_strterm);
+ rb_gc_mark((VALUE)deferred_nodes);
}
void