summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-06-27 16:51:08 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-06-27 16:51:08 +0000
commit4a497026b6270d6d7d066007e1a2a85b0490b554 (patch)
treebad1d79253373bfa2bd485bf4a47f7b7dbf1fde6 /eval.c
parent197535b5ebfd311e491fbda601a6c26899f81bed (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
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c107
1 files changed, 55 insertions, 52 deletions
diff --git a/eval.c b/eval.c
index c08b98128f..e9775fa308 100644
--- a/eval.c
+++ b/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;
}