Refactoring work on '~~ @array' implementation
Rafael Garcia-Suarez [Mon, 23 Mar 2009 15:57:57 +0000 (16:57 +0100)]
(remove commutativity)

pp_ctl.c
t/op/smartmatch.t

index 3977953..a7cee5a 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4029,10 +4029,6 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
     SV *This, *Other;  /* 'This' (and Other to match) to play with C++ */
     REGEXP *this_regex, *other_regex;
 
-#   define SM_REF(type) ( \
-          (SvROK(d) && (SvTYPE(This = SvRV(d)) == SVt_##type) && (Other = e)) \
-       || (SvROK(e) && (SvTYPE(This = SvRV(e)) == SVt_##type) && (Other = d)))
-
 #   define SM_REGEX ( \
           (SvROK(d) && (SvTYPE(This = SvRV(d)) == SVt_REGEXP)          \
        && (this_regex = (REGEXP*) This)                                \
@@ -4042,14 +4038,6 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
        && (this_regex = (REGEXP*) This)                                \
        && (Other = d)) )
        
-#   define SM_OTHER_REF(type) \
-       (SvROK(Other) && SvTYPE(SvRV(Other)) == SVt_##type)
-
-#   define SM_OTHER_REGEX (SvROK(Other)                                        \
-       && (SvTYPE(SvRV(Other)) == SVt_REGEXP)                          \
-       && (other_regex = (REGEXP*) SvRV(Other)))
-
-
 #   define SM_SEEN_THIS(sv) hv_exists_ent(seen_this, \
        sv_2mortal(newSViv(PTR2IV(sv))), 0)
 
@@ -4073,6 +4061,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
     if (SvGMAGICAL(e))
        e = sv_mortalcopy(e);
 
+    /* ~~ undef */
     if (!SvOK(e)) {
        if (SvOK(d))
            RETPUSHNO;
@@ -4084,6 +4073,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
            || (sv_isobject(e) && (SvTYPE(SvRV(e)) != SVt_REGEXP)))
        Perl_croak(aTHX_ "Smart matching a non-overloaded object breaks encapsulation");
 
+    /* ~~ sub */
     if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_PVCV) {
        I32 c;
        if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
@@ -4161,6 +4151,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
            RETURN;
        }
     }
+    /* ~~ %hash */
     else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_PVHV) {
        if (!SvOK(d)) {
            RETPUSHNO;
@@ -4263,10 +4254,30 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
                RETPUSHNO;
        }
     }
