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