From: Rafael Garcia-Suarez Date: Sat, 9 May 2009 15:47:31 +0000 (+0200) Subject: Implement Hash/Array ~~ Regex (with tests) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ea0c2dbd5f5ac6845ecc7ec6696415bf8e27bd52;p=p5sagit%2Fp5-mst-13.2.git Implement Hash/Array ~~ Regex (with tests) --- diff --git a/pp_ctl.c b/pp_ctl.c index c6bb46a..27a4c03 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 3124b7a..eb14bf0 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)]