* 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
This commit is contained in:
parent
197535b5eb
commit
4a497026b6
@ -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
|
||||
|
107
eval.c
107
eval.c
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user