github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/go/exact/exact.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package exact implements Values representing untyped
     6  // Go constants and the corresponding operations. Values
     7  // and operations have unlimited precision.
     8  //
     9  // A special Unknown value may be used when a value
    10  // is unknown due to an error. Operations on unknown
    11  // values produce unknown values unless specified
    12  // otherwise.
    13  //
    14  package exact // import "go/exact"
    15  
    16  import (
    17  	"fmt"
    18  	"go/token"
    19  	"math/big"
    20  	"strconv"
    21  )
    22  
    23  // Kind specifies the kind of value represented by a Value.
    24  type Kind int
    25  
    26  // Implementation note: Kinds must be enumerated in
    27  // order of increasing "complexity" (used by match).
    28  
    29  const (
    30  	// unknown values
    31  	Unknown Kind = iota
    32  
    33  	// non-numeric values
    34  	Bool
    35  	String
    36  
    37  	// numeric values
    38  	Int
    39  	Float
    40  	Complex
    41  )
    42  
    43  // A Value represents a mathematically exact value of a given Kind.
    44  type Value interface {
    45  	// Kind returns the value kind; it is always the smallest
    46  	// kind in which the value can be represented exactly.
    47  	Kind() Kind
    48  
    49  	// String returns a human-readable form of the value.
    50  	String() string
    51  
    52  	// Prevent external implementations.
    53  	implementsValue()
    54  }
    55  
    56  // ----------------------------------------------------------------------------
    57  // Implementations
    58  
    59  type (
    60  	unknownVal struct{}
    61  	boolVal    bool
    62  	stringVal  string
    63  	int64Val   int64
    64  	intVal     struct{ val *big.Int }
    65  	floatVal   struct{ val *big.Rat }
    66  	complexVal struct{ re, im *big.Rat }
    67  )
    68  
    69  func (unknownVal) Kind() Kind { return Unknown }
    70  func (boolVal) Kind() Kind    { return Bool }
    71  func (stringVal) Kind() Kind  { return String }
    72  func (int64Val) Kind() Kind   { return Int }
    73  func (intVal) Kind() Kind     { return Int }
    74  func (floatVal) Kind() Kind   { return Float }
    75  func (complexVal) Kind() Kind { return Complex }
    76  
    77  func (unknownVal) String() string   { return "unknown" }
    78  func (x boolVal) String() string    { return fmt.Sprintf("%v", bool(x)) }
    79  func (x stringVal) String() string  { return strconv.Quote(string(x)) }
    80  func (x int64Val) String() string   { return strconv.FormatInt(int64(x), 10) }
    81  func (x intVal) String() string     { return x.val.String() }
    82  func (x floatVal) String() string   { return x.val.String() }
    83  func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
    84  
    85  func (unknownVal) implementsValue() {}
    86  func (boolVal) implementsValue()    {}
    87  func (stringVal) implementsValue()  {}
    88  func (int64Val) implementsValue()   {}
    89  func (intVal) implementsValue()     {}
    90  func (floatVal) implementsValue()   {}
    91  func (complexVal) implementsValue() {}
    92  
    93  // int64 bounds
    94  var (
    95  	minInt64 = big.NewInt(-1 << 63)
    96  	maxInt64 = big.NewInt(1<<63 - 1)
    97  )
    98  
    99  func normInt(x *big.Int) Value {
   100  	if minInt64.Cmp(x) <= 0 && x.Cmp(maxInt64) <= 0 {
   101  		return int64Val(x.Int64())
   102  	}
   103  	return intVal{x}
   104  }
   105  
   106  func normFloat(x *big.Rat) Value {
   107  	if x.IsInt() {
   108  		return normInt(x.Num())
   109  	}
   110  	return floatVal{x}
   111  }
   112  
   113  func normComplex(re, im *big.Rat) Value {
   114  	if im.Sign() == 0 {
   115  		return normFloat(re)
   116  	}
   117  	return complexVal{re, im}
   118  }
   119  
   120  // ----------------------------------------------------------------------------
   121  // Factories
   122  
   123  // MakeUnknown returns the Unknown value.
   124  func MakeUnknown() Value { return unknownVal{} }
   125  
   126  // MakeBool returns the Bool value for x.
   127  func MakeBool(b bool) Value { return boolVal(b) }
   128  
   129  // MakeString returns the String value for x.
   130  func MakeString(s string) Value { return stringVal(s) }
   131  
   132  // MakeInt64 returns the Int value for x.
   133  func MakeInt64(x int64) Value { return int64Val(x) }
   134  
   135  // MakeUint64 returns the Int value for x.
   136  func MakeUint64(x uint64) Value { return normInt(new(big.Int).SetUint64(x)) }
   137  
   138  // MakeFloat64 returns the numeric value for x.
   139  // If x is not finite, the result is unknown.
   140  func MakeFloat64(x float64) Value {
   141  	if f := new(big.Rat).SetFloat64(x); f != nil {
   142  		return normFloat(f)
   143  	}
   144  	return unknownVal{}
   145  }
   146  
   147  // MakeFromLiteral returns the corresponding integer, floating-point,
   148  // imaginary, character, or string value for a Go literal string. The
   149  // result is nil if the literal string is invalid.
   150  func MakeFromLiteral(lit string, tok token.Token) Value {
   151  	switch tok {
   152  	case token.INT:
   153  		if x, err := strconv.ParseInt(lit, 0, 64); err == nil {
   154  			return int64Val(x)
   155  		}
   156  		if x, ok := new(big.Int).SetString(lit, 0); ok {
   157  			return intVal{x}
   158  		}
   159  
   160  	case token.FLOAT:
   161  		if x, ok := new(big.Rat).SetString(lit); ok {
   162  			return normFloat(x)
   163  		}
   164  
   165  	case token.IMAG:
   166  		if n := len(lit); n > 0 && lit[n-1] == 'i' {
   167  			if im, ok := new(big.Rat).SetString(lit[0 : n-1]); ok {
   168  				return normComplex(big.NewRat(0, 1), im)
   169  			}
   170  		}
   171  
   172  	case token.CHAR:
   173  		if n := len(lit); n >= 2 {
   174  			if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil {
   175  				return int64Val(code)
   176  			}
   177  		}
   178  
   179  	case token.STRING:
   180  		if s, err := strconv.Unquote(lit); err == nil {
   181  			return stringVal(s)
   182  		}
   183  	}
   184  
   185  	return nil
   186  }
   187  
   188  // ----------------------------------------------------------------------------
   189  // Accessors
   190  //
   191  // For unknown arguments the result is the zero value for the respective
   192  // accessor type, except for Sign, where the result is 1.
   193  
   194  // BoolVal returns the Go boolean value of x, which must be a Bool or an Unknown.
   195  // If x is Unknown, the result is false.
   196  func BoolVal(x Value) bool {
   197  	switch x := x.(type) {
   198  	case boolVal:
   199  		return bool(x)
   200  	case unknownVal:
   201  		return false
   202  	}
   203  	panic(fmt.Sprintf("%v not a Bool", x))
   204  }
   205  
   206  // StringVal returns the Go string value of x, which must be a String or an Unknown.
   207  // If x is Unknown, the result is "".
   208  func StringVal(x Value) string {
   209  	switch x := x.(type) {
   210  	case stringVal:
   211  		return string(x)
   212  	case unknownVal:
   213  		return ""
   214  	}
   215  	panic(fmt.Sprintf("%v not a String", x))
   216  }
   217  
   218  // Int64Val returns the Go int64 value of x and whether the result is exact;
   219  // x must be an Int or an Unknown. If the result is not exact, its value is undefined.
   220  // If x is Unknown, the result is (0, false).
   221  func Int64Val(x Value) (int64, bool) {
   222  	switch x := x.(type) {
   223  	case int64Val:
   224  		return int64(x), true
   225  	case intVal:
   226  		return x.val.Int64(), x.val.BitLen() <= 63
   227  	case unknownVal:
   228  		return 0, false
   229  	}
   230  	panic(fmt.Sprintf("%v not an Int", x))
   231  }
   232  
   233  // Uint64Val returns the Go uint64 value of x and whether the result is exact;
   234  // x must be an Int or an Unknown. If the result is not exact, its value is undefined.
   235  // If x is Unknown, the result is (0, false).
   236  func Uint64Val(x Value) (uint64, bool) {
   237  	switch x := x.(type) {
   238  	case int64Val:
   239  		return uint64(x), x >= 0
   240  	case intVal:
   241  		return x.val.Uint64(), x.val.Sign() >= 0 && x.val.BitLen() <= 64
   242  	case unknownVal:
   243  		return 0, false
   244  	}
   245  	panic(fmt.Sprintf("%v not an Int", x))
   246  }
   247  
   248  // Float32Val is like Float64Val but for float32 instead of float64.
   249  func Float32Val(x Value) (float32, bool) {
   250  	switch x := x.(type) {
   251  	case int64Val:
   252  		f := float32(x)
   253  		return f, int64Val(f) == x
   254  	case intVal:
   255  		return ratToFloat32(new(big.Rat).SetFrac(x.val, int1))
   256  	case floatVal:
   257  		return ratToFloat32(x.val)
   258  	case unknownVal:
   259  		return 0, false
   260  	}
   261  	panic(fmt.Sprintf("%v not a Float", x))
   262  }
   263  
   264  // Float64Val returns the nearest Go float64 value of x and whether the result is exact;
   265  // x must be numeric but not Complex, or Unknown. For values too small (too close to 0)
   266  // to represent as float64, Float64Val silently underflows to 0. The result sign always
   267  // matches the sign of x, even for 0.
   268  // If x is Unknown, the result is (0, false).
   269  func Float64Val(x Value) (float64, bool) {
   270  	switch x := x.(type) {
   271  	case int64Val:
   272  		f := float64(int64(x))
   273  		return f, int64Val(f) == x
   274  	case intVal:
   275  		return new(big.Rat).SetFrac(x.val, int1).Float64()
   276  	case floatVal:
   277  		return x.val.Float64()
   278  	case unknownVal:
   279  		return 0, false
   280  	}
   281  	panic(fmt.Sprintf("%v not a Float", x))
   282  }
   283  
   284  // BitLen returns the number of bits required to represent
   285  // the absolute value x in binary representation; x must be an Int or an Unknown.
   286  // If x is Unknown, the result is 0.
   287  func BitLen(x Value) int {
   288  	switch x := x.(type) {
   289  	case int64Val:
   290  		return new(big.Int).SetInt64(int64(x)).BitLen()
   291  	case intVal:
   292  		return x.val.BitLen()
   293  	case unknownVal:
   294  		return 0
   295  	}
   296  	panic(fmt.Sprintf("%v not an Int", x))
   297  }
   298  
   299  // Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0;
   300  // x must be numeric or Unknown. For complex values x, the sign is 0 if x == 0,
   301  // otherwise it is != 0. If x is Unknown, the result is 1.
   302  func Sign(x Value) int {
   303  	switch x := x.(type) {
   304  	case int64Val:
   305  		switch {
   306  		case x < 0:
   307  			return -1
   308  		case x > 0:
   309  			return 1
   310  		}
   311  		return 0
   312  	case intVal:
   313  		return x.val.Sign()
   314  	case floatVal:
   315  		return x.val.Sign()
   316  	case complexVal:
   317  		return x.re.Sign() | x.im.Sign()
   318  	case unknownVal:
   319  		return 1 // avoid spurious division by zero errors
   320  	}
   321  	panic(fmt.Sprintf("%v not numeric", x))
   322  }
   323  
   324  // ----------------------------------------------------------------------------
   325  // Support for serializing/deserializing integers
   326  
   327  const (
   328  	// Compute the size of a Word in bytes.
   329  	_m       = ^big.Word(0)
   330  	_log     = _m>>8&1 + _m>>16&1 + _m>>32&1
   331  	wordSize = 1 << _log
   332  )
   333  
   334  // Bytes returns the bytes for the absolute value of x in little-
   335  // endian binary representation; x must be an Int.
   336  func Bytes(x Value) []byte {
   337  	var val *big.Int
   338  	switch x := x.(type) {
   339  	case int64Val:
   340  		val = new(big.Int).SetInt64(int64(x))
   341  	case intVal:
   342  		val = x.val
   343  	default:
   344  		panic(fmt.Sprintf("%v not an Int", x))
   345  	}
   346  
   347  	words := val.Bits()
   348  	bytes := make([]byte, len(words)*wordSize)
   349  
   350  	i := 0
   351  	for _, w := range words {
   352  		for j := 0; j < wordSize; j++ {
   353  			bytes[i] = byte(w)
   354  			w >>= 8
   355  			i++
   356  		}
   357  	}
   358  	// remove leading 0's
   359  	for i > 0 && bytes[i-1] == 0 {
   360  		i--
   361  	}
   362  
   363  	return bytes[:i]
   364  }
   365  
   366  // MakeFromBytes returns the Int value given the bytes of its little-endian
   367  // binary representation. An empty byte slice argument represents 0.
   368  func MakeFromBytes(bytes []byte) Value {
   369  	words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize)
   370  
   371  	i := 0
   372  	var w big.Word
   373  	var s uint
   374  	for _, b := range bytes {
   375  		w |= big.Word(b) << s
   376  		if s += 8; s == wordSize*8 {
   377  			words[i] = w
   378  			i++
   379  			w = 0
   380  			s = 0
   381  		}
   382  	}
   383  	// store last word
   384  	if i < len(words) {
   385  		words[i] = w
   386  		i++
   387  	}
   388  	// remove leading 0's
   389  	for i > 0 && words[i-1] == 0 {
   390  		i--
   391  	}
   392  
   393  	return normInt(new(big.Int).SetBits(words[:i]))
   394  }
   395  
   396  // ----------------------------------------------------------------------------
   397  // Support for disassembling fractions
   398  
   399  // Num returns the numerator of x; x must be Int, Float, or Unknown.
   400  // If x is Unknown, the result is Unknown, otherwise it is an Int
   401  // with the same sign as x.
   402  func Num(x Value) Value {
   403  	switch x := x.(type) {
   404  	case unknownVal, int64Val, intVal:
   405  		return x
   406  	case floatVal:
   407  		return normInt(x.val.Num())
   408  	}
   409  	panic(fmt.Sprintf("%v not Int or Float", x))
   410  }
   411  
   412  // Denom returns the denominator of x; x must be Int, Float, or Unknown.
   413  // If x is Unknown, the result is Unknown, otherwise it is an Int >= 1.
   414  func Denom(x Value) Value {
   415  	switch x := x.(type) {
   416  	case unknownVal:
   417  		return x
   418  	case int64Val, intVal:
   419  		return int64Val(1)
   420  	case floatVal:
   421  		return normInt(x.val.Denom())
   422  	}
   423  	panic(fmt.Sprintf("%v not Int or Float", x))
   424  }
   425  
   426  // ----------------------------------------------------------------------------
   427  // Support for assembling/disassembling complex numbers
   428  
   429  // MakeImag returns the numeric value x*i (possibly 0);
   430  // x must be Int, Float, or Unknown.
   431  // If x is Unknown, the result is Unknown.
   432  func MakeImag(x Value) Value {
   433  	var im *big.Rat
   434  	switch x := x.(type) {
   435  	case unknownVal:
   436  		return x
   437  	case int64Val:
   438  		im = big.NewRat(int64(x), 1)
   439  	case intVal:
   440  		im = new(big.Rat).SetFrac(x.val, int1)
   441  	case floatVal:
   442  		im = x.val
   443  	default:
   444  		panic(fmt.Sprintf("%v not Int or Float", x))
   445  	}
   446  	return normComplex(rat0, im)
   447  }
   448  
   449  // Real returns the real part of x, which must be a numeric or unknown value.
   450  // If x is Unknown, the result is Unknown.
   451  func Real(x Value) Value {
   452  	switch x := x.(type) {
   453  	case unknownVal, int64Val, intVal, floatVal:
   454  		return x
   455  	case complexVal:
   456  		return normFloat(x.re)
   457  	}
   458  	panic(fmt.Sprintf("%v not numeric", x))
   459  }
   460  
   461  // Imag returns the imaginary part of x, which must be a numeric or unknown value.
   462  // If x is Unknown, the result is Unknown.
   463  func Imag(x Value) Value {
   464  	switch x := x.(type) {
   465  	case unknownVal:
   466  		return x
   467  	case int64Val, intVal, floatVal:
   468  		return int64Val(0)
   469  	case complexVal:
   470  		return normFloat(x.im)
   471  	}
   472  	panic(fmt.Sprintf("%v not numeric", x))
   473  }
   474  
   475  // ----------------------------------------------------------------------------
   476  // Operations
   477  
   478  // is32bit reports whether x can be represented using 32 bits.
   479  func is32bit(x int64) bool {
   480  	const s = 32
   481  	return -1<<(s-1) <= x && x <= 1<<(s-1)-1
   482  }
   483  
   484  // is63bit reports whether x can be represented using 63 bits.
   485  func is63bit(x int64) bool {
   486  	const s = 63
   487  	return -1<<(s-1) <= x && x <= 1<<(s-1)-1
   488  }
   489  
   490  // UnaryOp returns the result of the unary expression op y.
   491  // The operation must be defined for the operand.
   492  // If size >= 0 it specifies the ^ (xor) result size in bytes.
   493  // If y is Unknown, the result is Unknown.
   494  //
   495  func UnaryOp(op token.Token, y Value, size int) Value {
   496  	switch op {
   497  	case token.ADD:
   498  		switch y.(type) {
   499  		case unknownVal, int64Val, intVal, floatVal, complexVal:
   500  			return y
   501  		}
   502  
   503  	case token.SUB:
   504  		switch y := y.(type) {
   505  		case unknownVal:
   506  			return y
   507  		case int64Val:
   508  			if z := -y; z != y {
   509  				return z // no overflow
   510  			}
   511  			return normInt(new(big.Int).Neg(big.NewInt(int64(y))))
   512  		case intVal:
   513  			return normInt(new(big.Int).Neg(y.val))
   514  		case floatVal:
   515  			return normFloat(new(big.Rat).Neg(y.val))
   516  		case complexVal:
   517  			return normComplex(new(big.Rat).Neg(y.re), new(big.Rat).Neg(y.im))
   518  		}
   519  
   520  	case token.XOR:
   521  		var z big.Int
   522  		switch y := y.(type) {
   523  		case unknownVal:
   524  			return y
   525  		case int64Val:
   526  			z.Not(big.NewInt(int64(y)))
   527  		case intVal:
   528  			z.Not(y.val)
   529  		default:
   530  			goto Error
   531  		}
   532  		// For unsigned types, the result will be negative and
   533  		// thus "too large": We must limit the result size to
   534  		// the type's size.
   535  		if size >= 0 {
   536  			s := uint(size) * 8
   537  			z.AndNot(&z, new(big.Int).Lsh(big.NewInt(-1), s)) // z &^= (-1)<<s
   538  		}
   539  		return normInt(&z)
   540  
   541  	case token.NOT:
   542  		switch y := y.(type) {
   543  		case unknownVal:
   544  			return y
   545  		case boolVal:
   546  			return !y
   547  		}
   548  	}
   549  
   550  Error:
   551  	panic(fmt.Sprintf("invalid unary operation %s%v", op, y))
   552  }
   553  
   554  var (
   555  	int1 = big.NewInt(1)
   556  	rat0 = big.NewRat(0, 1)
   557  )
   558  
   559  func ord(x Value) int {
   560  	switch x.(type) {
   561  	default:
   562  		return 0
   563  	case boolVal, stringVal:
   564  		return 1
   565  	case int64Val:
   566  		return 2
   567  	case intVal:
   568  		return 3
   569  	case floatVal:
   570  		return 4
   571  	case complexVal:
   572  		return 5
   573  	}
   574  }
   575  
   576  // match returns the matching representation (same type) with the
   577  // smallest complexity for two values x and y. If one of them is
   578  // numeric, both of them must be numeric. If one of them is Unknown,
   579  // both results are Unknown.
   580  //
   581  func match(x, y Value) (_, _ Value) {
   582  	if ord(x) > ord(y) {
   583  		y, x = match(y, x)
   584  		return x, y
   585  	}
   586  	// ord(x) <= ord(y)
   587  
   588  	switch x := x.(type) {
   589  	case unknownVal:
   590  		return x, x
   591  
   592  	case boolVal, stringVal, complexVal:
   593  		return x, y
   594  
   595  	case int64Val:
   596  		switch y := y.(type) {
   597  		case int64Val:
   598  			return x, y
   599  		case intVal:
   600  			return intVal{big.NewInt(int64(x))}, y
   601  		case floatVal:
   602  			return floatVal{big.NewRat(int64(x), 1)}, y
   603  		case complexVal:
   604  			return complexVal{big.NewRat(int64(x), 1), rat0}, y
   605  		}
   606  
   607  	case intVal:
   608  		switch y := y.(type) {
   609  		case intVal:
   610  			return x, y
   611  		case floatVal:
   612  			return floatVal{new(big.Rat).SetFrac(x.val, int1)}, y
   613  		case complexVal:
   614  			return complexVal{new(big.Rat).SetFrac(x.val, int1), rat0}, y
   615  		}
   616  
   617  	case floatVal:
   618  		switch y := y.(type) {
   619  		case floatVal:
   620  			return x, y
   621  		case complexVal:
   622  			return complexVal{x.val, rat0}, y
   623  		}
   624  	}
   625  
   626  	panic("unreachable")
   627  }
   628  
   629  // BinaryOp returns the result of the binary expression x op y.
   630  // The operation must be defined for the operands. If one of the
   631  // operands is Unknown, the result is Unknown.
   632  // To force integer division of Int operands, use op == token.QUO_ASSIGN
   633  // instead of token.QUO; the result is guaranteed to be Int in this case.
   634  // Division by zero leads to a run-time panic.
   635  //
   636  func BinaryOp(x Value, op token.Token, y Value) Value {
   637  	x, y = match(x, y)
   638  
   639  	switch x := x.(type) {
   640  	case unknownVal:
   641  		return x
   642  
   643  	case boolVal:
   644  		y := y.(boolVal)
   645  		switch op {
   646  		case token.LAND:
   647  			return x && y
   648  		case token.LOR:
   649  			return x || y
   650  		}
   651  
   652  	case int64Val:
   653  		a := int64(x)
   654  		b := int64(y.(int64Val))
   655  		var c int64
   656  		switch op {
   657  		case token.ADD:
   658  			if !is63bit(a) || !is63bit(b) {
   659  				return normInt(new(big.Int).Add(big.NewInt(a), big.NewInt(b)))
   660  			}
   661  			c = a + b
   662  		case token.SUB:
   663  			if !is63bit(a) || !is63bit(b) {
   664  				return normInt(new(big.Int).Sub(big.NewInt(a), big.NewInt(b)))
   665  			}
   666  			c = a - b
   667  		case token.MUL:
   668  			if !is32bit(a) || !is32bit(b) {
   669  				return normInt(new(big.Int).Mul(big.NewInt(a), big.NewInt(b)))
   670  			}
   671  			c = a * b
   672  		case token.QUO:
   673  			return normFloat(new(big.Rat).SetFrac(big.NewInt(a), big.NewInt(b)))
   674  		case token.QUO_ASSIGN: // force integer division
   675  			c = a / b
   676  		case token.REM:
   677  			c = a % b
   678  		case token.AND:
   679  			c = a & b
   680  		case token.OR:
   681  			c = a | b
   682  		case token.XOR:
   683  			c = a ^ b
   684  		case token.AND_NOT:
   685  			c = a &^ b
   686  		default:
   687  			goto Error
   688  		}
   689  		return int64Val(c)
   690  
   691  	case intVal:
   692  		a := x.val
   693  		b := y.(intVal).val
   694  		var c big.Int
   695  		switch op {
   696  		case token.ADD:
   697  			c.Add(a, b)
   698  		case token.SUB:
   699  			c.Sub(a, b)
   700  		case token.MUL:
   701  			c.Mul(a, b)
   702  		case token.QUO:
   703  			return normFloat(new(big.Rat).SetFrac(a, b))
   704  		case token.QUO_ASSIGN: // force integer division
   705  			c.Quo(a, b)
   706  		case token.REM:
   707  			c.Rem(a, b)
   708  		case token.AND:
   709  			c.And(a, b)
   710  		case token.OR:
   711  			c.Or(a, b)
   712  		case token.XOR:
   713  			c.Xor(a, b)
   714  		case token.AND_NOT:
   715  			c.AndNot(a, b)
   716  		default:
   717  			goto Error
   718  		}
   719  		return normInt(&c)
   720  
   721  	case floatVal:
   722  		a := x.val
   723  		b := y.(floatVal).val
   724  		var c big.Rat
   725  		switch op {
   726  		case token.ADD:
   727  			c.Add(a, b)
   728  		case token.SUB:
   729  			c.Sub(a, b)
   730  		case token.MUL:
   731  			c.Mul(a, b)
   732  		case token.QUO:
   733  			c.Quo(a, b)
   734  		default:
   735  			goto Error
   736  		}
   737  		return normFloat(&c)
   738  
   739  	case complexVal:
   740  		y := y.(complexVal)
   741  		a, b := x.re, x.im
   742  		c, d := y.re, y.im
   743  		var re, im big.Rat
   744  		switch op {
   745  		case token.ADD:
   746  			// (a+c) + i(b+d)
   747  			re.Add(a, c)
   748  			im.Add(b, d)
   749  		case token.SUB:
   750  			// (a-c) + i(b-d)
   751  			re.Sub(a, c)
   752  			im.Sub(b, d)
   753  		case token.MUL:
   754  			// (ac-bd) + i(bc+ad)
   755  			var ac, bd, bc, ad big.Rat
   756  			ac.Mul(a, c)
   757  			bd.Mul(b, d)
   758  			bc.Mul(b, c)
   759  			ad.Mul(a, d)
   760  			re.Sub(&ac, &bd)
   761  			im.Add(&bc, &ad)
   762  		case token.QUO:
   763  			// (ac+bd)/s + i(bc-ad)/s, with s = cc + dd
   764  			var ac, bd, bc, ad, s, cc, dd big.Rat
   765  			ac.Mul(a, c)
   766  			bd.Mul(b, d)
   767  			bc.Mul(b, c)
   768  			ad.Mul(a, d)
   769  			cc.Mul(c, c)
   770  			dd.Mul(d, d)
   771  			s.Add(&cc, &dd)
   772  			re.Add(&ac, &bd)
   773  			re.Quo(&re, &s)
   774  			im.Sub(&bc, &ad)
   775  			im.Quo(&im, &s)
   776  		default:
   777  			goto Error
   778  		}
   779  		return normComplex(&re, &im)
   780  
   781  	case stringVal:
   782  		if op == token.ADD {
   783  			return x + y.(stringVal)
   784  		}
   785  	}
   786  
   787  Error:
   788  	panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y))
   789  }
   790  
   791  // Shift returns the result of the shift expression x op s
   792  // with op == token.SHL or token.SHR (<< or >>). x must be
   793  // an Int or an Unknown. If x is Unknown, the result is x.
   794  //
   795  func Shift(x Value, op token.Token, s uint) Value {
   796  	switch x := x.(type) {
   797  	case unknownVal:
   798  		return x
   799  
   800  	case int64Val:
   801  		if s == 0 {
   802  			return x
   803  		}
   804  		switch op {
   805  		case token.SHL:
   806  			z := big.NewInt(int64(x))
   807  			return normInt(z.Lsh(z, s))
   808  		case token.SHR:
   809  			return x >> s
   810  		}
   811  
   812  	case intVal:
   813  		if s == 0 {
   814  			return x
   815  		}
   816  		var z big.Int
   817  		switch op {
   818  		case token.SHL:
   819  			return normInt(z.Lsh(x.val, s))
   820  		case token.SHR:
   821  			return normInt(z.Rsh(x.val, s))
   822  		}
   823  	}
   824  
   825  	panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s))
   826  }
   827  
   828  func cmpZero(x int, op token.Token) bool {
   829  	switch op {
   830  	case token.EQL:
   831  		return x == 0
   832  	case token.NEQ:
   833  		return x != 0
   834  	case token.LSS:
   835  		return x < 0
   836  	case token.LEQ:
   837  		return x <= 0
   838  	case token.GTR:
   839  		return x > 0
   840  	case token.GEQ:
   841  		return x >= 0
   842  	}
   843  	panic("unreachable")
   844  }
   845  
   846  // Compare returns the result of the comparison x op y.
   847  // The comparison must be defined for the operands.
   848  // If one of the operands is Unknown, the result is
   849  // false.
   850  //
   851  func Compare(x Value, op token.Token, y Value) bool {
   852  	x, y = match(x, y)
   853  
   854  	switch x := x.(type) {
   855  	case unknownVal:
   856  		return false
   857  
   858  	case boolVal:
   859  		y := y.(boolVal)
   860  		switch op {
   861  		case token.EQL:
   862  			return x == y
   863  		case token.NEQ:
   864  			return x != y
   865  		}
   866  
   867  	case int64Val:
   868  		y := y.(int64Val)
   869  		switch op {
   870  		case token.EQL:
   871  			return x == y
   872  		case token.NEQ:
   873  			return x != y
   874  		case token.LSS:
   875  			return x < y
   876  		case token.LEQ:
   877  			return x <= y
   878  		case token.GTR:
   879  			return x > y
   880  		case token.GEQ:
   881  			return x >= y
   882  		}
   883  
   884  	case intVal:
   885  		return cmpZero(x.val.Cmp(y.(intVal).val), op)
   886  
   887  	case floatVal:
   888  		return cmpZero(x.val.Cmp(y.(floatVal).val), op)
   889  
   890  	case complexVal:
   891  		y := y.(complexVal)
   892  		re := x.re.Cmp(y.re)
   893  		im := x.im.Cmp(y.im)
   894  		switch op {
   895  		case token.EQL:
   896  			return re == 0 && im == 0
   897  		case token.NEQ:
   898  			return re != 0 || im != 0
   899  		}
   900  
   901  	case stringVal:
   902  		y := y.(stringVal)
   903  		switch op {
   904  		case token.EQL:
   905  			return x == y
   906  		case token.NEQ:
   907  			return x != y
   908  		case token.LSS:
   909  			return x < y
   910  		case token.LEQ:
   911  			return x <= y
   912  		case token.GTR:
   913  			return x > y
   914  		case token.GEQ:
   915  			return x >= y
   916  		}
   917  	}
   918  
   919  	panic(fmt.Sprintf("invalid comparison %v %s %v", x, op, y))
   920  }