diff --git a/ChangeLog b/ChangeLog index 9c6e8916de..896e0b2814 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,19 @@ +Thu Jan 9 15:12:30 2003 Yukihiro Matsumoto + + * parse.y (stmt): NODE_NOT elimitation for if/unless/while/until node. + + * parse.y (primary): ditto. + Thu Jan 9 13:26:18 2003 Akinori MUSHA * st.h, st.c: Back out the introduction of st_*_func_t. Some compilers complain about function type mismatch. +Thu Jan 9 02:10:44 2003 Yukihiro Matsumoto + + * eval.c (rb_eval): reduce recursive rb_eval() call by using sort + of continuation passing style. + Wed Jan 08 17:10:32 2003 NAKAMURA Usaku * ext/Win32API/lib/win32/registry.rb: added. [new] diff --git a/eval.c b/eval.c index 86671173d3..e954ac0d67 100644 --- a/eval.c +++ b/eval.c @@ -2209,6 +2209,7 @@ rb_eval(self, n) VALUE self; NODE *n; { + NODE * volatile contnode = 0; NODE * volatile node = n; int state; volatile VALUE result = Qnil; @@ -2224,10 +2225,10 @@ rb_eval(self, n) ruby_current_node = node; switch (nd_type(node)) { case NODE_BLOCK: - while (node->nd_next) { - rb_eval(self, node->nd_head); - node = node->nd_next; + if (contnode) { + rb_bug("nested NODE_BLOCK"); } + contnode = node->nd_next; node = node->nd_head; goto again; @@ -3391,7 +3392,6 @@ rb_eval(self, n) break; case NODE_NEWLINE: - ruby_sourceline = node->nd_nth; if (trace_func) { call_trace_func("line", node, self, ruby_frame->last_func, @@ -3405,6 +3405,11 @@ rb_eval(self, n) } finish: CHECK_INTS; + if (contnode) { + node = contnode; + contnode = 0; + goto again; + } return result; } @@ -4304,7 +4309,7 @@ rb_with_disable_interrupt(proc, data) return result; } -static void +static inline void stack_check() { static int overflowing = 0; diff --git a/parse.y b/parse.y index 0309b41ff0..67da743135 100644 --- a/parse.y +++ b/parse.y @@ -407,11 +407,21 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem { $$ = NEW_IF(cond($3), $1, 0); fixpos($$, $3); + if (nd_type($$->nd_cond) == NODE_NOT) { + $$->nd_cond = $$->nd_cond->nd_body; + $$->nd_else = $$->nd_body; + $$->nd_body = 0; + } } | stmt kUNLESS_MOD expr_value { $$ = NEW_UNLESS(cond($3), $1, 0); fixpos($$, $3); + if (nd_type($$->nd_cond) == NODE_NOT) { + $$->nd_cond = $$->nd_cond->nd_body; + $$->nd_body = $$->nd_else; + $$->nd_else = 0; + } } | stmt kWHILE_MOD expr_value { @@ -421,6 +431,10 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem else { $$ = NEW_WHILE(cond($3), $1, 1); } + if (nd_type($$->nd_cond) == NODE_NOT) { + $$->nd_cond = $$->nd_cond->nd_body; + nd_set_type($$, NODE_UNTIL); + } } | stmt kUNTIL_MOD expr_value { @@ -430,6 +444,10 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem else { $$ = NEW_UNTIL(cond($3), $1, 1); } + if (nd_type($$->nd_cond) == NODE_NOT) { + $$->nd_cond = $$->nd_cond->nd_body; + nd_set_type($$, NODE_WHILE); + } } | klBEGIN { @@ -1440,6 +1458,12 @@ primary : literal { $$ = NEW_IF(cond($2), $4, $5); fixpos($$, $2); + if (nd_type($$->nd_cond) == NODE_NOT) { + NODE *tmp = $$->nd_body; + $$->nd_cond = $$->nd_cond->nd_body; + $$->nd_body = $$->nd_else; + $$->nd_else = tmp; + } } | kUNLESS expr_value then compstmt @@ -1448,6 +1472,12 @@ primary : literal { $$ = NEW_UNLESS(cond($2), $4, $5); fixpos($$, $2); + if (nd_type($$->nd_cond) == NODE_NOT) { + NODE *tmp = $$->nd_body; + $$->nd_cond = $$->nd_cond->nd_body; + $$->nd_body = $$->nd_else; + $$->nd_else = tmp; + } } | kWHILE {COND_PUSH(1);} expr_value do {COND_POP();} compstmt @@ -1455,6 +1485,10 @@ primary : literal { $$ = NEW_WHILE(cond($3), $6, 1); fixpos($$, $3); + if (nd_type($$->nd_cond) == NODE_NOT) { + $$->nd_cond = $$->nd_cond->nd_body; + nd_set_type($$, NODE_UNTIL); + } } | kUNTIL {COND_PUSH(1);} expr_value do {COND_POP();} compstmt @@ -1462,6 +1496,10 @@ primary : literal { $$ = NEW_UNTIL(cond($3), $6, 1); fixpos($$, $3); + if (nd_type($$->nd_cond) == NODE_NOT) { + $$->nd_cond = $$->nd_cond->nd_body; + nd_set_type($$, NODE_WHILE); + } } | kCASE expr_value opt_terms case_body