1*4947cdc7SCole Faust// Always use this implementation, even for Posix-compliant platforms 2*4947cdc7SCole Faust// (upstream code uses the implementation in int_posix64.go, but we 3*4947cdc7SCole Faust// do not want to depend on golang.olg/x.sys/unix package). 4*4947cdc7SCole Faustpackage starlark 5*4947cdc7SCole Faust 6*4947cdc7SCole Faust// generic Int implementation as a union 7*4947cdc7SCole Faust 8*4947cdc7SCole Faustimport "math/big" 9*4947cdc7SCole Faust 10*4947cdc7SCole Fausttype intImpl struct { 11*4947cdc7SCole Faust // We use only the signed 32-bit range of small to ensure 12*4947cdc7SCole Faust // that small+small and small*small do not overflow. 13*4947cdc7SCole Faust small_ int64 // minint32 <= small <= maxint32 14*4947cdc7SCole Faust big_ *big.Int // big != nil <=> value is not representable as int32 15*4947cdc7SCole Faust} 16*4947cdc7SCole Faust 17*4947cdc7SCole Faust// --- low-level accessors --- 18*4947cdc7SCole Faust 19*4947cdc7SCole Faust// get returns the small and big components of the Int. 20*4947cdc7SCole Faust// small is defined only if big is nil. 21*4947cdc7SCole Faust// small is sign-extended to 64 bits for ease of subsequent arithmetic. 22*4947cdc7SCole Faustfunc (i Int) get() (small int64, big *big.Int) { 23*4947cdc7SCole Faust return i.impl.small_, i.impl.big_ 24*4947cdc7SCole Faust} 25*4947cdc7SCole Faust 26*4947cdc7SCole Faust// Precondition: math.MinInt32 <= x && x <= math.MaxInt32 27*4947cdc7SCole Faustfunc makeSmallInt(x int64) Int { 28*4947cdc7SCole Faust return Int{intImpl{small_: x}} 29*4947cdc7SCole Faust} 30*4947cdc7SCole Faust 31*4947cdc7SCole Faust// Precondition: x cannot be represented as int32. 32*4947cdc7SCole Faustfunc makeBigInt(x *big.Int) Int { 33*4947cdc7SCole Faust return Int{intImpl{big_: x}} 34*4947cdc7SCole Faust} 35