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