Skip to content

Commit af59ead

Browse files
committed
Support bitwise xor operator for type parameters.
1 parent c6df48a commit af59ead

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

compiler/expressions.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,8 @@ func (fc *funcContext) translateBinaryExpr(e *ast.BinaryExpr) *expression {
700700
return fc.formatExpr("%s.and(%e, %e)", fc.typeName(t), e.X, e.Y)
701701
case token.OR:
702702
return fc.formatExpr("%s.or(%e, %e)", fc.typeName(t), e.X, e.Y)
703+
case token.XOR:
704+
return fc.formatExpr("%s.xor(%e, %e)", fc.typeName(t), e.X, e.Y)
703705
}
704706
}
705707

compiler/prelude/types.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
427427
typ.rem = $irem;
428428
typ.and = (x, y) => (x & y);
429429
typ.or = (x, y) => (x | y);
430+
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
430431
break;
431432
case $kindUint8:
432433
case $kindUint16:
@@ -437,6 +438,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
437438
typ.rem = $irem;
438439
typ.and = (x, y) => (x & y) >>> 0;
439440
typ.or = (x, y) => (x | y) >>> 0;
441+
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
440442
break;
441443
case $kindUint:
442444
case $kindUint32:
@@ -448,6 +450,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
448450
typ.rem = $irem;
449451
typ.and = (x, y) => (x & y) >>> 0;
450452
typ.or = (x, y) => (x | y) >>> 0;
453+
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
451454
break;
452455
case $kindInt:
453456
case $kindInt32:
@@ -458,6 +461,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
458461
typ.rem = $irem;
459462
typ.and = (x, y) => (x & y);
460463
typ.or = (x, y) => (x | y);
464+
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
461465
break;
462466
case $kindInt64:
463467
case $kindUint64:
@@ -468,6 +472,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
468472
typ.rem = (x, y) => $div64(x, y, true);
469473
typ.and = (x, y) => new typ(x.$high & y.$high, (x.$low & y.$low) >>> 0);
470474
typ.or = (x, y) => new typ(x.$high | y.$high, (x.$low | y.$low) >>> 0);
475+
typ.xor = (x, y) => new typ(x.$high ^ y.$high, (x.$low ^ y.$low) >>> 0);
471476
break;
472477
case $kindFloat32:
473478
case $kindFloat64:

tests/typeparams/arithmetics_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,37 @@ func TestBitwiseOr(t *testing.T) {
300300
t.Run(test.String(), test.Run)
301301
}
302302
}
303+
304+
func xor[T constraints.Integer](x, y T) T {
305+
return x ^ y
306+
}
307+
308+
func xorTC[T constraints.Integer](x, y, want T) *testCase[T] {
309+
return &testCase[T]{
310+
op: xor[T],
311+
opName: token.XOR,
312+
x: x,
313+
y: y,
314+
want: want,
315+
}
316+
}
317+
318+
func TestBitwiseXor(t *testing.T) {
319+
tests := []testCaseI{
320+
xorTC[int](0x0011, 0x0101, 0x0110),
321+
xorTC[uint](0x0011, 0x0101, 0x0110),
322+
xorTC[uintptr](0x0011, 0x0101, 0x0110),
323+
xorTC[int8](0x11, 0x01, 0x10),
324+
xorTC[int16](0x0011, 0x0101, 0x0110),
325+
xorTC[int32](0x0011, 0x0101, 0x0110),
326+
xorTC[uint8](0x11, 0x01, 0x10),
327+
xorTC[uint16](0x0011, 0x0101, 0x0110),
328+
xorTC[uint32](0x0011, 0x0101, 0x0110),
329+
xorTC[int64](0x0000001100000011, 0x0000010100000101, 0x0000011000000110),
330+
xorTC[uint64](0x0000001100000011, 0x0000010100000101, 0x0000011000000110),
331+
}
332+
333+
for _, test := range tests {
334+
t.Run(test.String(), test.Run)
335+
}
336+
}

0 commit comments

Comments
 (0)