Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ac13918

Browse filesBrowse files
committed
Implement bitwise shift left operator for type parameters.
1 parent f4c0904 commit ac13918
Copy full SHA for ac13918

File tree

4 files changed

+51
-1
lines changed
Filter options

4 files changed

+51
-1
lines changed

‎compiler/expressions.go

Copy file name to clipboardExpand all lines: compiler/expressions.go
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ func (fc *funcContext) translateBinaryExpr(e *ast.BinaryExpr) *expression {
704704
return fc.formatExpr("%s.xor(%e, %e)", fc.typeName(t), e.X, e.Y)
705705
case token.AND_NOT:
706706
return fc.formatExpr("%s.andNot(%e, %e)", fc.typeName(t), e.X, e.Y)
707+
case token.SHL:
708+
return fc.formatExpr("%s.shl(%e, $flatten64(%e, %s))", fc.typeName(t), e.X, e.Y, fc.typeName(t2))
707709
}
708710
}
709711

‎compiler/prelude/numeric.js

Copy file name to clipboardExpand all lines: compiler/prelude/numeric.js
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ var $floatKey = f => {
3030
return String(f);
3131
};
3232

33-
var $flatten64 = x => {
33+
var $flatten64 = (x, typ) => {
34+
if (typ && typ.kind != $kindInt64 && typ.kind != $kindUint64) {
35+
return x; // Not a 64-bit number, no need to flatten.
36+
}
3437
return x.$high * 4294967296 + x.$low;
3538
};
3639

‎compiler/prelude/types.js

Copy file name to clipboardExpand all lines: compiler/prelude/types.js
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
429429
typ.or = (x, y) => (x | y);
430430
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
431431
typ.andNot = (x, y) => $truncateNumber(x & ~y, typ);
432+
typ.shl = (x, y) => (y < 32) ? $truncateNumber(x << y, typ) : 0;
432433
break;
433434
case $kindUint8:
434435
case $kindUint16:
@@ -441,6 +442,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
441442
typ.or = (x, y) => (x | y) >>> 0;
442443
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
443444
typ.andNot = (x, y) => $truncateNumber(x & ~y, typ);
445+
typ.shl = (x, y) => (y < 32) ? $truncateNumber(x << y, typ) : 0;
444446
break;
445447
case $kindUint:
446448
case $kindUint32:
@@ -454,6 +456,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
454456
typ.or = (x, y) => (x | y) >>> 0;
455457
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
456458
typ.andNot = (x, y) => $truncateNumber(x & ~y, typ);
459+
typ.shl = (x, y) => (y < 32) ? $truncateNumber(x << y, typ) : 0;
457460
break;
458461
case $kindInt:
459462
case $kindInt32:
@@ -466,6 +469,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
466469
typ.or = (x, y) => (x | y);
467470
typ.xor = (x, y) => $truncateNumber(x ^ y, typ);
468471
typ.andNot = (x, y) => $truncateNumber(x & ~y, typ);
472+
typ.shl = (x, y) => (y < 32) ? $truncateNumber(x << y, typ) : 0;
469473
break;
470474
case $kindInt64:
471475
case $kindUint64:
@@ -478,6 +482,7 @@ var $newType = (size, kind, string, named, pkg, exported, constructor) => {
478482
typ.or = (x, y) => new typ(x.$high | y.$high, (x.$low | y.$low) >>> 0);
479483
typ.xor = (x, y) => new typ(x.$high ^ y.$high, (x.$low ^ y.$low) >>> 0);
480484
typ.andNot = (x, y) => new typ(x.$high & ~y.$high, (x.$low & ~y.$low) >>> 0);
485+
typ.shl = (x, y) => $shiftLeft64(x, y);
481486
break;
482487
case $kindFloat32:
483488
case $kindFloat64:

‎tests/typeparams/arithmetics_test.go

Copy file name to clipboardExpand all lines: tests/typeparams/arithmetics_test.go
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package typeparams_test
33
import (
44
"fmt"
55
"go/token"
6+
"math/bits"
67
"testing"
78

89
"golang.org/x/exp/constraints"
@@ -368,3 +369,42 @@ func TestBitwiseAndNot(t *testing.T) {
368369
t.Run(test.String(), test.Run)
369370
}
370371
}
372+
373+
func leftShift[T constraints.Integer](x, y T) T {
374+
return x << y
375+
}
376+
377+
func leftShiftTC[T constraints.Integer](x, y, want T) *testCase[T] {
378+
return &testCase[T]{
379+
op: leftShift[T],
380+
opName: token.SHL,
381+
x: x,
382+
y: y,
383+
want: want,
384+
}
385+
}
386+
387+
func TestBitwiseShitLeft(t *testing.T) {
388+
tests := []testCaseI{
389+
leftShiftTC[int8](0x48, 1, -0x70),
390+
leftShiftTC[int16](0x4008, 1, -0x7ff0),
391+
leftShiftTC[int32](0x40000008, 1, -0x7ffffff0),
392+
leftShiftTC[uint8](0x88, 1, 0x10),
393+
leftShiftTC[uint16](0x8008, 1, 0x0010),
394+
leftShiftTC[uint32](0x80000008, 1, 0x00000010),
395+
leftShiftTC[int64](0x4000000000000008, 1, -0x7ffffffffffffff0),
396+
leftShiftTC[uint64](0x8000000000000008, 1, 0x0000000000000010),
397+
}
398+
399+
if bits.UintSize == 32 {
400+
tests = append(tests,
401+
leftShiftTC[int](0x40000008, 1, -0x7ffffff0),
402+
leftShiftTC[uint](0x80000008, 1, 0x00000010),
403+
leftShiftTC[uintptr](0x80000008, 1, 0x00000010),
404+
)
405+
}
406+
407+
for _, test := range tests {
408+
t.Run(test.String(), test.Run)
409+
}
410+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.