type Kind … const Unknown … const Bool … const String … const Int … const Float … const Complex … type Value … const prec … type unknownVal … type boolVal … type stringVal … type int64Val … type intVal … type ratVal … type floatVal … type complexVal … func (unknownVal) Kind() Kind { … } func (boolVal) Kind() Kind { … } func (*stringVal) Kind() Kind { … } func (int64Val) Kind() Kind { … } func (intVal) Kind() Kind { … } func (ratVal) Kind() Kind { … } func (floatVal) Kind() Kind { … } func (complexVal) Kind() Kind { … } func (unknownVal) String() string { … } func (x boolVal) String() string { … } // String returns a possibly shortened quoted form of the String value. func (x *stringVal) String() string { … } // string constructs and returns the actual string literal value. // If x represents an addition, then it rewrites x to be a single // string, to speed future calls. This lazy construction avoids // building different string values for all subpieces of a large // concatenation. See golang.org/issue/23348. func (x *stringVal) string() string { … } // reverse reverses x in place and returns it. func reverse(x []string) []string { … } // appendReverse appends to list all of x's subpieces, but in reverse, // and returns the result. Appending the reversal allows processing // the right side in a recursive call and the left side in a loop. // Because a chain like a + b + c + d + e is actually represented // as ((((a + b) + c) + d) + e), the left-side loop avoids deep recursion. // x must be locked. func (x *stringVal) appendReverse(list []string) []string { … } func (x int64Val) String() string { … } func (x intVal) String() string { … } func (x ratVal) String() string { … } // String returns a decimal approximation of the Float value. func (x floatVal) String() string { … } func (x complexVal) String() string { … } func (x unknownVal) ExactString() string { … } func (x boolVal) ExactString() string { … } func (x *stringVal) ExactString() string { … } func (x int64Val) ExactString() string { … } func (x intVal) ExactString() string { … } func (x ratVal) ExactString() string { … } func (x floatVal) ExactString() string { … } func (x complexVal) ExactString() string { … } func (unknownVal) implementsValue() { … } func (boolVal) implementsValue() { … } func (*stringVal) implementsValue() { … } func (int64Val) implementsValue() { … } func (ratVal) implementsValue() { … } func (intVal) implementsValue() { … } func (floatVal) implementsValue() { … } func (complexVal) implementsValue() { … } func newInt() *big.Int { … } func newRat() *big.Rat { … } func newFloat() *big.Float { … } func i64toi(x int64Val) intVal { … } func i64tor(x int64Val) ratVal { … } func i64tof(x int64Val) floatVal { … } func itor(x intVal) ratVal { … } func itof(x intVal) floatVal { … } func rtof(x ratVal) floatVal { … } func vtoc(x Value) complexVal { … } func makeInt(x *big.Int) Value { … } func makeRat(x *big.Rat) Value { … } var floatVal0 … func makeFloat(x *big.Float) Value { … } func makeComplex(re, im Value) Value { … } func makeFloatFromLiteral(lit string) Value { … } const maxExp … // smallInt reports whether x would lead to "reasonably"-sized fraction // if converted to a *big.Rat. func smallInt(x *big.Int) bool { … } // smallFloat64 reports whether x would lead to "reasonably"-sized fraction // if converted to a *big.Rat. func smallFloat64(x float64) bool { … } // smallFloat reports whether x would lead to "reasonably"-sized fraction // if converted to a *big.Rat. func smallFloat(x *big.Float) bool { … } // MakeUnknown returns the [Unknown] value. func MakeUnknown() Value { … } // MakeBool returns the [Bool] value for b. func MakeBool(b bool) Value { … } // MakeString returns the [String] value for s. func MakeString(s string) Value { … } var emptyString … // MakeInt64 returns the [Int] value for x. func MakeInt64(x int64) Value { … } // MakeUint64 returns the [Int] value for x. func MakeUint64(x uint64) Value { … } // MakeFloat64 returns the [Float] value for x. // If x is -0.0, the result is 0.0. // If x is not finite, the result is an [Unknown]. func MakeFloat64(x float64) Value { … } // MakeFromLiteral returns the corresponding integer, floating-point, // imaginary, character, or string value for a Go literal string. The // tok value must be one of [token.INT], [token.FLOAT], [token.IMAG], // [token.CHAR], or [token.STRING]. The final argument must be zero. // If the literal string syntax is invalid, the result is an [Unknown]. func MakeFromLiteral(lit string, tok token.Token, zero uint) Value { … } // BoolVal returns the Go boolean value of x, which must be a [Bool] or an [Unknown]. // If x is [Unknown], the result is false. func BoolVal(x Value) bool { … } // StringVal returns the Go string value of x, which must be a [String] or an [Unknown]. // If x is [Unknown], the result is "". func StringVal(x Value) string { … } // Int64Val returns the Go int64 value of x and whether the result is exact; // x must be an [Int] or an [Unknown]. If the result is not exact, its value is undefined. // If x is [Unknown], the result is (0, false). func Int64Val(x Value) (int64, bool) { … } // Uint64Val returns the Go uint64 value of x and whether the result is exact; // x must be an [Int] or an [Unknown]. If the result is not exact, its value is undefined. // If x is [Unknown], the result is (0, false). func Uint64Val(x Value) (uint64, bool) { … } // Float32Val is like [Float64Val] but for float32 instead of float64. func Float32Val(x Value) (float32, bool) { … } // Float64Val returns the nearest Go float64 value of x and whether the result is exact; // x must be numeric or an [Unknown], but not [Complex]. For values too small (too close to 0) // to represent as float64, [Float64Val] silently underflows to 0. The result sign always // matches the sign of x, even for 0. // If x is [Unknown], the result is (0, false). func Float64Val(x Value) (float64, bool) { … } // Val returns the underlying value for a given constant. Since it returns an // interface, it is up to the caller to type assert the result to the expected // type. The possible dynamic return types are: // // x Kind type of result // ----------------------------------------- // Bool bool // String string // Int int64 or *big.Int // Float *big.Float or *big.Rat // everything else nil func Val(x Value) any { … } // Make returns the [Value] for x. // // type of x result Kind // ---------------------------- // bool Bool // string String // int64 Int // *big.Int Int // *big.Float Float // *big.Rat Float // anything else Unknown func Make(x any) Value { … } // BitLen returns the number of bits required to represent // the absolute value x in binary representation; x must be an [Int] or an [Unknown]. // If x is [Unknown], the result is 0. func BitLen(x Value) int { … } // Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0; // x must be numeric or [Unknown]. For complex values x, the sign is 0 if x == 0, // otherwise it is != 0. If x is [Unknown], the result is 1. func Sign(x Value) int { … } const _m … const _log … const wordSize … // Bytes returns the bytes for the absolute value of x in little- // endian binary representation; x must be an [Int]. func Bytes(x Value) []byte { … } // MakeFromBytes returns the [Int] value given the bytes of its little-endian // binary representation. An empty byte slice argument represents 0. func MakeFromBytes(bytes []byte) Value { … } // Num returns the numerator of x; x must be [Int], [Float], or [Unknown]. // If x is [Unknown], or if it is too large or small to represent as a // fraction, the result is [Unknown]. Otherwise the result is an [Int] // with the same sign as x. func Num(x Value) Value { … } // Denom returns the denominator of x; x must be [Int], [Float], or [Unknown]. // If x is [Unknown], or if it is too large or small to represent as a // fraction, the result is [Unknown]. Otherwise the result is an [Int] >= 1. func Denom(x Value) Value { … } // MakeImag returns the [Complex] value x*i; // x must be [Int], [Float], or [Unknown]. // If x is [Unknown], the result is [Unknown]. func MakeImag(x Value) Value { … } // Real returns the real part of x, which must be a numeric or unknown value. // If x is [Unknown], the result is [Unknown]. func Real(x Value) Value { … } // Imag returns the imaginary part of x, which must be a numeric or unknown value. // If x is [Unknown], the result is [Unknown]. func Imag(x Value) Value { … } // ToInt converts x to an [Int] value if x is representable as an [Int]. // Otherwise it returns an [Unknown]. func ToInt(x Value) Value { … } // ToFloat converts x to a [Float] value if x is representable as a [Float]. // Otherwise it returns an [Unknown]. func ToFloat(x Value) Value { … } // ToComplex converts x to a [Complex] value if x is representable as a [Complex]. // Otherwise it returns an [Unknown]. func ToComplex(x Value) Value { … } // is32bit reports whether x can be represented using 32 bits. func is32bit(x int64) bool { … } // is63bit reports whether x can be represented using 63 bits. func is63bit(x int64) bool { … } // UnaryOp returns the result of the unary expression op y. // The operation must be defined for the operand. // If prec > 0 it specifies the ^ (xor) result size in bits. // If y is [Unknown], the result is [Unknown]. func UnaryOp(op token.Token, y Value, prec uint) Value { … } func ord(x Value) int { … } // match returns the matching representation (same type) with the // smallest complexity for two values x and y. If one of them is // numeric, both of them must be numeric. If one of them is Unknown // or invalid (say, nil) both results are that value. func match(x, y Value) (_, _ Value) { … } // match0 must only be called by match. // Invariant: ord(x) < ord(y) func match0(x, y Value) (_, _ Value) { … } // BinaryOp returns the result of the binary expression x op y. // The operation must be defined for the operands. If one of the // operands is [Unknown], the result is [Unknown]. // BinaryOp doesn't handle comparisons or shifts; use [Compare] // or [Shift] instead. // // To force integer division of [Int] operands, use op == [token.QUO_ASSIGN] // instead of [token.QUO]; the result is guaranteed to be [Int] in this case. // Division by zero leads to a run-time panic. func BinaryOp(x_ Value, op token.Token, y_ Value) Value { … } func add(x, y Value) Value { … } func sub(x, y Value) Value { … } func mul(x, y Value) Value { … } func quo(x, y Value) Value { … } // Shift returns the result of the shift expression x op s // with op == [token.SHL] or [token.SHR] (<< or >>). x must be // an [Int] or an [Unknown]. If x is [Unknown], the result is x. func Shift(x Value, op token.Token, s uint) Value { … } func cmpZero(x int, op token.Token) bool { … } // Compare returns the result of the comparison x op y. // The comparison must be defined for the operands. // If one of the operands is [Unknown], the result is // false. func Compare(x_ Value, op token.Token, y_ Value) bool { … }