summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>2009-05-09 17:47:31 +0200
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2009-05-09 17:47:31 +0200
commitea0c2dbd5f5ac6845ecc7ec6696415bf8e27bd52 (patch)
tree72faa9699aa372f43133eb6de7ae99146e78a73f
parent90a32bcb5e6a686bec0d5726c12e209e6c769d92 (diff)
downloadperl-ea0c2dbd5f5ac6845ecc7ec6696415bf8e27bd52.tar.gz
Implement Hash/Array ~~ Regex (with tests)
-rw-r--r--pp_ctl.c74
-rw-r--r--t/op/smartmatch.t31
2 files changed, 60 insertions, 45 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index c6bb46ab5e..27a4c03195 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4203,20 +4203,23 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
RETPUSHNO;
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_REGEXP) {
- PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
- HE *he;
- HV *hv = MUTABLE_HV(SvRV(e));
-
- (void) hv_iterinit(hv);
- while ( (he = hv_iternext(hv)) ) {
- if (matcher_matches_sv(matcher, hv_iterkeysv(he))) {
- (void) hv_iterinit(hv);
- destroy_matcher(matcher);
- RETPUSHYES;
+ sm_regex_hash:
+ {
+ PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
+ HE *he;
+ HV *hv = MUTABLE_HV(SvRV(e));
+
+ (void) hv_iterinit(hv);
+ while ( (he = hv_iternext(hv)) ) {
+ if (matcher_matches_sv(matcher, hv_iterkeysv(he))) {
+ (void) hv_iterinit(hv);
+ destroy_matcher(matcher);
+ RETPUSHYES;
+ }
}
+ destroy_matcher(matcher);
+ RETPUSHNO;
}
- destroy_matcher(matcher);
- RETPUSHNO;
}
else {
sm_any_hash:
@@ -4303,19 +4306,22 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
}
}
else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_REGEXP) {
- PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
- const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
- I32 i;
+ sm_regex_array:
+ {
+ PMOP * const matcher = make_matcher((REGEXP*) SvRV(d));
+ const I32 this_len = av_len(MUTABLE_AV(SvRV(e)));
+ I32 i;
- for(i = 0; i <= this_len; ++i) {
- SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
- if (svp && matcher_matches_sv(matcher, *svp)) {
- destroy_matcher(matcher);
- RETPUSHYES;
+ for(i = 0; i <= this_len; ++i) {
+ SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
+ if (svp && matcher_matches_sv(matcher, *svp)) {
+ destroy_matcher(matcher);
+ RETPUSHYES;
+ }
}
+ destroy_matcher(matcher);
+ RETPUSHNO;
}
- destroy_matcher(matcher);
- RETPUSHNO;
}
else if (!SvOK(d)) {
/* undef ~~ array */
@@ -4355,14 +4361,24 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
}
/* ~~ qr// */
else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_REGEXP) {
- PMOP * const matcher = make_matcher((REGEXP*) SvRV(e));
+ if (!object_on_left && SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
+ SV *t = d; d = e; e = t;
+ goto sm_regex_hash;
+ }
+ else if (!object_on_left && SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
+ SV *t = d; d = e; e = t;
+ goto sm_regex_array;
+ }
+ else {
+ PMOP * const matcher = make_matcher((REGEXP*) SvRV(e));
- PUTBACK;
- PUSHs(matcher_matches_sv(matcher, d)
- ? &PL_sv_yes
- : &PL_sv_no);
- destroy_matcher(matcher);
- RETURN;
+ PUTBACK;
+ PUSHs(matcher_matches_sv(matcher, d)
+ ? &PL_sv_yes
+ : &PL_sv_no);
+ destroy_matcher(matcher);
+ RETURN;
+ }
}
/* ~~ X..Y TODO */
/* ~~ scalar */
diff --git a/t/op/smartmatch.t b/t/op/smartmatch.t
index 3124b7a485..eb14bf032c 100644
--- a/t/op/smartmatch.t
+++ b/t/op/smartmatch.t
@@ -266,16 +266,15 @@ __DATA__
= \@fooormore %fooormore
# - a regex
-# TODO those should be symmetrical
- qr/^(fo[ox])$/ {foo => 1}
- /^(fo[ox])$/ %fooormore
+= qr/^(fo[ox])$/ {foo => 1}
+= /^(fo[ox])$/ %fooormore
=! qr/[13579]$/ +{0..99}
-! qr/a*/ {}
+=! qr/a*/ {}
= qr/a*/ {b=>2}
- qr/B/i {b=>2}
- /B/i {b=>2}
-! qr/a+/ {b=>2}
- qr/^à/ {"à"=>2}
+= qr/B/i {b=>2}
+= /B/i {b=>2}
+=! qr/a+/ {b=>2}
+= qr/^à/ {"à"=>2}
# - a scalar
"foo" +{foo => 1, bar => 2}
@@ -301,8 +300,8 @@ __DATA__
# - another array ref
[] []
=! [] [1]
-! [["foo"], ["bar"]] [qr/o/, qr/a/]
- [["foo"], ["bar"]] [qr/ARRAY/, qr/ARRAY/]
+ [["foo"], ["bar"]] [qr/o/, qr/a/]
+! [["foo"], ["bar"]] [qr/ARRAY/, qr/ARRAY/]
["foo", "bar"] [qr/o/, qr/a/]
! [qr/o/, qr/a/] ["foo", "bar"]
["foo", "bar"] [["foo"], ["bar"]]
@@ -328,12 +327,12 @@ __DATA__
"foo" ('foo','bar') TODO
# - a regex
- qr/x/ [qw(foo bar baz quux)]
-! qr/y/ [qw(foo bar baz quux)]
- /x/ [qw(foo bar baz quux)]
-! /y/ [qw(foo bar baz quux)]
- /FOO/i @fooormore
-! /bar/ @fooormore
+= qr/x/ [qw(foo bar baz quux)]
+=! qr/y/ [qw(foo bar baz quux)]
+= /x/ [qw(foo bar baz quux)]
+=! /y/ [qw(foo bar baz quux)]
+= /FOO/i @fooormore
+=! /bar/ @fooormore
# - a number
2 [qw(1.00 2.00)]