Hi,
At Fri, 13 Apr 2007 15:50:11 +0900,
Robert Klemme wrote in [ruby-talk:247769]:
I think it's worth the effort only if a) it really accepts "unlimited"
cases and b) it doesn't cost performance. (Haven't checked either)
In this case, yes for a, and almost yes for b, I guess.
Since there was a typo in [ruby-talk:247527], merged patch of
[ruby-talk:247527] and [ruby-talk:247595].
Index: parse.y
===================================================================
--- parse.y (revision 12203)
+++ parse.y (working copy)
@@ -273,5 +273,5 @@ static void top_local_setup();
%type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
%type <node> expr_value arg_value primary_value
-%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
+%type <node> if_then opt_else case_body cases opt_rescue rescue exc_list exc_var opt_ensure
%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
@@ -376,5 +376,7 @@ bodystmt : compstmt
$$ = $1;
if ($2) {
- $$ = NEW_RESCUE($1, $2, $3);
+ $$ = $2;
+ $$->nd_head = $1;
+ $$->nd_else = $3;
}
else if ($3) {
@@ -1553,11 +1555,9 @@ primary : literal
fixpos($$, $1);
}
- | kIF expr_value then
- compstmt
- if_tail
- kEND
+ | if_then opt_else kEND
{
- $$ = NEW_IF(cond($2), $4, $5);
- fixpos($$, $2);
+ $1->nd_else->nd_else = $2;
+ $$ = $1->nd_body;
+ rb_gc_force_recycle((VALUE)$1);
if (cond_negative(&$$->nd_cond)) {
NODE *tmp = $$->nd_body;
@@ -1599,14 +1599,16 @@ primary : literal
}
}
- | kCASE expr_value opt_terms
- case_body
- kEND
+ | kCASE expr_value opt_terms cases opt_else kEND
{
- $$ = NEW_CASE($2, $4);
+ $4->nd_head->nd_next = $5;
+ $4->nd_head = $2;
+ $$ = $4;
fixpos($$, $2);
}
- | kCASE opt_terms case_body kEND
+ | kCASE opt_terms cases opt_else kEND
{
- $$ = $3;
+ $3->nd_head->nd_next = $4;
+ $$ = $3->nd_body;
+ rb_gc_force_recycle((VALUE)$3);
}
| kCASE opt_terms kELSE compstmt kEND
@@ -1744,18 +1746,26 @@ do : term
;
-if_tail : opt_else
- | kELSIF expr_value then
- compstmt
- if_tail
+opt_else : none
+ | kELSE compstmt
{
- $$ = NEW_IF(cond($2), $4, $5);
- fixpos($$, $2);
+ $$ = $2;
}
;
-opt_else : none
- | kELSE compstmt
+if_then : kIF expr_value then
+ compstmt
{
- $$ = $2;
+ $$ = NEW_IF(cond($2), $4, 0);
+ fixpos($$, $2);
+ $$ = NEW_IF(0, $$, $$);
+ }
+ | if_then kELSIF expr_value then
+ compstmt
+ {
+ NODE *elsif = NEW_IF(cond($3), $5, 0);
+ fixpos(elsif, $3);
+ $$ = $1;
+ $$->nd_else->nd_else = elsif;
+ $$->nd_else = elsif;
}
;
@@ -1871,7 +1881,6 @@ brace_block : '{'
case_body : kWHEN when_args then
compstmt
- cases
{
- $$ = NEW_WHEN($2, $4, $5);
+ $$ = NEW_WHEN($2, $4, 0);
}
;
@@ -1887,11 +1896,34 @@ when_args : args
;
-cases : opt_else
- | case_body
+cases : case_body
+ {
+ $$ = NEW_CASE($1, $1);
+ }
+ | cases
+ case_body
+ {
+ $$ = $1;
+ $$->nd_head->nd_next = $2;
+ $$->nd_head = $2;
+ }
;
-opt_rescue : kRESCUE exc_list exc_var then
+opt_rescue : none
+ | opt_rescue
+ rescue
+ {
+ if ($1) {
+ $1->nd_head->nd_head = $2;
+ $1->nd_head = $2;
+ $$ = $1;
+ }
+ else {
+ $$ = NEW_RESCUE($2, $2, 0);
+ }
+ }
+ ;
+
+rescue : kRESCUE exc_list exc_var then
compstmt
- opt_rescue
{
if ($3) {
@@ -1899,8 +1931,7 @@ opt_rescue : kRESCUE exc_list exc_var th
$5 = block_append($3, $5);
}
- $$ = NEW_RESBODY($2, $5, $6);
+ $$ = NEW_RESBODY($2, $5, 0);
fixpos($$, $2?$2:$5);
}
- | none
;
@@ -6109,4 +6140,5 @@ rb_id2name(id)
{
char *name;
+ st_data_t data;
if (id < tLAST_TOKEN) {
@@ -6119,6 +6151,6 @@ rb_id2name(id)
}
- if (st_lookup(sym_rev_tbl, id, (st_data_t *)&name))
- return name;
+ if (st_lookup(sym_rev_tbl, id, &data))
+ return (char *)data;
if (is_attrset_id(id)) {
@@ -6333,5 +6365,5 @@ rb_parser_free(ptr)
NODE **prev = &parser_heap, *n;
- while (n = *prev) {
+ while ((n = *prev) != 0) {
if (n->u1.node == ptr) {
*prev = n->u2.node;