-    else if (SM_REF(PVAV)) {
-       if (SM_OTHER_REF(PVAV)) {
-           AV *other_av = MUTABLE_AV(SvRV(Other));
-           if (av_len(MUTABLE_AV(This)) != av_len(other_av))
+    /* ~~ @array */
+    else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_PVAV) {
+       This = SvRV(e);
+       if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) {
+           AV * const other_av = MUTABLE_AV(SvRV(e));
+           const I32 other_len = av_len(other_av) + 1;
+           I32 i;
+
+           for (i = 0; i < other_len; ++i) {
+               SV ** const svp = av_fetch(other_av, i, FALSE);
+               char *key;
+               STRLEN key_len;
+
+               if (svp) {      /* ??? When can this not happen? */
+                   key = SvPV(*svp, key_len);
+                   if (hv_exists(MUTABLE_HV(SvRV(d)), key, key_len))
+                       RETPUSHYES;
+               }
+           }
+           RETPUSHNO;
+       }
+       if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) {
+           AV *other_av = MUTABLE_AV(SvRV(d));
+           if (av_len(MUTABLE_AV(SvRV(e))) != av_len(other_av))
                RETPUSHNO;
            else {
                I32 i;
@@ -4281,7 +4292,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
                    (void) sv_2mortal(MUTABLE_SV(seen_other));
                }
                for(i = 0; i <= other_len; ++i) {
-                   SV * const * const this_elem = av_fetch(MUTABLE_AV(This), i, FALSE);
+                   SV * const * const this_elem = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
                    SV * const * const other_elem = av_fetch(other_av, i, FALSE);
 
                    if (!this_elem || !other_elem) {
@@ -4315,13 +4326,14 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
                RETPUSHYES;
            }
        }
-       else if (SM_OTHER_REGEX) {
+       else if (SvROK(d) && (SvTYPE(SvRV(d)) == SVt_REGEXP)
+               && (other_regex = (REGEXP*) SvRV(d))) {
            PMOP * const matcher = make_matcher(other_regex);
-           const I32 this_len = av_len(MUTABLE_AV(This));
+           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(This), i, FALSE);
+               SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
                if (svp && matcher_matches_sv(matcher, *svp)) {
                    destroy_matcher(matcher);
                    RETPUSHYES;
@@ -4330,15 +4342,15 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
            destroy_matcher(matcher);
            RETPUSHNO;
        }
-       else if (SvIOK(Other) || SvNOK(Other)) {
+       else if (SvIOK(d) || SvNOK(d)) {
            I32 i;
 
-           for(i = 0; i <= AvFILL(MUTABLE_AV(This)); ++i) {
-               SV * const * const svp = av_fetch(MUTABLE_AV(This), i, FALSE);
+           for(i = 0; i <= AvFILL(MUTABLE_AV(SvRV(e))); ++i) {
+               SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
                if (!svp)
                    continue;
                
-               PUSHs(Other);
+               PUSHs(d);
                PUSHs(*svp);
                PUTBACK;
                if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
@@ -4351,16 +4363,16 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
            }
            RETPUSHNO;
        }
-       else if (SvPOK(Other)) {
-           const I32 this_len = av_len(MUTABLE_AV(This));
+       else if (SvPOK(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(This), i, FALSE);
+               SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
                if (!svp)
                    continue;
                
-               PUSHs(Other);
+               PUSHs(d);
                PUSHs(*svp);
                PUTBACK;
                (void) pp_seq();
@@ -4371,6 +4383,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
            RETPUSHNO;
        }
     }
+    /* ~~ qr// */
     else if (SM_REGEX) {
        PMOP * const matcher = make_matcher(this_regex);
 
@@ -4381,6 +4394,8 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
        destroy_matcher(matcher);
        RETURN;
     }
+    /* ~~ X..Y TODO */
+    /* ~~ scalar */
     else if ( ((SvIOK(d) || SvNOK(d)) && (This = d) && (Other = e))
          ||   ((SvIOK(e) || SvNOK(e)) && (This = e) && (Other = d)) )
     {
index d336cfc..9511acc 100644 (file)
@@ -153,9 +153,9 @@ __DATA__
 =      $ov_obj         {"key" => 1}
 =      $ov_obj         {"key" => 1, bar => 2}          TODO
 =!     $ov_obj         {"foo" => 1}
-=      $ov_obj         @keyandmore                     TODO
+=      $ov_obj         @keyandmore
 =!     $ov_obj         @fooormore
-=      $ov_obj         ["key" => 1]                    TODO
+=      $ov_obj         ["key" => 1]
 =!     $ov_obj         ["foo" => 1]
 =      $ov_obj         /key/                           TODO
 =!     $ov_obj         /foo/
@@ -284,18 +284,20 @@ __DATA__
        \@nums                  \@tied_nums
 
 #  - a regex
-       [qw(foo bar baz quux)]  qr/x/
-!      [qw(foo bar baz quux)]  qr/y/
+       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)]
 
 # - a number
-       [qw(1foo 2bar)]         2
-       [qw(foo 2)]             2
-       [qw(foo 2)]             2.0_0e+0
-!      [qw(1foo bar2)]         2
+       2               [qw(1foo 2bar)]
+       2               [qw(foo 2)]
+       2.0_0e+0        [qw(foo 2)]
+!      2               [qw(1foo bar2)]
 
 # - a string
-!      [qw(1foo 2bar)]         "2"
-       [qw(1foo 2bar)]         "2bar"
+!      "2"             [qw(1foo 2bar)]
+       "2bar"          [qw(1foo 2bar)]
 
 # Number against number
        2               2
@@ -317,9 +319,8 @@ __DATA__
 # Regex against number
        12345           qr/3/
 
-
 # Test the implicit referencing
-       @nums           7
+       7               @nums
        @nums           \@nums
 !      @nums           \\@nums
        @nums           [1..10]