> According to Vladimir Lipskiy:
> > The patch below implements the missing XORS ops.
>
> Context diffs preferred, I think.

Sure.

Index: string.c
===================================================================
RCS file: /cvs/public/parrot/string.c,v
retrieving revision 1.141
diff -r1.141 string.c


1008,1012c1008
STRING *
string_bitwise_and(struct Parrot_Interp *interpreter, STRING *s1,
               STRING *s2, STRING **dest)
{
    const char *s1start;
    const char *s2start;
    char *dp;
    STRING *res;
    size_t len;

<     len = s1 ? s1->bufused : 0;
<     if (s2 && s2->bufused < len)
<         len = s2->bufused;
<
<     if (dest && *dest)
---
>    if (dest && *dest)
        res = *dest;
    else if (!s1 || !s2)
        res = string_make(interpreter, NULL, 0, NULL, 0, NULL);

    if (!s1 || !s2) {
        res->bufused = 0;
        res->strlen = 0;
        return res;
    }

    /* trigger GC for debug */
    if (interpreter && GC_DEBUG(interpreter))
        Parrot_do_dod_run(interpreter, 1);

    if (s1->type != s2->type || s1->encoding != s2->encoding) {
        s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
                NULL);
        s2 = string_transcode(interpreter, s2, NULL, string_unicode_type,
                NULL);
    }
<     /* get the real len after trancode */
---
>
    len = s1 ? s1->bufused : 0;
    if (s2 && s2->bufused < len)
        len = s2->bufused;
<     if (!dest || *dest)
---
>     if (!dest || !*dest)
        res = string_make(interpreter, NULL, len, s1->encoding, 0,
s1->type);
<
---
>     else if (res->bufused < len)
>         string_grow(interpreter, res, len - res->bufused);
>
    s1start = s1->strstart;
    s2start = s2->strstart;
    dp = res->strstart;
    res->bufused = len;

    for ( ; len ; ++s1start, ++s2start, ++dp, --len)
        *dp = *s1start & *s2start;
    res->strlen = s1->strlen;
    if (s2->strlen < s1->strlen)
        res->strlen = s2->strlen;

    if (dest)
        *dest = res;
    return res;
}

/*=for api string string_bitwise_or
 * or two strings, performing type and encoding conversions if
 * necessary. If *dest != NULL reuse dest, else create a new result
 */
