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