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