STRING *
string_bitwise_or(struct Parrot_Interp *interpreter, STRING *s1,
               STRING *s2, STRING **dest)
{
    const char *s1start;
    const char *s2start;
    const char *s1end;
    const char *s2end;
    char *dp;
    STRING *res;
    size_t len;

<     len = s1 ? s1->bufused : 0;
<     if (s2 && s2->bufused > len)
<         len = s2->bufused;
---
>
    if (dest && *dest)
        res = *dest;
<     else if (len == 0)
---
>     else if (!s1 && !s2)
>         res = string_make(interpreter, NULL, 0, NULL, 0, NULL);

<     if (!len) {
---
>     if (!s1 && !s2) {
        res->bufused = 0;
        res->strlen = 0;
        return res;
    }

    /* trigger GC for debug */
    if (interpreter && GC_DEBUG(interpreter))
        Parrot_do_dod_run(interpreter, 1);

    if (s1 && s2) {
        if (s1->type != s2->type || s1->encoding != s2->encoding) {
            s1 = string_transcode(interpreter, s1, NULL,
string_unicode_type,
                    NULL);
            s2 = string_transcode(interpreter, s2, NULL,
string_unicode_type,
                    NULL);
        }
    }

    len = s1 ? s1->bufused: 0;
    if (s2 && s2->bufused > len)
        len = s2->bufused;
    if (!dest || !*dest)
        res = string_make(interpreter, NULL, len,
                s1 ? s1->encoding : NULL, 0, s1 ? s1->type : NULL);
    else if (res->bufused < len)
        string_grow(interpreter, res, len - res->bufused);

    if (s1) {
        s1start = s1->strstart;
        s1end = s1start + s1->bufused;
        res->strlen = s1->strlen;
    }
    else
        s1start = s1end = NULL;
    if (s2) {
        s2start = s2->strstart;
        s2end = s2start + s2->bufused;
<         if ((s1 && s2->strlen > s1->strlen) || !s1)
---
>         if (!s1 || s2->strlen > s1->strlen)
            res->strlen = s2->strlen;
    }
    else
        s2start = s2end = NULL;
    dp = res->strstart;
    res->bufused = len;

    for ( ; len ; ++s1start, ++s2start, ++dp, --len) {
        if (s1start < s1end && s2start < s2end)
            *dp = *s1start | *s2start;
        else if (s1start < s1end)
            *dp = *s1start;
        else
            *dp = *s2start;
    }

    if (dest)
        *dest = res;

    return res;
}

<
---
> /*=for api string string_bitwise_xor
>  * or two strings, performing type and encoding conversions if
>  * necessary. If *dest != NULL reuse dest, else create a new result
>  */
> STRING *
> string_bitwise_xor(struct Parrot_Interp *interpreter, STRING *s1,
>                STRING *s2, STRING **dest)
> {
>     const char *s1start;
>     const char *s2start;
>     const char *s1end;
>     const char *s2end;
>     char *dp;
>     STRING *res;
>     size_t len;
>
>     if (dest && *dest)
>         res = *dest;
>     else if (!s1 && !s2)
>         res = string_make(interpreter, NULL, 0, NULL, 0, NULL);
>
>     if (!s1 && !s2) {
>         res->bufused = 0;
>         res->strlen = 0;
>         return res;
>     }
>
>     /* trigger GC for debug */
>     if (interpreter && GC_DEBUG(interpreter))
>         Parrot_do_dod_run(interpreter, 1);
>
>     if (s1 && s2) {
>         if (s1->type != s2->type || s1->encoding != s2->encoding) {
>             s1 = string_transcode(interpreter, s1, NULL,
string_unicode_type,
>                     NULL);
>             s2 = string_transcode(interpreter, s2, NULL,
string_unicode_type,
>                     NULL);
>         }
>     }
>
>     len = s1 ? s1->bufused: 0;
>     if (s2 && s2->bufused > len)
>         len = s2->bufused;
>     if (!dest || !*dest)
>         res = string_make(interpreter, NULL, len,
>                 s1 ? s1->encoding : NULL, 0, s1 ? s1->type : NULL);
>     else if (res->bufused < len)
>         string_grow(interpreter, res, len - res->bufused);
>
>     if (s1) {
>         s1start = s1->strstart;
>         s1end = s1start + s1->bufused;
>         res->strlen = s1->strlen;
>     }
>     else
>         s1start = s1end = NULL;
>     if (s2) {
>         s2start = s2->strstart;
>         s2end = s2start + s2->bufused;
>         if (!s1 || s2->strlen > s1->strlen)
>             res->strlen = s2->strlen;
>     }
>     else
>         s2start = s2end = NULL;
>     dp = res->strstart;
>     res->bufused = len;
>
>     for ( ; len ; ++s1start, ++s2start, ++dp, --len) {
>         if (s1start < s1end && s2start < s2end)
>             *dp = *s1start ^ *s2start;
>         else if (s1start < s1end)
>             *dp = *s1start;
>         else
>             *dp = *s2start;
>     }
>
>     if (dest)
>         *dest = res;
>
>     return res;
> }



Index: bit.ops
===================================================================
RCS file: /cvs/public/parrot/bit.ops,v
retrieving revision 1.2
diff -r1.2 bit.ops

339a340,387
inline op bxor(in PMC, in PMC, in INT) {
  $2->vtable->bitwise_xor_int(interpreter, $2, $3, $1);
  goto NEXT();
}

inline op bxor(in PMC, in PMC, in PMC) {
  $2->vtable->bitwise_xor(interpreter, $2, $3, $1);
  goto NEXT();
}

> =item B<bxors>(inout STR, in STR)
>
> =item B<bxors>(in PMC, in STR)
>
> =item B<bxors>(in PMC, in PMC)
>
> Set the bits of $1 according to the B<xor> of the corresponding bits from
$1 and $2.
>
> =item B<bxors>(out STR, in STR, in STR)
>
> =item B<bxors>(in PMC, in PMC, in STR)
>
> =item B<bxors>(in PMC, in PMC, in PMC)
>
> Set the bits of $1 according to the B<xor> of the corresponding bits from
$2 and $3.
>
> =cut
>
> inline op bxors(inout STR, in STR) {
>   string_bitwise_xor(interpreter, $1, $2, &$1);
>   goto NEXT();
> }
>
> inline op bxors(in PMC, in STR) {
>   $1->vtable->bitwise_xors_str(interpreter, $1, $2, $1);
>   goto NEXT();
> }
>
> inline op bxors(in PMC, in PMC) {
>   $1->vtable->bitwise_xors(interpreter, $1, $2, $1);
>   goto NEXT();
> }
>
> inline op bxors(out STR, in STR, in STR) {
>   $1 = string_bitwise_xor(interpreter, $2, $3, NULL);
>   goto NEXT();
> }
>
> inline op bxors(in PMC, in PMC, in STR) {
>   $2->vtable->bitwise_xors_str(interpreter, $2, $3, $1);
>   goto NEXT();
> }
>
> inline op bxors(in PMC, in PMC, in PMC) {
>   $2->vtable->bitwise_xors(interpreter, $2, $3, $1);
>   goto NEXT();
> }
>
=back

=cut

############################################################################
###

=head1 COPYRIGHT

Copyright (C) 2001-2003 The Perl Foundation.  All rights reserved.



Index: string.t
===================================================================
RCS file: /cvs/public/parrot/t/op/string.t,v
retrieving revision 1.52
diff -r1.52 string.t
3c3
#! perl -w

< use Parrot::Test tests => 113;
---
> use Parrot::Test tests => 116;
use Test::More;

output_is( <<'CODE', <<OUTPUT, "set_s_s|sc" );



1895a1896,1978
output_is( <<'CODE', <<OUTPUT, "bors 3");
 set S1, "abc"
 set S2, "EE"
 bors S0, S1, S2
 print S0
 print "\n"
 print S1
 print "\n"
 print S2
 print "\n"
 end
CODE
egc
abc
EE
OUTPUT

> output_is( <<'CODE', <<OUTPUT, "bxors NULL string");
>  null S1
>  set S2, ""
>  bxors S1, S2
>     null S3
>  eq S1, S3, ok1
>  print "not "
> ok1: print "ok 1\n"
>  bxors S2, S1
>  eq S2, S3, ok2
>  print "not "
> ok2: print "ok 2\n"
>     null S1
>  set S2, "abc"
>     bxors S1, S2
>  eq S1, "abc", ok3
>  print "not "
> ok3: print "ok 3\n"
>     null S2
>     bxors S1, S2
>  eq S1, "abc", ok4
>  print "not "
> ok4: print "ok 4\n"
>     end
> CODE
> ok 1
> ok 2
> ok 3
> ok 4
> OUTPUT
>
> output_is( <<'CODE', <<OUTPUT, "bxors 2");
>  set S1, "a2c"
>  set S2, "Dw"
>  bxors S1, S2
>  print S1
>  print "\n"
>  print S2
>  print "\n"
>     set S1, "abc"
>     set S2, "    "
>     bxors S1, S2
>     print S1
>  print "\n"
>  print S2
>  print "\n"
>  end
> CODE
> %Ec
> Dw
> ABC
>
> OUTPUT
>
> output_is( <<'CODE', <<OUTPUT, "bxors 3");
>  set S1, "a2c"
>  set S2, "Dw"
>  bxors S0, S1, S2
>  print S0
>  print "\n"
>  print S1
>  print "\n"
>  print S2
>  print "\n"
>     set S1, "abc"
>     set S2, "    "
>     bxors S0, S1, S2
>  print S0
>  print "\n"
>     print S1
>  print "\n"
>  print S2
>  print "\n"
>  end
> CODE
> %Ec
> a2c
> Dw
> ABC
> abc
>
>OUTPUT

# Set all string registers to values given by &$_[0](reg num)
sub set_str_regs {
  my $code = shift;


Index: string.c
===================================================================
RCS file: /cvs/public/parrot/string.c,v
retrieving revision 1.141
diff -r1.141 string.c


1008,1012c1008
STRING *
string_bitwise_and(struct Parrot_Interp *interpreter, STRING *s1,
               STRING *s2, STRING **dest)
{
    const char *s1start;
    const char *s2start;
    char *dp;
    STRING *res;
    size_t len;

<     len = s1 ? s1->bufused : 0;
<     if (s2 && s2->bufused < len)
<         len = s2->bufused;
< 
<     if (dest && *dest)
---
>    if (dest && *dest)
        res = *dest;
    else if (!s1 || !s2)
        res = string_make(interpreter, NULL, 0, NULL, 0, NULL);

    if (!s1 || !s2) {
        res->bufused = 0;
        res->strlen = 0;
        return res;
    }

    /* trigger GC for debug */
    if (interpreter && GC_DEBUG(interpreter))
        Parrot_do_dod_run(interpreter, 1);

    if (s1->type != s2->type || s1->encoding != s2->encoding) {
        s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
                NULL);
        s2 = string_transcode(interpreter, s2, NULL, string_unicode_type,
                NULL);
    }
<     /* get the real len after trancode */
---
>     
    len = s1 ? s1->bufused : 0;
    if (s2 && s2->bufused < len)
        len = s2->bufused;
<     if (!dest || *dest)
---
>     if (!dest || !*dest)
        res = string_make(interpreter, NULL, len, s1->encoding, 0, s1->type);
< 
---
>     else if (res->bufused < len)
>         string_grow(interpreter, res, len - res->bufused);
> 
    s1start = s1->strstart;
    s2start = s2->strstart;
    dp = res->strstart;
    res->bufused = len;

    for ( ; len ; ++s1start, ++s2start, ++dp, --len)
        *dp = *s1start & *s2start;
    res->strlen = s1->strlen;
    if (s2->strlen < s1->strlen)
        res->strlen = s2->strlen;

    if (dest)
        *dest = res;
    return res;
}

/*=for api string string_bitwise_or
 * or two strings, performing type and encoding conversions if
 * necessary. If *dest != NULL reuse dest, else create a new result
 */
STRING *
string_bitwise_or(struct Parrot_Interp *interpreter, STRING *s1,
               STRING *s2, STRING **dest)
{
    const char *s1start;
    const char *s2start;
    const char *s1end;
    const char *s2end;
    char *dp;
    STRING *res;
    size_t len;

<     len = s1 ? s1->bufused : 0;
<     if (s2 && s2->bufused > len)
<         len = s2->bufused;
---
> 
    if (dest && *dest)
        res = *dest;
<     else if (len == 0)
---
>     else if (!s1 && !s2)
>         res = string_make(interpreter, NULL, 0, NULL, 0, NULL);
    
<     if (!len) {
---
>     if (!s1 && !s2) {
        res->bufused = 0;
        res->strlen = 0;
        return res;
    }

    /* trigger GC for debug */
    if (interpreter && GC_DEBUG(interpreter))
        Parrot_do_dod_run(interpreter, 1);

    if (s1 && s2) {
        if (s1->type != s2->type || s1->encoding != s2->encoding) {
            s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
                    NULL);
            s2 = string_transcode(interpreter, s2, NULL, string_unicode_type,
                    NULL);
        }
    }
    
    len = s1 ? s1->bufused: 0;
    if (s2 && s2->bufused > len)
        len = s2->bufused;
    if (!dest || !*dest)
        res = string_make(interpreter, NULL, len,
                s1 ? s1->encoding : NULL, 0, s1 ? s1->type : NULL);
    else if (res->bufused < len)
        string_grow(interpreter, res, len - res->bufused);
    
    if (s1) {
        s1start = s1->strstart;
        s1end = s1start + s1->bufused;
        res->strlen = s1->strlen;
    }
    else
        s1start = s1end = NULL;
    if (s2) {
        s2start = s2->strstart;
        s2end = s2start + s2->bufused;
<         if ((s1 && s2->strlen > s1->strlen) || !s1)
---
>         if (!s1 || s2->strlen > s1->strlen)
            res->strlen = s2->strlen;
    }
    else
        s2start = s2end = NULL;
    dp = res->strstart;
    res->bufused = len;

    for ( ; len ; ++s1start, ++s2start, ++dp, --len) {
        if (s1start < s1end && s2start < s2end)
            *dp = *s1start | *s2start;
        else if (s1start < s1end)
            *dp = *s1start;
        else
            *dp = *s2start;
    }

    if (dest)
        *dest = res;

    return res;
}

< 
---
> /*=for api string string_bitwise_xor
>  * or two strings, performing type and encoding conversions if
>  * necessary. If *dest != NULL reuse dest, else create a new result
>  */
> STRING *
> string_bitwise_xor(struct Parrot_Interp *interpreter, STRING *s1,
>                STRING *s2, STRING **dest)
> {
>     const char *s1start;
>     const char *s2start;
>     const char *s1end;
>     const char *s2end;
>     char *dp;
>     STRING *res;
>     size_t len;
> 
>     if (dest && *dest)
>         res = *dest;
>     else if (!s1 && !s2)
>         res = string_make(interpreter, NULL, 0, NULL, 0, NULL);
>     
>     if (!s1 && !s2) {
>         res->bufused = 0;
>         res->strlen = 0;
>         return res;
>     }
> 
>     /* trigger GC for debug */
>     if (interpreter && GC_DEBUG(interpreter))
>         Parrot_do_dod_run(interpreter, 1);
> 
>     if (s1 && s2) {
>         if (s1->type != s2->type || s1->encoding != s2->encoding) {
>             s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
>                     NULL);
>             s2 = string_transcode(interpreter, s2, NULL, string_unicode_type,
>                     NULL);
>         }
>     }
>     
>     len = s1 ? s1->bufused: 0;
>     if (s2 && s2->bufused > len)
>         len = s2->bufused;
>     if (!dest || !*dest)
>         res = string_make(interpreter, NULL, len,
>                 s1 ? s1->encoding : NULL, 0, s1 ? s1->type : NULL);
>     else if (res->bufused < len)
>         string_grow(interpreter, res, len - res->bufused);
>     
>     if (s1) {
>         s1start = s1->strstart;
>         s1end = s1start + s1->bufused;
>         res->strlen = s1->strlen;
>     }
>     else
>         s1start = s1end = NULL;
>     if (s2) {
>         s2start = s2->strstart;
>         s2end = s2start + s2->bufused;
>         if (!s1 || s2->strlen > s1->strlen)
>             res->strlen = s2->strlen;
>     }
>     else
>         s2start = s2end = NULL;
>     dp = res->strstart;
>     res->bufused = len;
> 
>     for ( ; len ; ++s1start, ++s2start, ++dp, --len) {
>         if (s1start < s1end && s2start < s2end)
>             *dp = *s1start ^ *s2start;
>         else if (s1start < s1end)
>             *dp = *s1start;
>         else
>             *dp = *s2start;
>     }
> 
>     if (dest)
>         *dest = res;
> 
>     return res;
> }



