github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/go/constant/value.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 constant implements Values representing untyped 6 // Go constants and their corresponding operations. 7 // 8 // A special Unknown value may be used when a value 9 // is unknown due to an error. Operations on unknown 10 // values produce unknown values unless specified 11 // otherwise. 12 // 13 package constant // import "go/constant" 14 15 import ( 16 "fmt" 17 "go/token" 18 "math" 19 "math/big" 20 "strconv" 21 "unicode/utf8" 22 ) 23 24 // Kind specifies the kind of value represented by a Value. 25 type Kind int 26 27 const ( 28 // unknown values 29 Unknown Kind = iota 30 31 // non-numeric values 32 Bool 33 String 34 35 // numeric values 36 Int 37 Float 38 Complex 39 ) 40 41 // A Value represents the value of a Go constant. 42 type Value interface { 43 // Kind returns the value kind. 44 Kind() Kind 45 46 // String returns a short, quoted (human-readable) form of the value. 47 // For numeric values, the result may be an approximation; 48 // for String values the result may be a shortened string. 49 // Use ExactString for a string representing a value exactly. 50 String() string 51 52 // ExactString returns an exact, quoted (human-readable) form of the value. 53 // If the Value is of Kind String, use StringVal to obtain the unquoted string. 54 ExactString() string 55 56 // Prevent external implementations. 57 implementsValue() 58 } 59 60 // ---------------------------------------------------------------------------- 61 // Implementations 62 63 // Maximum supported mantissa precision. 64 // The spec requires at least 256 bits; typical implementations use 512 bits. 65 const prec = 512 66 67 type ( 68 unknownVal struct{} 69 boolVal bool 70 stringVal string 71 int64Val int64 // Int values representable as an int64 72 intVal struct{ val *big.Int } // Int values not representable as an int64 73 ratVal struct{ val *big.Rat } // Float values representable as a fraction 74 floatVal struct{ val *big.Float } // Float values not representable as a fraction 75 complexVal struct{ re, im Value } 76 ) 77 78 func (unknownVal) Kind() Kind { return Unknown } 79 func (boolVal) Kind() Kind { return Bool } 80 func (stringVal) Kind() Kind { return String } 81 func (int64Val) Kind() Kind { return Int } 82 func (intVal) Kind() Kind { return Int } 83 func (ratVal) Kind() Kind { return Float } 84 func (floatVal) Kind() Kind { return Float } 85 func (complexVal) Kind() Kind { return Complex } 86 87 func (unknownVal) String() string { return "unknown" } 88 func (x boolVal) String() string { return strconv.FormatBool(bool(x)) } 89 90 // String returns a possibly shortened quoted form of the String value. 91 func (x stringVal) String() string { 92 const maxLen = 72 // a reasonable length 93 s := strconv.Quote(string(x)) 94 if utf8.RuneCountInString(s) > maxLen { 95 // The string without the enclosing quotes is greater than maxLen-2 runes 96 // long. Remove the last 3 runes (including the closing '"') by keeping 97 // only the first maxLen-3 runes; then add "...". 98 i := 0 99 for n := 0; n < maxLen-3; n++ { 100 _, size := utf8.DecodeRuneInString(s[i:]) 101 i += size 102 } 103 s = s[:i] + "..." 104 } 105 return s 106 } 107 108 func (x int64Val) String() string { return strconv.FormatInt(int64(x), 10) } 109 func (x intVal) String() string { return x.val.String() } 110 func (x ratVal) String() string { return rtof(x).String() } 111 112 // String returns returns a decimal approximation of the Float value. 113 func (x floatVal) String() string { 114 f := x.val 115 116 // Don't try to convert infinities (will not terminate). 117 if f.IsInf() { 118 return f.String() 119 } 120 121 // Use exact fmt formatting if in float64 range (common case): 122 // proceed if f doesn't underflow to 0 or overflow to inf. 123 if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) { 124 return fmt.Sprintf("%.6g", x) 125 } 126 127 // Out of float64 range. Do approximate manual to decimal 128 // conversion to avoid precise but possibly slow Float 129 // formatting. 130 // f = mant * 2**exp 131 var mant big.Float 132 exp := f.MantExp(&mant) // 0.5 <= |mant| < 1.0 133 134 // approximate float64 mantissa m and decimal exponent d 135 // f ~ m * 10**d 136 m, _ := mant.Float64() // 0.5 <= |m| < 1.0 137 d := float64(exp) * (math.Ln2 / math.Ln10) // log_10(2) 138 139 // adjust m for truncated (integer) decimal exponent e 140 e := int64(d) 141 m *= math.Pow(10, d-float64(e)) 142 143 // ensure 1 <= |m| < 10 144 switch am := math.Abs(m); { 145 case am < 1-0.5e-6: 146 // The %.6g format below rounds m to 5 digits after the 147 // decimal point. Make sure that m*10 < 10 even after 148 // rounding up: m*10 + 0.5e-5 < 10 => m < 1 - 0.5e6. 149 m *= 10 150 e-- 151 case am >= 10: 152 m /= 10 153 e++ 154 } 155 156 return fmt.Sprintf("%.6ge%+d", m, e) 157 } 158 159 func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) } 160 161 func (x unknownVal) ExactString() string { return x.String() } 162 func (x boolVal) ExactString() string { return x.String() } 163 func (x stringVal) ExactString() string { return strconv.Quote(string(x)) } 164 func (x int64Val) ExactString() string { return x.String() } 165 func (x intVal) ExactString() string { return x.String() } 166 167 func (x ratVal) ExactString() string { 168 r := x.val 169 if r.IsInt() { 170 return r.Num().String() 171 } 172 return r.String() 173 } 174 175 func (x floatVal) ExactString() string { return x.val.Text('p', 0) } 176 177 func (x complexVal) ExactString() string { 178 return fmt.Sprintf("(%s + %si)", x.re.ExactString(), x.im.ExactString()) 179 } 180 181 func (unknownVal) implementsValue() {} 182 func (boolVal) implementsValue() {} 183 func (stringVal) implementsValue() {} 184 func (int64Val) implementsValue() {} 185 func (ratVal) implementsValue() {} 186 func (intVal) implementsValue() {} 187 func (floatVal) implementsValue() {} 188 func (complexVal) implementsValue() {} 189 190 func newInt() *big.Int { return new(big.Int) } 191 func newRat() *big.Rat { return new(big.Rat) } 192 func newFloat() *big.Float { return new(big.Float).SetPrec(prec) } 193 194 func i64toi(x int64Val) intVal { return intVal{newInt().SetInt64(int64(x))} } 195 func i64tor(x int64Val) ratVal { return ratVal{newRat().SetInt64(int64(x))} } 196 func i64tof(x int64Val) floatVal { return floatVal{newFloat().SetInt64(int64(x))} } 197 func itor(x intVal) ratVal { return ratVal{newRat().SetInt(x.val)} } 198 func itof(x intVal) floatVal { return floatVal{newFloat().SetInt(x.val)} } 199 200 func rtof(x ratVal) floatVal { 201 a := newFloat().SetInt(x.val.Num()) 202 b := newFloat().SetInt(x.val.Denom()) 203 return floatVal{a.Quo(a, b)} 204 } 205 206 func vtoc(x Value) complexVal { return complexVal{x, int64Val(0)} } 207 208 var ( 209 minInt64 = big.NewInt(-1 << 63) 210 maxInt64 = big.NewInt(1<<63 - 1) 211 ) 212 213 func makeInt(x *big.Int) Value { 214 if minInt64.Cmp(x) <= 0 && x.Cmp(maxInt64) <= 0 { 215 return int64Val(x.Int64()) 216 } 217 return intVal{x} 218 } 219 220 // Permit fractions with component sizes up to maxExp 221 // before switching to using floating-point numbers. 222 const maxExp = 4 << 10 223 224 func makeRat(x *big.Rat) Value { 225 a := x.Num() 226 b := x.Denom() 227 if a.BitLen() < maxExp && b.BitLen() < maxExp { 228 // ok to remain fraction 229 return ratVal{x} 230 } 231 // components too large => switch to float 232 fa := newFloat().SetInt(a) 233 fb := newFloat().SetInt(b) 234 return floatVal{fa.Quo(fa, fb)} 235 } 236 237 var floatVal0 = floatVal{newFloat()} 238 239 func makeFloat(x *big.Float) Value { 240 // convert -0 241 if x.Sign() == 0 { 242 return floatVal0 243 } 244 return floatVal{x} 245 } 246 247 func makeComplex(re, im Value) Value { 248 return complexVal{re, im} 249 } 250 251 func makeFloatFromLiteral(lit string) Value { 252 if f, ok := newFloat().SetString(lit); ok { 253 if smallRat(f) { 254 // ok to use rationals 255 r, _ := newRat().SetString(lit) 256 return ratVal{r} 257 } 258 // otherwise use floats 259 return makeFloat(f) 260 } 261 return nil 262 } 263 264 // smallRat reports whether x would lead to "reasonably"-sized fraction 265 // if converted to a *big.Rat. 266 func smallRat(x *big.Float) bool { 267 if !x.IsInf() { 268 e := x.MantExp(nil) 269 return -maxExp < e && e < maxExp 270 } 271 return false 272 } 273 274 // ---------------------------------------------------------------------------- 275 // Factories 276 277 // MakeUnknown returns the Unknown value. 278 func MakeUnknown() Value { return unknownVal{} } 279 280 // MakeBool returns the Bool value for b. 281 func MakeBool(b bool) Value { return boolVal(b) } 282 283 // MakeString returns the String value for s. 284 func MakeString(s string) Value { return stringVal(s) } 285 286 // MakeInt64 returns the Int value for x. 287 func MakeInt64(x int64) Value { return int64Val(x) } 288 289 // MakeUint64 returns the Int value for x. 290 func MakeUint64(x uint64) Value { 291 if x < 1<<63 { 292 return int64Val(int64(x)) 293 } 294 return intVal{newInt().SetUint64(x)} 295 } 296 297 // MakeFloat64 returns the Float value for x. 298 // If x is not finite, the result is an Unknown. 299 func MakeFloat64(x float64) Value { 300 if math.IsInf(x, 0) || math.IsNaN(x) { 301 return unknownVal{} 302 } 303 // convert -0 to 0 304 if x == 0 { 305 return int64Val(0) 306 } 307 return ratVal{newRat().SetFloat64(x)} 308 } 309 310 // MakeFromLiteral returns the corresponding integer, floating-point, 311 // imaginary, character, or string value for a Go literal string. The 312 // tok value must be one of token.INT, token.FLOAT, token.IMAG, 313 // token.CHAR, or token.STRING. The final argument must be zero. 314 // If the literal string syntax is invalid, the result is an Unknown. 315 func MakeFromLiteral(lit string, tok token.Token, zero uint) Value { 316 if zero != 0 { 317 panic("MakeFromLiteral called with non-zero last argument") 318 } 319 320 switch tok { 321 case token.INT: 322 if x, err := strconv.ParseInt(lit, 0, 64); err == nil { 323 return int64Val(x) 324 } 325 if x, ok := newInt().SetString(lit, 0); ok { 326 return intVal{x} 327 } 328 329 case token.FLOAT: 330 if x := makeFloatFromLiteral(lit); x != nil { 331 return x 332 } 333 334 case token.IMAG: 335 if n := len(lit); n > 0 && lit[n-1] == 'i' { 336 if im := makeFloatFromLiteral(lit[:n-1]); im != nil { 337 return makeComplex(int64Val(0), im) 338 } 339 } 340 341 case token.CHAR: 342 if n := len(lit); n >= 2 { 343 if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil { 344 return MakeInt64(int64(code)) 345 } 346 } 347 348 case token.STRING: 349 if s, err := strconv.Unquote(lit); err == nil { 350 return MakeString(s) 351 } 352 353 default: 354 panic(fmt.Sprintf("%v is not a valid token", tok)) 355 } 356 357 return unknownVal{} 358 } 359 360 // ---------------------------------------------------------------------------- 361 // Accessors 362 // 363 // For unknown arguments the result is the zero value for the respective 364 // accessor type, except for Sign, where the result is 1. 365 366 // BoolVal returns the Go boolean value of x, which must be a Bool or an Unknown. 367 // If x is Unknown, the result is false. 368 func BoolVal(x Value) bool { 369 switch x := x.(type) { 370 case boolVal: 371 return bool(x) 372 case unknownVal: 373 return false 374 default: 375 panic(fmt.Sprintf("%v not a Bool", x)) 376 } 377 } 378 379 // StringVal returns the Go string value of x, which must be a String or an Unknown. 380 // If x is Unknown, the result is "". 381 func StringVal(x Value) string { 382 switch x := x.(type) { 383 case stringVal: 384 return string(x) 385 case unknownVal: 386 return "" 387 default: 388 panic(fmt.Sprintf("%v not a String", x)) 389 } 390 } 391 392 // Int64Val returns the Go int64 value of x and whether the result is exact; 393 // x must be an Int or an Unknown. If the result is not exact, its value is undefined. 394 // If x is Unknown, the result is (0, false). 395 func Int64Val(x Value) (int64, bool) { 396 switch x := x.(type) { 397 case int64Val: 398 return int64(x), true 399 case intVal: 400 return x.val.Int64(), false // not an int64Val and thus not exact 401 case unknownVal: 402 return 0, false 403 default: 404 panic(fmt.Sprintf("%v not an Int", x)) 405 } 406 } 407 408 // Uint64Val returns the Go uint64 value of x and whether the result is exact; 409 // x must be an Int or an Unknown. If the result is not exact, its value is undefined. 410 // If x is Unknown, the result is (0, false). 411 func Uint64Val(x Value) (uint64, bool) { 412 switch x := x.(type) { 413 case int64Val: 414 return uint64(x), x >= 0 415 case intVal: 416 return x.val.Uint64(), x.val.Sign() >= 0 && x.val.BitLen() <= 64 417 case unknownVal: 418 return 0, false 419 default: 420 panic(fmt.Sprintf("%v not an Int", x)) 421 } 422 } 423 424 // Float32Val is like Float64Val but for float32 instead of float64. 425 func Float32Val(x Value) (float32, bool) { 426 switch x := x.(type) { 427 case int64Val: 428 f := float32(x) 429 return f, int64Val(f) == x 430 case intVal: 431 f, acc := newFloat().SetInt(x.val).Float32() 432 return f, acc == big.Exact 433 case ratVal: 434 return x.val.Float32() 435 case floatVal: 436 f, acc := x.val.Float32() 437 return f, acc == big.Exact 438 case unknownVal: 439 return 0, false 440 default: 441 panic(fmt.Sprintf("%v not a Float", x)) 442 } 443 } 444 445 // Float64Val returns the nearest Go float64 value of x and whether the result is exact; 446 // x must be numeric or an Unknown, but not Complex. For values too small (too close to 0) 447 // to represent as float64, Float64Val silently underflows to 0. The result sign always 448 // matches the sign of x, even for 0. 449 // If x is Unknown, the result is (0, false). 450 func Float64Val(x Value) (float64, bool) { 451 switch x := x.(type) { 452 case int64Val: 453 f := float64(int64(x)) 454 return f, int64Val(f) == x 455 case intVal: 456 f, acc := newFloat().SetInt(x.val).Float64() 457 return f, acc == big.Exact 458 case ratVal: 459 return x.val.Float64() 460 case floatVal: 461 f, acc := x.val.Float64() 462 return f, acc == big.Exact 463 case unknownVal: 464 return 0, false 465 default: 466 panic(fmt.Sprintf("%v not a Float", x)) 467 } 468 } 469 470 // BitLen returns the number of bits required to represent 471 // the absolute value x in binary representation; x must be an Int or an Unknown. 472 // If x is Unknown, the result is 0. 473 func BitLen(x Value) int { 474 switch x := x.(type) { 475 case int64Val: 476 return i64toi(x).val.BitLen() 477 case intVal: 478 return x.val.BitLen() 479 case unknownVal: 480 return 0 481 default: 482 panic(fmt.Sprintf("%v not an Int", x)) 483 } 484 } 485 486 // Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0; 487 // x must be numeric or Unknown. For complex values x, the sign is 0 if x == 0, 488 // otherwise it is != 0. If x is Unknown, the result is 1. 489 func Sign(x Value) int { 490 switch x := x.(type) { 491 case int64Val: 492 switch { 493 case x < 0: 494 return -1 495 case x > 0: 496 return 1 497 } 498 return 0 499 case intVal: 500 return x.val.Sign() 501 case ratVal: 502 return x.val.Sign() 503 case floatVal: 504 return x.val.Sign() 505 case complexVal: 506 return Sign(x.re) | Sign(x.im) 507 case unknownVal: 508 return 1 // avoid spurious division by zero errors 509 default: 510 panic(fmt.Sprintf("%v not numeric", x)) 511 } 512 } 513 514 // ---------------------------------------------------------------------------- 515 // Support for assembling/disassembling numeric values 516 517 const ( 518 // Compute the size of a Word in bytes. 519 _m = ^big.Word(0) 520 _log = _m>>8&1 + _m>>16&1 + _m>>32&1 521 wordSize = 1 << _log 522 ) 523 524 // Bytes returns the bytes for the absolute value of x in little- 525 // endian binary representation; x must be an Int. 526 func Bytes(x Value) []byte { 527 var t intVal 528 switch x := x.(type) { 529 case int64Val: 530 t = i64toi(x) 531 case intVal: 532 t = x 533 default: 534 panic(fmt.Sprintf("%v not an Int", x)) 535 } 536 537 words := t.val.Bits() 538 bytes := make([]byte, len(words)*wordSize) 539 540 i := 0 541 for _, w := range words { 542 for j := 0; j < wordSize; j++ { 543 bytes[i] = byte(w) 544 w >>= 8 545 i++ 546 } 547 } 548 // remove leading 0's 549 for i > 0 && bytes[i-1] == 0 { 550 i-- 551 } 552 553 return bytes[:i] 554 } 555 556 // MakeFromBytes returns the Int value given the bytes of its little-endian 557 // binary representation. An empty byte slice argument represents 0. 558 func MakeFromBytes(bytes []byte) Value { 559 words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize) 560 561 i := 0 562 var w big.Word 563 var s uint 564 for _, b := range bytes { 565 w |= big.Word(b) << s 566 if s += 8; s == wordSize*8 { 567 words[i] = w 568 i++ 569 w = 0 570 s = 0 571 } 572 } 573 // store last word 574 if i < len(words) { 575 words[i] = w 576 i++ 577 } 578 // remove leading 0's 579 for i > 0 && words[i-1] == 0 { 580 i-- 581 } 582 583 return makeInt(newInt().SetBits(words[:i])) 584 } 585 586 // Num returns the numerator of x; x must be Int, Float, or Unknown. 587 // If x is Unknown, or if it is too large or small to represent as a 588 // fraction, the result is Unknown. Otherwise the result is an Int 589 // with the same sign as x. 590 func Num(x Value) Value { 591 switch x := x.(type) { 592 case int64Val, intVal: 593 return x 594 case ratVal: 595 return makeInt(x.val.Num()) 596 case floatVal: 597 if smallRat(x.val) { 598 r, _ := x.val.Rat(nil) 599 return makeInt(r.Num()) 600 } 601 case unknownVal: 602 break 603 default: 604 panic(fmt.Sprintf("%v not Int or Float", x)) 605 } 606 return unknownVal{} 607 } 608 609 // Denom returns the denominator of x; x must be Int, Float, or Unknown. 610 // If x is Unknown, or if it is too large or small to represent as a 611 // fraction, the result is Unknown. Otherwise the result is an Int >= 1. 612 func Denom(x Value) Value { 613 switch x := x.(type) { 614 case int64Val, intVal: 615 return int64Val(1) 616 case ratVal: 617 return makeInt(x.val.Denom()) 618 case floatVal: 619 if smallRat(x.val) { 620 r, _ := x.val.Rat(nil) 621 return makeInt(r.Denom()) 622 } 623 case unknownVal: 624 break 625 default: 626 panic(fmt.Sprintf("%v not Int or Float", x)) 627 } 628 return unknownVal{} 629 } 630 631 // MakeImag returns the Complex value x*i; 632 // x must be Int, Float, or Unknown. 633 // If x is Unknown, the result is Unknown. 634 func MakeImag(x Value) Value { 635 switch x.(type) { 636 case unknownVal: 637 return x 638 case int64Val, intVal, ratVal, floatVal: 639 return makeComplex(int64Val(0), x) 640 default: 641 panic(fmt.Sprintf("%v not Int or Float", x)) 642 } 643 } 644 645 // Real returns the real part of x, which must be a numeric or unknown value. 646 // If x is Unknown, the result is Unknown. 647 func Real(x Value) Value { 648 switch x := x.(type) { 649 case unknownVal, int64Val, intVal, ratVal, floatVal: 650 return x 651 case complexVal: 652 return x.re 653 default: 654 panic(fmt.Sprintf("%v not numeric", x)) 655 } 656 } 657 658 // Imag returns the imaginary part of x, which must be a numeric or unknown value. 659 // If x is Unknown, the result is Unknown. 660 func Imag(x Value) Value { 661 switch x := x.(type) { 662 case unknownVal: 663 return x 664 case int64Val, intVal, ratVal, floatVal: 665 return int64Val(0) 666 case complexVal: 667 return x.im 668 default: 669 panic(fmt.Sprintf("%v not numeric", x)) 670 } 671 } 672 673 // ---------------------------------------------------------------------------- 674 // Numeric conversions 675 676 // ToInt converts x to an Int value if x is representable as an Int. 677 // Otherwise it returns an Unknown. 678 func ToInt(x Value) Value { 679 switch x := x.(type) { 680 case int64Val, intVal: 681 return x 682 683 case ratVal: 684 if x.val.IsInt() { 685 return makeInt(x.val.Num()) 686 } 687 688 case floatVal: 689 // avoid creation of huge integers 690 // (Existing tests require permitting exponents of at least 1024; 691 // allow any value that would also be permissible as a fraction.) 692 if smallRat(x.val) { 693 i := newInt() 694 if _, acc := x.val.Int(i); acc == big.Exact { 695 return makeInt(i) 696 } 697 698 // If we can get an integer by rounding up or down, 699 // assume x is not an integer because of rounding 700 // errors in prior computations. 701 702 const delta = 4 // a small number of bits > 0 703 var t big.Float 704 t.SetPrec(prec - delta) 705 706 // try rounding down a little 707 t.SetMode(big.ToZero) 708 t.Set(x.val) 709 if _, acc := t.Int(i); acc == big.Exact { 710 return makeInt(i) 711 } 712 713 // try rounding up a little 714 t.SetMode(big.AwayFromZero) 715 t.Set(x.val) 716 if _, acc := t.Int(i); acc == big.Exact { 717 return makeInt(i) 718 } 719 } 720 721 case complexVal: 722 if re := ToFloat(x); re.Kind() == Float { 723 return ToInt(re) 724 } 725 } 726 727 return unknownVal{} 728 } 729 730 // ToFloat converts x to a Float value if x is representable as a Float. 731 // Otherwise it returns an Unknown. 732 func ToFloat(x Value) Value { 733 switch x := x.(type) { 734 case int64Val: 735 return i64tof(x) 736 case intVal: 737 return itof(x) 738 case ratVal, floatVal: 739 return x 740 case complexVal: 741 if im := ToInt(x.im); im.Kind() == Int && Sign(im) == 0 { 742 // imaginary component is 0 743 return ToFloat(x.re) 744 } 745 } 746 return unknownVal{} 747 } 748 749 // ToComplex converts x to a Complex value if x is representable as a Complex. 750 // Otherwise it returns an Unknown. 751 func ToComplex(x Value) Value { 752 switch x := x.(type) { 753 case int64Val: 754 return vtoc(i64tof(x)) 755 case intVal: 756 return vtoc(itof(x)) 757 case ratVal: 758 return vtoc(x) 759 case floatVal: 760 return vtoc(x) 761 case complexVal: 762 return x 763 } 764 return unknownVal{} 765 } 766 767 // ---------------------------------------------------------------------------- 768 // Operations 769 770 // is32bit reports whether x can be represented using 32 bits. 771 func is32bit(x int64) bool { 772 const s = 32 773 return -1<<(s-1) <= x && x <= 1<<(s-1)-1 774 } 775 776 // is63bit reports whether x can be represented using 63 bits. 777 func is63bit(x int64) bool { 778 const s = 63 779 return -1<<(s-1) <= x && x <= 1<<(s-1)-1 780 } 781 782 // UnaryOp returns the result of the unary expression op y. 783 // The operation must be defined for the operand. 784 // If prec > 0 it specifies the ^ (xor) result size in bits. 785 // If y is Unknown, the result is Unknown. 786 // 787 func UnaryOp(op token.Token, y Value, prec uint) Value { 788 switch op { 789 case token.ADD: 790 switch y.(type) { 791 case unknownVal, int64Val, intVal, ratVal, floatVal, complexVal: 792 return y 793 } 794 795 case token.SUB: 796 switch y := y.(type) { 797 case unknownVal: 798 return y 799 case int64Val: 800 if z := -y; z != y { 801 return z // no overflow 802 } 803 return makeInt(newInt().Neg(big.NewInt(int64(y)))) 804 case intVal: 805 return makeInt(newInt().Neg(y.val)) 806 case ratVal: 807 return makeRat(newRat().Neg(y.val)) 808 case floatVal: 809 return makeFloat(newFloat().Neg(y.val)) 810 case complexVal: 811 re := UnaryOp(token.SUB, y.re, 0) 812 im := UnaryOp(token.SUB, y.im, 0) 813 return makeComplex(re, im) 814 } 815 816 case token.XOR: 817 z := newInt() 818 switch y := y.(type) { 819 case unknownVal: 820 return y 821 case int64Val: 822 z.Not(big.NewInt(int64(y))) 823 case intVal: 824 z.Not(y.val) 825 default: 826 goto Error 827 } 828 // For unsigned types, the result will be negative and 829 // thus "too large": We must limit the result precision 830 // to the type's precision. 831 if prec > 0 { 832 z.AndNot(z, newInt().Lsh(big.NewInt(-1), prec)) // z &^= (-1)<<prec 833 } 834 return makeInt(z) 835 836 case token.NOT: 837 switch y := y.(type) { 838 case unknownVal: 839 return y 840 case boolVal: 841 return !y 842 } 843 } 844 845 Error: 846 panic(fmt.Sprintf("invalid unary operation %s%v", op, y)) 847 } 848 849 func ord(x Value) int { 850 switch x.(type) { 851 case unknownVal: 852 return 0 853 case boolVal, stringVal: 854 return 1 855 case int64Val: 856 return 2 857 case intVal: 858 return 3 859 case ratVal: 860 return 4 861 case floatVal: 862 return 5 863 case complexVal: 864 return 6 865 default: 866 panic("unreachable") 867 } 868 } 869 870 // match returns the matching representation (same type) with the 871 // smallest complexity for two values x and y. If one of them is 872 // numeric, both of them must be numeric. If one of them is Unknown, 873 // both results are Unknown. 874 // 875 func match(x, y Value) (_, _ Value) { 876 if ord(x) > ord(y) { 877 y, x = match(y, x) 878 return x, y 879 } 880 // ord(x) <= ord(y) 881 882 switch x := x.(type) { 883 case unknownVal: 884 return x, x 885 886 case boolVal, stringVal, complexVal: 887 return x, y 888 889 case int64Val: 890 switch y := y.(type) { 891 case int64Val: 892 return x, y 893 case intVal: 894 return i64toi(x), y 895 case ratVal: 896 return i64tor(x), y 897 case floatVal: 898 return i64tof(x), y 899 case complexVal: 900 return vtoc(x), y 901 } 902 903 case intVal: 904 switch y := y.(type) { 905 case intVal: 906 return x, y 907 case ratVal: 908 return itor(x), y 909 case floatVal: 910 return itof(x), y 911 case complexVal: 912 return vtoc(x), y 913 } 914 915 case ratVal: 916 switch y := y.(type) { 917 case ratVal: 918 return x, y 919 case floatVal: 920 return rtof(x), y 921 case complexVal: 922 return vtoc(x), y 923 } 924 case floatVal: 925 switch y := y.(type) { 926 case floatVal: 927 return x, y 928 case complexVal: 929 return vtoc(x), y 930 } 931 } 932 933 panic("unreachable") 934 } 935 936 // BinaryOp returns the result of the binary expression x op y. 937 // The operation must be defined for the operands. If one of the 938 // operands is Unknown, the result is Unknown. 939 // To force integer division of Int operands, use op == token.QUO_ASSIGN 940 // instead of token.QUO; the result is guaranteed to be Int in this case. 941 // Division by zero leads to a run-time panic. 942 // 943 func BinaryOp(x Value, op token.Token, y Value) Value { 944 x, y = match(x, y) 945 946 switch x := x.(type) { 947 case unknownVal: 948 return x 949 950 case boolVal: 951 y := y.(boolVal) 952 switch op { 953 case token.LAND: 954 return x && y 955 case token.LOR: 956 return x || y 957 } 958 959 case int64Val: 960 a := int64(x) 961 b := int64(y.(int64Val)) 962 var c int64 963 switch op { 964 case token.ADD: 965 if !is63bit(a) || !is63bit(b) { 966 return makeInt(newInt().Add(big.NewInt(a), big.NewInt(b))) 967 } 968 c = a + b 969 case token.SUB: 970 if !is63bit(a) || !is63bit(b) { 971 return makeInt(newInt().Sub(big.NewInt(a), big.NewInt(b))) 972 } 973 c = a - b 974 case token.MUL: 975 if !is32bit(a) || !is32bit(b) { 976 return makeInt(newInt().Mul(big.NewInt(a), big.NewInt(b))) 977 } 978 c = a * b 979 case token.QUO: 980 return makeRat(big.NewRat(a, b)) 981 case token.QUO_ASSIGN: // force integer division 982 c = a / b 983 case token.REM: 984 c = a % b 985 case token.AND: 986 c = a & b 987 case token.OR: 988 c = a | b 989 case token.XOR: 990 c = a ^ b 991 case token.AND_NOT: 992 c = a &^ b 993 default: 994 goto Error 995 } 996 return int64Val(c) 997 998 case intVal: 999 a := x.val 1000 b := y.(intVal).val 1001 c := newInt() 1002 switch op { 1003 case token.ADD: 1004 c.Add(a, b) 1005 case token.SUB: 1006 c.Sub(a, b) 1007 case token.MUL: 1008 c.Mul(a, b) 1009 case token.QUO: 1010 return makeRat(newRat().SetFrac(a, b)) 1011 case token.QUO_ASSIGN: // force integer division 1012 c.Quo(a, b) 1013 case token.REM: 1014 c.Rem(a, b) 1015 case token.AND: 1016 c.And(a, b) 1017 case token.OR: 1018 c.Or(a, b) 1019 case token.XOR: 1020 c.Xor(a, b) 1021 case token.AND_NOT: 1022 c.AndNot(a, b) 1023 default: 1024 goto Error 1025 } 1026 return makeInt(c) 1027 1028 case ratVal: 1029 a := x.val 1030 b := y.(ratVal).val 1031 c := newRat() 1032 switch op { 1033 case token.ADD: 1034 c.Add(a, b) 1035 case token.SUB: 1036 c.Sub(a, b) 1037 case token.MUL: 1038 c.Mul(a, b) 1039 case token.QUO: 1040 c.Quo(a, b) 1041 default: 1042 goto Error 1043 } 1044 return makeRat(c) 1045 1046 case floatVal: 1047 a := x.val 1048 b := y.(floatVal).val 1049 c := newFloat() 1050 switch op { 1051 case token.ADD: 1052 c.Add(a, b) 1053 case token.SUB: 1054 c.Sub(a, b) 1055 case token.MUL: 1056 c.Mul(a, b) 1057 case token.QUO: 1058 c.Quo(a, b) 1059 default: 1060 goto Error 1061 } 1062 return makeFloat(c) 1063 1064 case complexVal: 1065 y := y.(complexVal) 1066 a, b := x.re, x.im 1067 c, d := y.re, y.im 1068 var re, im Value 1069 switch op { 1070 case token.ADD: 1071 // (a+c) + i(b+d) 1072 re = add(a, c) 1073 im = add(b, d) 1074 case token.SUB: 1075 // (a-c) + i(b-d) 1076 re = sub(a, c) 1077 im = sub(b, d) 1078 case token.MUL: 1079 // (ac-bd) + i(bc+ad) 1080 ac := mul(a, c) 1081 bd := mul(b, d) 1082 bc := mul(b, c) 1083 ad := mul(a, d) 1084 re = sub(ac, bd) 1085 im = add(bc, ad) 1086 case token.QUO: 1087 // (ac+bd)/s + i(bc-ad)/s, with s = cc + dd 1088 ac := mul(a, c) 1089 bd := mul(b, d) 1090 bc := mul(b, c) 1091 ad := mul(a, d) 1092 cc := mul(c, c) 1093 dd := mul(d, d) 1094 s := add(cc, dd) 1095 re = add(ac, bd) 1096 re = quo(re, s) 1097 im = sub(bc, ad) 1098 im = quo(im, s) 1099 default: 1100 goto Error 1101 } 1102 return makeComplex(re, im) 1103 1104 case stringVal: 1105 if op == token.ADD { 1106 return x + y.(stringVal) 1107 } 1108 } 1109 1110 Error: 1111 panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y)) 1112 } 1113 1114 func add(x, y Value) Value { return BinaryOp(x, token.ADD, y) } 1115 func sub(x, y Value) Value { return BinaryOp(x, token.SUB, y) } 1116 func mul(x, y Value) Value { return BinaryOp(x, token.MUL, y) } 1117 func quo(x, y Value) Value { return BinaryOp(x, token.QUO, y) } 1118 1119 // Shift returns the result of the shift expression x op s 1120 // with op == token.SHL or token.SHR (<< or >>). x must be 1121 // an Int or an Unknown. If x is Unknown, the result is x. 1122 // 1123 func Shift(x Value, op token.Token, s uint) Value { 1124 switch x := x.(type) { 1125 case unknownVal: 1126 return x 1127 1128 case int64Val: 1129 if s == 0 { 1130 return x 1131 } 1132 switch op { 1133 case token.SHL: 1134 z := i64toi(x).val 1135 return makeInt(z.Lsh(z, s)) 1136 case token.SHR: 1137 return x >> s 1138 } 1139 1140 case intVal: 1141 if s == 0 { 1142 return x 1143 } 1144 z := newInt() 1145 switch op { 1146 case token.SHL: 1147 return makeInt(z.Lsh(x.val, s)) 1148 case token.SHR: 1149 return makeInt(z.Rsh(x.val, s)) 1150 } 1151 } 1152 1153 panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s)) 1154 } 1155 1156 func cmpZero(x int, op token.Token) bool { 1157 switch op { 1158 case token.EQL: 1159 return x == 0 1160 case token.NEQ: 1161 return x != 0 1162 case token.LSS: 1163 return x < 0 1164 case token.LEQ: 1165 return x <= 0 1166 case token.GTR: 1167 return x > 0 1168 case token.GEQ: 1169 return x >= 0 1170 } 1171 panic("unreachable") 1172 } 1173 1174 // Compare returns the result of the comparison x op y. 1175 // The comparison must be defined for the operands. 1176 // If one of the operands is Unknown, the result is 1177 // false. 1178 // 1179 func Compare(x Value, op token.Token, y Value) bool { 1180 x, y = match(x, y) 1181 1182 switch x := x.(type) { 1183 case unknownVal: 1184 return false 1185 1186 case boolVal: 1187 y := y.(boolVal) 1188 switch op { 1189 case token.EQL: 1190 return x == y 1191 case token.NEQ: 1192 return x != y 1193 } 1194 1195 case int64Val: 1196 y := y.(int64Val) 1197 switch op { 1198 case token.EQL: 1199 return x == y 1200 case token.NEQ: 1201 return x != y 1202 case token.LSS: 1203 return x < y 1204 case token.LEQ: 1205 return x <= y 1206 case token.GTR: 1207 return x > y 1208 case token.GEQ: 1209 return x >= y 1210 } 1211 1212 case intVal: 1213 return cmpZero(x.val.Cmp(y.(intVal).val), op) 1214 1215 case ratVal: 1216 return cmpZero(x.val.Cmp(y.(ratVal).val), op) 1217 1218 case floatVal: 1219 return cmpZero(x.val.Cmp(y.(floatVal).val), op) 1220 1221 case complexVal: 1222 y := y.(complexVal) 1223 re := Compare(x.re, token.EQL, y.re) 1224 im := Compare(x.im, token.EQL, y.im) 1225 switch op { 1226 case token.EQL: 1227 return re && im 1228 case token.NEQ: 1229 return !re || !im 1230 } 1231 1232 case stringVal: 1233 y := y.(stringVal) 1234 switch op { 1235 case token.EQL: 1236 return x == y 1237 case token.NEQ: 1238 return x != y 1239 case token.LSS: 1240 return x < y 1241 case token.LEQ: 1242 return x <= y 1243 case token.GTR: 1244 return x > y 1245 case token.GEQ: 1246 return x >= y 1247 } 1248 } 1249 1250 panic(fmt.Sprintf("invalid comparison %v %s %v", x, op, y)) 1251 }