diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-06-27 16:51:08 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-06-27 16:51:08 +0000 |
commit | 4a497026b6270d6d7d066007e1a2a85b0490b554 (patch) | |
tree | bad1d79253373bfa2bd485bf4a47f7b7dbf1fde6 | |
parent | 197535b5ebfd311e491fbda601a6c26899f81bed (diff) |
* eval.c (rb_eval): support splat in when expression list.
[ruby-dev:28822]
* eval.c (when_check): a new auxiliary function for case match.
* eval.c (when_cond): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | eval.c | 107 |
2 files changed, 64 insertions, 52 deletions
@@ -1,3 +1,12 @@ +Wed Jun 28 01:48:23 2006 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_eval): support splat in when expression list. + [ruby-dev:28822] + + * eval.c (when_check): a new auxiliary function for case match. + + * eval.c (when_cond): ditto. + Wed Jun 28 01:05:37 2006 Yukihiro Matsumoto <matz@ruby-lang.org> * object.c (rb_cstr_to_dbl): should not skip '_' at the beginning @@ -2674,6 +2674,48 @@ unknown_node(NODE *volatile node) } } +static int +when_cond(VALUE v1, VALUE v2) +{ + if (v1 == Qundef) { + return RTEST(v2); + } + return RTEST(rb_funcall2(v2, eqq, 1, &v1)); +} + +static int +when_check(NODE *tag, VALUE val, VALUE self) +{ + VALUE elm; + long i; + + switch (nd_type(tag)) { + case NODE_ARRAY: + while (tag) { + elm = rb_eval(self, tag->nd_head); + if (when_cond(val, elm)) { + return Qtrue; + } + tag = tag->nd_next; + } + break; + case NODE_SPLAT: + elm = svalue_to_avalue(rb_eval(self, tag->nd_head)); + for (i=0; i<RARRAY(elm)->len; i++) { + if (when_cond(val, RARRAY(elm)->ptr[i])) { + return Qtrue; + } + } + break; + case NODE_ARGSCAT: + if (when_check(tag->nd_head, val, self)) return Qtrue; + return when_check(tag->nd_body, val, self); + default: + unknown_node(tag); + } + return Qfalse; +} + static VALUE rb_eval(VALUE self, NODE *n) { @@ -2804,34 +2846,15 @@ rb_eval(VALUE self, NODE *n) goto again; case NODE_WHEN: + node = node->nd_body; while (node) { - NODE *tag; - if (nd_type(node) != NODE_WHEN) goto again; - tag = node->nd_head; - while (tag) { - EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self, - ruby_frame->this_func, - ruby_frame->this_class); - if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) { - VALUE v = rb_eval(self, tag->nd_head->nd_head); - long i; - - if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v); - for (i=0; i<RARRAY(v)->len; i++) { - if (RTEST(RARRAY(v)->ptr[i])) { - node = node->nd_body; - goto again; - } - } - tag = tag->nd_next; - continue; - } - if (RTEST(rb_eval(self, tag->nd_head))) { - node = node->nd_body; - goto again; - } - tag = tag->nd_next; + EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node->nd_head, self, + ruby_frame->this_func, + ruby_frame->this_class); + if (when_check(node->nd_head, Qundef, self)) { + node = node->nd_body; + goto again; } node = node->nd_next; } @@ -2844,35 +2867,15 @@ rb_eval(VALUE self, NODE *n) val = rb_eval(self, node->nd_head); node = node->nd_body; while (node) { - NODE *tag; - if (nd_type(node) != NODE_WHEN) { goto again; } - tag = node->nd_head; - while (tag) { - EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self, - ruby_frame->this_func, - ruby_frame->this_class); - if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) { - VALUE v = rb_eval(self, tag->nd_head->nd_head); - long i; - - if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v); - for (i=0; i<RARRAY(v)->len; i++) { - if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){ - node = node->nd_body; - goto again; - } - } - tag = tag->nd_next; - continue; - } - if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val))) { - node = node->nd_body; - goto again; - } - tag = tag->nd_next; + EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node->nd_head, self, + ruby_frame->this_func, + ruby_frame->this_class); + if (when_check(node->nd_head, val, self)) { + node = node->nd_body; + goto again; } node = node->nd_next; } |