Index: bit.ops
===================================================================
RCS file: /cvs/public/parrot/bit.ops,v
retrieving revision 1.2
diff -r1.2 bit.ops

339a340,387
inline op bxor(in PMC, in PMC, in INT) {
  $2->vtable->bitwise_xor_int(interpreter, $2, $3, $1);
  goto NEXT();
}

inline op bxor(in PMC, in PMC, in PMC) {
  $2->vtable->bitwise_xor(interpreter, $2, $3, $1);
  goto NEXT();
}

> =item B<bxors>(inout STR, in STR)
> 
> =item B<bxors>(in PMC, in STR)
> 
> =item B<bxors>(in PMC, in PMC)
> 
> Set the bits of $1 according to the B<xor> of the corresponding bits from $1 and $2.
> 
> =item B<bxors>(out STR, in STR, in STR)
> 
> =item B<bxors>(in PMC, in PMC, in STR)
> 
> =item B<bxors>(in PMC, in PMC, in PMC)
> 
> Set the bits of $1 according to the B<xor> of the corresponding bits from $2 and $3.
> 
> =cut
> 
> inline op bxors(inout STR, in STR) {
>   string_bitwise_xor(interpreter, $1, $2, &$1);
>   goto NEXT();
> }
> 
> inline op bxors(in PMC, in STR) {
>   $1->vtable->bitwise_xors_str(interpreter, $1, $2, $1);
>   goto NEXT();
> }
> 
> inline op bxors(in PMC, in PMC) {
>   $1->vtable->bitwise_xors(interpreter, $1, $2, $1);
>   goto NEXT();
> }
> 
> inline op bxors(out STR, in STR, in STR) {
>   $1 = string_bitwise_xor(interpreter, $2, $3, NULL);
>   goto NEXT();
> }
> 
> inline op bxors(in PMC, in PMC, in STR) {
>   $2->vtable->bitwise_xors_str(interpreter, $2, $3, $1);
>   goto NEXT();
> }
> 
> inline op bxors(in PMC, in PMC, in PMC) {
>   $2->vtable->bitwise_xors(interpreter, $2, $3, $1);
>   goto NEXT();
> }
> 
=back

