> 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;