From: Robert Griesemer Date: Tue, 21 Apr 2015 19:47:11 +0000 (-0700) Subject: go/exact: future-proof API: permit setting precision limit X-Git-Tag: go1.5beta1~960 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3f91a017f8f67cb9a744cf5d0a8b5db34a95808d;p=gostls13.git go/exact: future-proof API: permit setting precision limit Added a prec parameter to MakeFromLiteral (which currently must always be 0). This will permit go/types to provide an upper limit for the precision of constant values, eventually. Overflows can be returned with a special Overflow value (very much like the current Unknown values). This is a minimal change that should prevent the need for future backward-incompatible API changes. Change-Id: I6c9390d7cc4810375e26c53ed3bde5a383392330 Reviewed-on: https://go-review.googlesource.com/9168 Run-TryBot: Robert Griesemer Reviewed-by: Alan Donovan --- diff --git a/src/go/exact/exact.go b/src/go/exact/exact.go index e3ceff33a4..f0510ce669 100644 --- a/src/go/exact/exact.go +++ b/src/go/exact/exact.go @@ -145,9 +145,15 @@ func MakeFloat64(x float64) Value { } // MakeFromLiteral returns the corresponding integer, floating-point, -// imaginary, character, or string value for a Go literal string. The -// result is nil if the literal string is invalid. -func MakeFromLiteral(lit string, tok token.Token) Value { +// imaginary, character, or string value for a Go literal string. +// If prec > 0, prec specifies an upper limit for the precision of +// a numeric value. If the literal string is invalid, the result is +// nil. +// BUG(gri) Only prec == 0 is supported at the moment. +func MakeFromLiteral(lit string, tok token.Token, prec uint) Value { + if prec != 0 { + panic("limited precision not supported") + } switch tok { case token.INT: if x, err := strconv.ParseInt(lit, 0, 64); err == nil { @@ -489,10 +495,10 @@ func is63bit(x int64) bool { // UnaryOp returns the result of the unary expression op y. // The operation must be defined for the operand. -// If size >= 0 it specifies the ^ (xor) result size in bytes. +// 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, size int) Value { +func UnaryOp(op token.Token, y Value, prec uint) Value { switch op { case token.ADD: switch y.(type) { @@ -530,11 +536,10 @@ func UnaryOp(op token.Token, y Value, size int) Value { goto Error } // For unsigned types, the result will be negative and - // thus "too large": We must limit the result size to - // the type's size. - if size >= 0 { - s := uint(size) * 8 - z.AndNot(&z, new(big.Int).Lsh(big.NewInt(-1), s)) // z &^= (-1)< 0 { + z.AndNot(&z, new(big.Int).Lsh(big.NewInt(-1), prec)) // z &^= (-1)<