=cut

###############################################################################

=head1 COPYRIGHT

Copyright (C) 2001-2003 The Perl Foundation.  All rights reserved.



Index: string.t
===================================================================
RCS file: /cvs/public/parrot/t/op/string.t,v
retrieving revision 1.52
diff -r1.52 string.t
3c3
#! perl -w

< use Parrot::Test tests => 113;
---
> use Parrot::Test tests => 116;
use Test::More;

output_is( <<'CODE', <<OUTPUT, "set_s_s|sc" );



1895a1896,1978
output_is( <<'CODE', <<OUTPUT, "bors 3");
        set S1, "abc"
        set S2, "EE"
        bors S0, S1, S2
        print S0
        print "\n"
        print S1
        print "\n"
        print S2
        print "\n"
        end
CODE
egc
abc
EE
OUTPUT

> output_is( <<'CODE', <<OUTPUT, "bxors NULL string");
>       null S1
>       set S2, ""
>       bxors S1, S2
>     null S3
>       eq S1, S3, ok1
>       print "not "
> ok1:  print "ok 1\n"
>       bxors S2, S1
>       eq S2, S3, ok2
>       print "not "
> ok2:  print "ok 2\n"
>     null S1
>       set S2, "abc"
>     bxors S1, S2
>       eq S1, "abc", ok3
>       print "not "
> ok3:  print "ok 3\n"
>     null S2
>     bxors S1, S2
>       eq S1, "abc", ok4
>       print "not "
> ok4:  print "ok 4\n"
>     end
> CODE
> ok 1
> ok 2
> ok 3
> ok 4
> OUTPUT
> 
> output_is( <<'CODE', <<OUTPUT, "bxors 2");
>       set S1, "a2c"
>       set S2, "Dw"
>       bxors S1, S2
>       print S1
>       print "\n"
>       print S2
>       print "\n"
>     set S1, "abc"
>     set S2, "    "
>     bxors S1, S2
>     print S1
>       print "\n"
>       print S2
>       print "\n"
>       end
> CODE
> %Ec
> Dw
> ABC 
>     
> OUTPUT
> 
> output_is( <<'CODE', <<OUTPUT, "bxors 3");
>       set S1, "a2c"
>       set S2, "Dw"
>       bxors S0, S1, S2
>       print S0
>       print "\n"
>       print S1
>       print "\n"
>       print S2
>       print "\n"
>     set S1, "abc"
>     set S2, "    "
>     bxors S0, S1, S2
>       print S0
>       print "\n"
>     print S1
>       print "\n"
>       print S2
>       print "\n"
>       end
> CODE
> %Ec
> a2c
> Dw
> ABC 
> abc
>    
>OUTPUT

# Set all string registers to values given by &$_[0](reg num)
sub set_str_regs {
  my $code = shift;

Reply via email to