diff options
Diffstat (limited to 'starlark/int_generic.go')
-rw-r--r-- | starlark/int_generic.go | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/starlark/int_generic.go b/starlark/int_generic.go new file mode 100644 index 0000000..9e84d7f --- /dev/null +++ b/starlark/int_generic.go @@ -0,0 +1,33 @@ +//+build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris darwin,arm64 !amd64,!arm64,!mips64x,!ppc64x + +package starlark + +// generic Int implementation as a union + +import "math/big" + +type intImpl struct { + // We use only the signed 32-bit range of small to ensure + // that small+small and small*small do not overflow. + small_ int64 // minint32 <= small <= maxint32 + big_ *big.Int // big != nil <=> value is not representable as int32 +} + +// --- low-level accessors --- + +// get returns the small and big components of the Int. +// small is defined only if big is nil. +// small is sign-extended to 64 bits for ease of subsequent arithmetic. +func (i Int) get() (small int64, big *big.Int) { + return i.impl.small_, i.impl.big_ +} + +// Precondition: math.MinInt32 <= x && x <= math.MaxInt32 +func makeSmallInt(x int64) Int { + return Int{intImpl{small_: x}} +} + +// Precondition: x cannot be represented as int32. +func makeBigInt(x *big.Int) Int { + return Int{intImpl{big_: x}} +} |