github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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 r, _ := newRat().SetString(lit) 251 return ratVal{r} 252 } 253 // otherwise use floats 254 return makeFloat(f) 255 } 256 return nil 257 } 258 259 // smallRat reports whether x would lead to "reasonably"-sized fraction 260 // if converted to a *big.Rat. 261 func smallRat(x *big.Float) bool { 262 if !x.IsInf() { 263 e := x.MantExp(nil) 264 return -maxExp < e && e < maxExp 265 } 266 return false 267 } 268 269 // ---------------------------------------------------------------------------- 270 // Factories 271 272 // MakeUnknown returns the Unknown value. 273 func MakeUnknown() Value { return unknownVal{} } 274 275 // MakeBool returns the Bool value for b. 276 func MakeBool(b bool) Value { return boolVal(b) } 277 278 // MakeString returns the String value for s. 279 func MakeString(s string) Value { return stringVal(s) } 280 281 // MakeInt64 returns the Int value for x. 282 func MakeInt64(x int64) Value { return int64Val(x) } 283 284 // MakeUint64 returns the Int value for x. 285 func MakeUint64(x uint64) Value { 286 if x < 1<<63 { 287 return int64Val(int64(x)) 288 } 289 return intVal{newInt().SetUint64(x)} 290 } 291 292 // MakeFloat64 returns the Float value for x. 293 // If x is not finite, the result is an Unknown. 294 func MakeFloat64(x float64) Value { 295 if math.IsInf(x, 0) || math.IsNaN(x) { 296 return unknownVal{} 297 } 298 // convert -0 to 0 299 if x == 0 { 300 return int64Val(0) 301 } 302 return ratVal{newRat().SetFloat64(x)} 303 } 304 305 // MakeFromLiteral returns the corresponding integer, floating-point, 306 // imaginary, character, or string value for a Go literal string. The 307 // tok value must be one of token.INT, token.FLOAT, token.IMAG, 308 // token.CHAR, or token.STRING. The final argument must be zero. 309 // If the literal string syntax is invalid, the result is an Unknown. 310 func MakeFromLiteral(lit string, tok token.Token, zero uint) Value { 311 if zero != 0 { 312 panic("MakeFromLiteral called with non-zero last argument") 313 } 314 315 switch tok { 316 case token.INT: 317 if x, err := strconv.ParseInt(lit, 0, 64); err == nil { 318 return int64Val(x) 319 } 320 if x, ok := newInt().SetString(lit, 0); ok { 321 return intVal{x} 322 } 323 324 case token.FLOAT: 325 if x := makeFloatFromLiteral(lit); x != nil { 326 return x 327 } 328 329 case token.IMAG: 330 if n := len(lit); n > 0 && lit[n-1] == 'i' { 331 if im := makeFloatFromLiteral(lit[:n-1]); im != nil { 332 return makeComplex(int64Val(0), im) 333 } 334 } 335 336 case token.CHAR: 337 if n := len(lit); n >= 2 { 338 if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil { 339 return MakeInt64(int64(code)) 340 } 341 } 342 343 case token.STRING: 344 if s, err := strconv.Unquote(lit); err == nil { 345 return MakeString(s) 346 } 347 348 default: 349 panic(fmt.Sprintf("%v is not a valid token", tok)) 350 } 351 352 return unknownVal{} 353 } 354 355 // ---------------------------------------------------------------------------- 356 // Accessors 357 // 358 // For unknown arguments the result is the zero value for the respective 359 // accessor type, except for Sign, where the result is 1. 360 361 // BoolVal returns the Go boolean value of x, which must be a Bool or an Unknown. 362 // If x is Unknown, the result is false. 363 func BoolVal(x Value) bool { 364 switch x := x.(type) { 365 case boolVal: 366 return bool(x) 367 case unknownVal: 368 return false 369 default: 370 panic(fmt.Sprintf("%v not a Bool", x)) 371 } 372 } 373 374 // StringVal returns the Go string value of x, which must be a String or an Unknown. 375 // If x is Unknown, the result is "". 376 func StringVal(x Value) string { 377 switch x := x.(type) { 378 case stringVal: 379 return string(x) 380 case unknownVal: 381 return "" 382 default: 383 panic(fmt.Sprintf("%v not a String", x)) 384 } 385 } 386 387 // Int64Val returns the Go int64 value of x and whether the result is exact; 388 // x must be an Int or an Unknown. If the result is not exact, its value is undefined. 389 // If x is Unknown, the result is (0, false). 390 func Int64Val(x Value) (int64, bool) { 391 switch x := x.(type) { 392 case int64Val: 393 return int64(x), true 394 case intVal: 395 return x.val.Int64(), false // not an int64Val and thus not exact 396 case unknownVal: 397 return 0, false 398 default: 399 panic(fmt.Sprintf("%v not an Int", x)) 400 } 401 } 402 403 // Uint64Val returns the Go uint64 value of x and whether the result is exact; 404 // x must be an Int or an Unknown. If the result is not exact, its value is undefined. 405 // If x is Unknown, the result is (0, false). 406 func Uint64Val(x Value) (uint64, bool) { 407 switch x := x.(type) { 408 case int64Val: 409 return uint64(x), x >= 0 410 case intVal: 411 return x.val.Uint64(), x.val.IsUint64() 412 case unknownVal: 413 return 0, false 414 default: 415 panic(fmt.Sprintf("%v not an Int", x)) 416 } 417 } 418 419 // Float32Val is like Float64Val but for float32 instead of float64. 420 func Float32Val(x Value) (float32, bool) { 421 switch x := x.(type) { 422 case int64Val: 423 f := float32(x) 424 return f, int64Val(f) == x 425 case intVal: 426 f, acc := newFloat().SetInt(x.val).Float32() 427 return f, acc == big.Exact 428 case ratVal: 429 return x.val.Float32() 430 case floatVal: 431 f, acc := x.val.Float32() 432 return f, acc == big.Exact 433 case unknownVal: 434 return 0, false 435 default: 436 panic(fmt.Sprintf("%v not a Float", x)) 437 } 438 } 439 440 // Float64Val returns the nearest Go float64 value of x and whether the result is exact; 441 // x must be numeric or an Unknown, but not Complex. For values too small (too close to 0) 442 // to represent as float64, Float64Val silently underflows to 0. The result sign always 443 // matches the sign of x, even for 0. 444 // If x is Unknown, the result is (0, false). 445 func Float64Val(x Value) (float64, bool) { 446 switch x := x.(type) { 447 case int64Val: 448 f := float64(int64(x)) 449 return f, int64Val(f) == x 450 case intVal: 451 f, acc := newFloat().SetInt(x.val).Float64() 452 return f, acc == big.Exact 453 case ratVal: 454 return x.val.Float64() 455 case floatVal: 456 f, acc := x.val.Float64() 457 return f, acc == big.Exact 458 case unknownVal: 459 return 0, false 460 default: 461 panic(fmt.Sprintf("%v not a Float", x)) 462 } 463 } 464 465 // BitLen returns the number of bits required to represent 466 // the absolute value x in binary representation; x must be an Int or an Unknown. 467 // If x is Unknown, the result is 0. 468 func BitLen(x Value) int { 469 switch x := x.(type) { 470 case int64Val: 471 return i64toi(x).val.BitLen() 472 case intVal: 473 return x.val.BitLen() 474 case unknownVal: 475 return 0 476 default: 477 panic(fmt.Sprintf("%v not an Int", x)) 478 } 479 } 480 481 // Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0; 482 // x must be numeric or Unknown. For complex values x, the sign is 0 if x == 0, 483 // otherwise it is != 0. If x is Unknown, the result is 1. 484 func Sign(x Value) int { 485 switch x := x.(type) { 486 case int64Val: 487 switch { 488 case x < 0: 489 return -1 490 case x > 0: 491 return 1 492 } 493 return 0 494 case intVal: 495 return x.val.Sign() 496 case ratVal: 497 return x.val.Sign() 498 case floatVal: 499 return x.val.Sign() 500 case complexVal: 501 return Sign(x.re) | Sign(x.im) 502 case unknownVal: 503 return 1 // avoid spurious division by zero errors 504 default: 505 panic(fmt.Sprintf("%v not numeric", x)) 506 } 507 } 508 509 // ---------------------------------------------------------------------------- 510 // Support for assembling/disassembling numeric values 511 512 const ( 513 // Compute the size of a Word in bytes. 514 _m = ^big.Word(0) 515 _log = _m>>8&1 + _m>>16&1 + _m>>32&1 516 wordSize = 1 << _log 517 ) 518 519 // Bytes returns the bytes for the absolute value of x in little- 520 // endian binary representation; x must be an Int. 521 func Bytes(x Value) []byte { 522 var t intVal 523 switch x := x.(type) { 524 case int64Val: 525 t = i64toi(x) 526 case intVal: 527 t = x 528 default: 529 panic(fmt.Sprintf("%v not an Int", x)) 530 } 531 532 words := t.val.Bits() 533 bytes := make([]byte, len(words)*wordSize) 534 535 i := 0 536 for _, w := range words { 537 for j := 0; j < wordSize; j++ { 538 bytes[i] = byte(w) 539 w >>= 8 540 i++ 541 } 542 } 543 // remove leading 0's 544 for i > 0 && bytes[i-1] == 0 { 545 i-- 546 } 547 548 return bytes[:i] 549 } 550 551 // MakeFromBytes returns the Int value given the bytes of its little-endian 552 // binary representation. An empty byte slice argument represents 0. 553 func MakeFromBytes(bytes []byte) Value { 554 words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize) 555 556 i := 0 557 var w big.Word 558 var s uint 559 for _, b := range bytes { 560 w |= big.Word(b) << s 561 if s += 8; s == wordSize*8 { 562 words[i] = w 563 i++ 564 w = 0 565 s = 0 566 } 567 } 568 // store last word 569 if i < len(words) { 570 words[i] = w 571 i++ 572 } 573 // remove leading 0's 574 for i > 0 && words[i-1] == 0 { 575 i-- 576 } 577 578 return makeInt(newInt().SetBits(words[:i])) 579 } 580 581 // Num returns the numerator of x; x must be Int, Float, or Unknown. 582 // If x is Unknown, or if it is too large or small to represent as a 583 // fraction, the result is Unknown. Otherwise the result is an Int 584 // with the same sign as x. 585 func Num(x Value) Value { 586 switch x := x.(type) { 587 case int64Val, intVal: 588 return x 589 case ratVal: 590 return makeInt(x.val.Num()) 591 case floatVal: 592 if smallRat(x.val) { 593 r, _ := x.val.Rat(nil) 594 return makeInt(r.Num()) 595 } 596 case unknownVal: 597 break 598 default: 599 panic(fmt.Sprintf("%v not Int or Float", x)) 600 } 601 return unknownVal{} 602 } 603 604 // Denom returns the denominator of x; x must be Int, Float, or Unknown. 605 // If x is Unknown, or if it is too large or small to represent as a 606 // fraction, the result is Unknown. Otherwise the result is an Int >= 1. 607 func Denom(x Value) Value { 608 switch x := x.(type) { 609 case int64Val, intVal: 610 return int64Val(1) 611 case ratVal: 612 return makeInt(x.val.Denom()) 613 case floatVal: 614 if smallRat(x.val) { 615 r, _ := x.val.Rat(nil) 616 return makeInt(r.Denom()) 617 } 618 case unknownVal: 619 break 620 default: 621 panic(fmt.Sprintf("%v not Int or Float", x)) 622 } 623 return unknownVal{} 624 } 625 626 // MakeImag returns the Complex value x*i; 627 // x must be Int, Float, or Unknown. 628 // If x is Unknown, the result is Unknown. 629 func MakeImag(x Value) Value { 630 switch x.(type) { 631 case unknownVal: 632 return x 633 case int64Val, intVal, ratVal, floatVal: 634 return makeComplex(int64Val(0), x) 635 default: 636 panic(fmt.Sprintf("%v not Int or Float", x)) 637 } 638 } 639 640 // Real returns the real part of x, which must be a numeric or unknown value. 641 // If x is Unknown, the result is Unknown. 642 func Real(x Value) Value { 643 switch x := x.(type) { 644 case unknownVal, int64Val, intVal, ratVal, floatVal: 645 return x 646 case complexVal: 647 return x.re 648 default: 649 panic(fmt.Sprintf("%v not numeric", x)) 650 } 651 } 652 653 // Imag returns the imaginary part of x, which must be a numeric or unknown value. 654 // If x is Unknown, the result is Unknown. 655 func Imag(x Value) Value { 656 switch x := x.(type) { 657 case unknownVal: 658 return x 659 case int64Val, intVal, ratVal, floatVal: 660 return int64Val(0) 661 case complexVal: 662 return x.im 663 default: 664 panic(fmt.Sprintf("%v not numeric", x)) 665 } 666 } 667 668 // ---------------------------------------------------------------------------- 669 // Numeric conversions 670 671 // ToInt converts x to an Int value if x is representable as an Int. 672 // Otherwise it returns an Unknown. 673 func ToInt(x Value) Value { 674 switch x := x.(type) { 675 case int64Val, intVal: 676 return x 677 678 case ratVal: 679 if x.val.IsInt() { 680 return makeInt(x.val.Num()) 681 } 682 683 case floatVal: 684 // avoid creation of huge integers 685 // (Existing tests require permitting exponents of at least 1024; 686 // allow any value that would also be permissible as a fraction.) 687 if smallRat(x.val) { 688 i := newInt() 689 if _, acc := x.val.Int(i); acc == big.Exact { 690 return makeInt(i) 691 } 692 693 // If we can get an integer by rounding up or down, 694 // assume x is not an integer because of rounding 695 // errors in prior computations. 696 697 const delta = 4 // a small number of bits > 0 698 var t big.Float 699 t.SetPrec(prec - delta) 700 701 // try rounding down a little 702 t.SetMode(big.ToZero) 703 t.Set(x.val) 704 if _, acc := t.Int(i); acc == big.Exact { 705 return makeInt(i) 706 } 707 708 // try rounding up a little 709 t.SetMode(big.AwayFromZero) 710 t.Set(x.val) 711 if _, acc := t.Int(i); acc == big.Exact { 712 return makeInt(i) 713 } 714 } 715 716 case complexVal: 717 if re := ToFloat(x); re.Kind() == Float { 718 return ToInt(re) 719 } 720 } 721 722 return unknownVal{} 723 } 724 725 // ToFloat converts x to a Float value if x is representable as a Float. 726 // Otherwise it returns an Unknown. 727 func ToFloat(x Value) Value { 728 switch x := x.(type) { 729 case int64Val: 730 return i64tof(x) 731 case intVal: 732 return itof(x) 733 case ratVal, floatVal: 734 return x 735 case complexVal: 736 if im := ToInt(x.im); im.Kind() == Int && Sign(im) == 0 { 737 // imaginary component is 0 738 return ToFloat(x.re) 739 } 740 } 741 return unknownVal{} 742 } 743 744 // ToComplex converts x to a Complex value if x is representable as a Complex. 745 // Otherwise it returns an Unknown. 746 func ToComplex(x Value) Value { 747 switch x := x.(type) { 748 case int64Val: 749 return vtoc(i64tof(x)) 750 case intVal: 751 return vtoc(itof(x)) 752 case ratVal: 753 return vtoc(x) 754 case floatVal: 755 return vtoc(x) 756 case complexVal: 757 return x 758 } 759 return unknownVal{} 760 } 761 762 // ---------------------------------------------------------------------------- 763 // Operations 764 765 // is32bit reports whether x can be represented using 32 bits. 766 func is32bit(x int64) bool { 767 const s = 32 768 return -1<<(s-1) <= x && x <= 1<<(s-1)-1 769 } 770 771 // is63bit reports whether x can be represented using 63 bits. 772 func is63bit(x int64) bool { 773 const s = 63 774 return -1<<(s-1) <= x && x <= 1<<(s-1)-1 775 } 776 777 // UnaryOp returns the result of the unary expression op y. 778 // The operation must be defined for the operand. 779 // If prec > 0 it specifies the ^ (xor) result size in bits. 780 // If y is Unknown, the result is Unknown. 781 // 782 func UnaryOp(op token.Token, y Value, prec uint) Value { 783 switch op { 784 case token.ADD: 785 switch y.(type) { 786 case unknownVal, int64Val, intVal, ratVal, floatVal, complexVal: 787 return y 788 } 789 790 case token.SUB: 791 switch y := y.(type) { 792 case unknownVal: 793 return y 794 case int64Val: 795 if z := -y; z != y { 796 return z // no overflow 797 } 798 return makeInt(newInt().Neg(big.NewInt(int64(y)))) 799 case intVal: 800 return makeInt(newInt().Neg(y.val)) 801 case ratVal: 802 return makeRat(newRat().Neg(y.val)) 803 case floatVal: 804 return makeFloat(newFloat().Neg(y.val)) 805 case complexVal: 806 re := UnaryOp(token.SUB, y.re, 0) 807 im := UnaryOp(token.SUB, y.im, 0) 808 return makeComplex(re, im) 809 } 810 811 case token.XOR: 812 z := newInt() 813 switch y := y.(type) { 814 case unknownVal: 815 return y 816 case int64Val: 817 z.Not(big.NewInt(int64(y))) 818 case intVal: 819 z.Not(y.val) 820 default: 821 goto Error 822 } 823 // For unsigned types, the result will be negative and 824 // thus "too large": We must limit the result precision 825 // to the type's precision. 826 if prec > 0 { 827 z.AndNot(z, newInt().Lsh(big.NewInt(-1), prec)) // z &^= (-1)<<prec 828 } 829 return makeInt(z) 830 831 case token.NOT: 832 switch y := y.(type) { 833 case unknownVal: 834 return y 835 case boolVal: 836 return !y 837 } 838 } 839 840 Error: 841 panic(fmt.Sprintf("invalid unary operation %s%v", op, y)) 842 } 843 844 func ord(x Value) int { 845 switch x.(type) { 846 default: 847 // force invalid value into "x position" in match 848 // (don't panic here so that callers can provide a better error message) 849 return -1 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 } 865 } 866 867 // match returns the matching representation (same type) with the 868 // smallest complexity for two values x and y. If one of them is 869 // numeric, both of them must be numeric. If one of them is Unknown 870 // or invalid (say, nil) both results are that value. 871 // 872 func match(x, y Value) (_, _ Value) { 873 if ord(x) > ord(y) { 874 y, x = match(y, x) 875 return x, y 876 } 877 // ord(x) <= ord(y) 878 879 switch x := x.(type) { 880 case boolVal, stringVal, complexVal: 881 return x, y 882 883 case int64Val: 884 switch y := y.(type) { 885 case int64Val: 886 return x, y 887 case intVal: 888 return i64toi(x), y 889 case ratVal: 890 return i64tor(x), y 891 case floatVal: 892 return i64tof(x), y 893 case complexVal: 894 return vtoc(x), y 895 } 896 897 case intVal: 898 switch y := y.(type) { 899 case intVal: 900 return x, y 901 case ratVal: 902 return itor(x), y 903 case floatVal: 904 return itof(x), y 905 case complexVal: 906 return vtoc(x), y 907 } 908 909 case ratVal: 910 switch y := y.(type) { 911 case ratVal: 912 return x, y 913 case floatVal: 914 return rtof(x), y 915 case complexVal: 916 return vtoc(x), y 917 } 918 919 case floatVal: 920 switch y := y.(type) { 921 case floatVal: 922 return x, y 923 case complexVal: 924 return vtoc(x), y 925 } 926 } 927 928 // force unknown and invalid values into "x position" in callers of match 929 // (don't panic here so that callers can provide a better error message) 930 return x, x 931 } 932 933 // BinaryOp returns the result of the binary expression x op y. 934 // The operation must be defined for the operands. If one of the 935 // operands is Unknown, the result is Unknown. 936 // BinaryOp doesn't handle comparisons or shifts; use Compare 937 // or Shift instead. 938 // 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(fmt.Sprintf("invalid comparison %v %s 0", x, op)) 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 }