> I have checked in some functionality for string bitwise ops. > - vtable > - B<ands>, B<ors> opcodes > - string_bitwise_{or,and} functions in string.c > - minimal tests > > Missing: > - B<xors> ops > - support for perl scalar PMCs > > I'd be glad if someone wants to continue that stuff.
The patch below implements the missing XORS ops. And if this patch is okay and nobody objects, I'd like to continue that stuff (supporting for perl scalar PMCs). Index: string.c =================================================================== RCS file: /cvs/public/parrot/string.c,v retrieving revision 1.141 diff -r1.141 string.c 1008,1012c1008 < len = s1 ? s1->bufused : 0; < if (s2 && s2->bufused < len) < len = s2->bufused; < < if (dest && *dest) --- > if (dest && *dest) 1033c1029 < /* get the real len after trancode */ --- > 1037c1033 < if (!dest || *dest) --- > if (!dest || !*dest) 1039c1035,1037 < --- > else if (res->bufused < len) > string_grow(interpreter, res, len - res->bufused); > 1072c1070,1094 < len = s1 ? s1->bufused : 0; --- > 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; 1074a1097,1150 > 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) > 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; 1078c1154 < else if (len == 0) --- > else if (!s1 && !s2) 1080c1156,1157 < if (!len) { --- > > if (!s1 && !s2) { 1097a1175 > 1106c1184 < --- > 1127c1205 < *dp = *s1start | *s2start; --- > *dp = *s1start ^ *s2start; 1132a1211 > 1137a1217 > Index: bit.ops =================================================================== RCS file: /cvs/public/parrot/bit.ops,v retrieving revision 1.2 diff -r1.2 bit.ops 339a340,387 > =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(); > } > Index: string.t =================================================================== RCS file: /cvs/public/parrot/t/op/string.t,v retrieving revision 1.52 diff -r1.52 string.t 3c3 < use Parrot::Test tests => 113; --- > use Parrot::Test tests => 116; 1839c1839 < output_is( <<'CODE', <<OUTPUT, "bors NULL string"); --- > output_is(<<'CODE', <<OUTPUT, "bors NULL string"); 1895a1896,1978 > 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 >
Index: string.c =================================================================== RCS file: /cvs/public/parrot/string.c,v retrieving revision 1.141 diff -r1.141 string.c 1008,1012c1008 < len = s1 ? s1->bufused : 0; < if (s2 && s2->bufused < len) < len = s2->bufused; < < if (dest && *dest) --- > if (dest && *dest) 1033c1029 < /* get the real len after trancode */ --- > 1037c1033 < if (!dest || *dest) --- > if (!dest || !*dest) 1039c1035,1037 < --- > else if (res->bufused < len) > string_grow(interpreter, res, len - res->bufused); > 1072c1070,1094 < len = s1 ? s1->bufused : 0; --- > 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; 1074a1097,1150 > 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) > 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; 1078c1154 < else if (len == 0) --- > else if (!s1 && !s2) 1080c1156,1157 < if (!len) { --- > > if (!s1 && !s2) { 1097a1175 > 1106c1184 < --- > 1127c1205 < *dp = *s1start | *s2start; --- > *dp = *s1start ^ *s2start; 1132a1211 > 1137a1217 > Index: bit.ops =================================================================== RCS file: /cvs/public/parrot/bit.ops,v retrieving revision 1.2 diff -r1.2 bit.ops 339a340,387 > =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(); > } > Index: string.t =================================================================== RCS file: /cvs/public/parrot/t/op/string.t,v retrieving revision 1.52 diff -r1.52 string.t 3c3 < use Parrot::Test tests => 113; --- > use Parrot::Test tests => 116; 1839c1839 < output_is( <<'CODE', <<OUTPUT, "bors NULL string"); --- > output_is(<<'CODE', <<OUTPUT, "bors NULL string"); 1895a1896,1978 > 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 >