github.com/remobjects/goldbaselibrary@v0.0.0-20230924164425-d458680a936b/Source/Gold/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 14 15 import ( 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. 27 type Kind int 28 29 const ( 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. 44 type 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. 67 const prec = 512 68 69 type ( 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 85 func (unknownVal) Kind() Kind { return Unknown } 86 func (boolVal) Kind() Kind { return Bool } 87 func (*stringVal) Kind() Kind { return String } 88 func (int64Val) Kind() Kind { return Int } 89 func (intVal) Kind() Kind { return Int } 90 func (ratVal) Kind() Kind { return Float } 91 func (floatVal) Kind() Kind { return Float } 92 func (complexVal) Kind() Kind { return Complex } 93 94 func (unknownVal) String() string { return "unknown" } 95 func (x boolVal) String() string { return strconv.FormatBool(bool(x)) } 96 97 // String returns a possibly shortened quoted form of the String value. 98 func (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. 120 func (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. 134 func 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. 148 func (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 169 func (x int64Val) String() string { return strconv.FormatInt(int64(x), 10) } 170 func (x intVal) String() string { return x.val.String() } 171 func (x ratVal) String() string { return rtof(x).String() } 172 173 // String returns a decimal approximation of the Float value. 174 func (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 220 func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) } 221 222 func (x unknownVal) ExactString() string { return x.String() } 223 func (x boolVal) ExactString() string { return x.String() } 224 func (x *stringVal) ExactString() string { return strconv.Quote(x.string()) } 225 func (x int64Val) ExactString() string { return x.String() } 226 func (x intVal) ExactString() string { return x.String() } 227 228 func (x ratVal) ExactString() string { 229 r := x.val 230 if r.IsInt() { 231 return r.Num().String() 232 } 233 return r.String() 234 } 235 236 func (x floatVal) ExactString() string { return x.val.Text('p', 0) } 237 238 func (x complexVal) ExactString() string { 239 return fmt.Sprintf("(%s + %si)", x.re.ExactString(), x.im.ExactString()) 240 } 241 242 func (unknownVal) implementsValue() {} 243 func (boolVal) implementsValue() {} 244 func (*stringVal) implementsValue() {} 245 func (int64Val) implementsValue() {} 246 func (ratVal) implementsValue() {} 247 func (intVal) implementsValue() {} 248 func (floatVal) implementsValue() {} 249 func (complexVal) implementsValue() {} 250 251 func newInt() *big.Int { return new(big.Int) } 252 func newRat() *big.Rat { return new(big.Rat) } 253 func newFloat() *big.Float { return new(big.Float).SetPrec(prec) } 254 255 func i64toi(x int64Val) intVal { return intVal{newInt().SetInt64(int64(x))} } 256 func i64tor(x int64Val) ratVal { return ratVal{newRat().SetInt64(int64(x))} } 257 func i64tof(x int64Val) floatVal { return floatVal{newFloat().SetInt64(int64(x))} } 258 func itor(x intVal) ratVal { return ratVal{newRat().SetInt(x.val)} } 259 func itof(x intVal) floatVal { return floatVal{newFloat().SetInt(x.val)} } 260 261 func 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 267 func vtoc(x Value) complexVal { return complexVal{x, int64Val(0)} } 268 269 func 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. 278 const maxExp = 4 << 10 279 280 func 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 293 var floatVal0 = floatVal{newFloat()} 294 295 func makeFloat(x *big.Float) Value { 296 // convert -0 297 if x.Sign() == 0 { 298 return floatVal0 299 } 300 return floatVal{x} 301 } 302 303 func makeComplex(re, im Value) Value { 304 return complexVal{re, im} 305 } 306 307 func 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. 330 func 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. 342 func MakeUnknown() Value { return unknownVal{} } 343 344 // MakeBool returns the Bool value for b. 345 func MakeBool(b bool) Value { return boolVal(b) } 346 347 // MakeString returns the String value for s. 348 func MakeString(s string) Value { return &stringVal{s: s} } 349 350 // MakeInt64 returns the Int value for x. 351 func MakeInt64(x int64) Value { return int64Val(x) } 352 353 // MakeUint64 returns the Int value for x. 354 func 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. 363 func 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. 379 func 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 435 func 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. 463 func 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 "". 476 func 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). 490 func 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). 506 func 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. 520 func 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). 545 func 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 // 577 func 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 // 608 func 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. 630 func 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. 646 func 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 674 const ( 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. 683 func 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. 715 func 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. 747 func Num(x Value) Value { 748 switch x := x.(type) { 749 case int64Val, intVal: 750 // ElementsChange!!! 751 //return x 752 return Value(x) 753 case ratVal: 754 return makeInt(x.val.Num()) 755 case floatVal: 756 if smallRat(x.val) { 757 r, _ := x.val.Rat(nil) 758 return makeInt(r.Num()) 759 } 760 case unknownVal: 761 break 762 default: 763 panic(fmt.Sprintf("%v not Int or Float", x)) 764 } 765 return unknownVal{} 766 } 767 768 // Denom returns the denominator of x; x must be Int, Float, or Unknown. 769 // If x is Unknown, or if it is too large or small to represent as a 770 // fraction, the result is Unknown. Otherwise the result is an Int >= 1. 771 func Denom(x Value) Value { 772 switch x := x.(type) { 773 case int64Val, intVal: 774 return int64Val(1) 775 case ratVal: 776 return makeInt(x.val.Denom()) 777 case floatVal: 778 if smallRat(x.val) { 779 r, _ := x.val.Rat(nil) 780 return makeInt(r.Denom()) 781 } 782 case unknownVal: 783 break 784 default: 785 panic(fmt.Sprintf("%v not Int or Float", x)) 786 } 787 return unknownVal{} 788 } 789 790 // MakeImag returns the Complex value x*i; 791 // x must be Int, Float, or Unknown. 792 // If x is Unknown, the result is Unknown. 793 func MakeImag(x Value) Value { 794 switch x.(type) { 795 case unknownVal: 796 return x 797 case int64Val, intVal, ratVal, floatVal: 798 return makeComplex(int64Val(0), x) 799 default: 800 panic(fmt.Sprintf("%v not Int or Float", x)) 801 } 802 } 803 804 // Real returns the real part of x, which must be a numeric or unknown value. 805 // If x is Unknown, the result is Unknown. 806 func Real(x Value) Value { 807 switch x := x.(type) { 808 case unknownVal, int64Val, intVal, ratVal, floatVal: 809 // ElementsChange!!! 810 //return x 811 return Value(x) 812 case complexVal: 813 return x.re 814 default: 815 panic(fmt.Sprintf("%v not numeric", x)) 816 } 817 } 818 819 // Imag returns the imaginary part of x, which must be a numeric or unknown value. 820 // If x is Unknown, the result is Unknown. 821 func Imag(x Value) Value { 822 switch x := x.(type) { 823 case unknownVal: 824 return x 825 case int64Val, intVal, ratVal, floatVal: 826 return int64Val(0) 827 case complexVal: 828 return x.im 829 default: 830 panic(fmt.Sprintf("%v not numeric", x)) 831 } 832 } 833 834 // ---------------------------------------------------------------------------- 835 // Numeric conversions 836 837 // ToInt converts x to an Int value if x is representable as an Int. 838 // Otherwise it returns an Unknown. 839 func ToInt(x Value) Value { 840 switch x := x.(type) { 841 case int64Val, intVal: 842 // ElementsChange!!! 843 //return x 844 return Value(x) 845 846 case ratVal: 847 if x.val.IsInt() { 848 return makeInt(x.val.Num()) 849 } 850 851 case floatVal: 852 // avoid creation of huge integers 853 // (Existing tests require permitting exponents of at least 1024; 854 // allow any value that would also be permissible as a fraction.) 855 if smallRat(x.val) { 856 i := newInt() 857 if _, acc := x.val.Int(i); acc == big.Exact { 858 return makeInt(i) 859 } 860 861 // If we can get an integer by rounding up or down, 862 // assume x is not an integer because of rounding 863 // errors in prior computations. 864 865 const delta = 4 // a small number of bits > 0 866 var t big.Float 867 t.SetPrec(prec - delta) 868 869 // try rounding down a little 870 t.SetMode(big.ToZero) 871 t.Set(x.val) 872 if _, acc := t.Int(i); acc == big.Exact { 873 return makeInt(i) 874 } 875 876 // try rounding up a little 877 t.SetMode(big.AwayFromZero) 878 t.Set(x.val) 879 if _, acc := t.Int(i); acc == big.Exact { 880 return makeInt(i) 881 } 882 } 883 884 case complexVal: 885 if re := ToFloat(x); re.Kind() == Float { 886 return ToInt(re) 887 } 888 } 889 890 return unknownVal{} 891 } 892 893 // ToFloat converts x to a Float value if x is representable as a Float. 894 // Otherwise it returns an Unknown. 895 func ToFloat(x Value) Value { 896 switch x := x.(type) { 897 case int64Val: 898 return i64tof(x) 899 case intVal: 900 return itof(x) 901 case ratVal, floatVal: 902 // ElementsChange!!! 903 //return x 904 return Value(x) 905 case complexVal: 906 if im := ToInt(x.im); im.Kind() == Int && Sign(im) == 0 { 907 // imaginary component is 0 908 return ToFloat(x.re) 909 } 910 } 911 return unknownVal{} 912 } 913 914 // ToComplex converts x to a Complex value if x is representable as a Complex. 915 // Otherwise it returns an Unknown. 916 func ToComplex(x Value) Value { 917 switch x := x.(type) { 918 case int64Val: 919 return vtoc(i64tof(x)) 920 case intVal: 921 return vtoc(itof(x)) 922 case ratVal: 923 return vtoc(x) 924 case floatVal: 925 return vtoc(x) 926 case complexVal: 927 return x 928 } 929 return unknownVal{} 930 } 931 932 // ---------------------------------------------------------------------------- 933 // Operations 934 935 // is32bit reports whether x can be represented using 32 bits. 936 func is32bit(x int64) bool { 937 const s = 32 938 return -1<<(s-1) <= x && x <= 1<<(s-1)-1 939 } 940 941 // is63bit reports whether x can be represented using 63 bits. 942 func is63bit(x int64) bool { 943 const s = 63 944 return -1<<(s-1) <= x && x <= 1<<(s-1)-1 945 } 946 947 // UnaryOp returns the result of the unary expression op y. 948 // The operation must be defined for the operand. 949 // If prec > 0 it specifies the ^ (xor) result size in bits. 950 // If y is Unknown, the result is Unknown. 951 // 952 func UnaryOp(op token.Token, y Value, prec uint) Value { 953 switch op { 954 case token.ADD: 955 switch y.(type) { 956 case unknownVal, int64Val, intVal, ratVal, floatVal, complexVal: 957 return y 958 } 959 960 case token.SUB: 961 switch y := y.(type) { 962 case unknownVal: 963 return y 964 case int64Val: 965 if z := -y; z != y { 966 return z // no overflow 967 } 968 return makeInt(newInt().Neg(big.NewInt(int64(y)))) 969 case intVal: 970 return makeInt(newInt().Neg(y.val)) 971 case ratVal: 972 return makeRat(newRat().Neg(y.val)) 973 case floatVal: 974 return makeFloat(newFloat().Neg(y.val)) 975 case complexVal: 976 re := UnaryOp(token.SUB, y.re, 0) 977 im := UnaryOp(token.SUB, y.im, 0) 978 return makeComplex(re, im) 979 } 980 981 case token.XOR: 982 z := newInt() 983 switch y := y.(type) { 984 case unknownVal: 985 return y 986 case int64Val: 987 z.Not(big.NewInt(int64(y))) 988 case intVal: 989 z.Not(y.val) 990 default: 991 goto Error 992 } 993 // For unsigned types, the result will be negative and 994 // thus "too large": We must limit the result precision 995 // to the type's precision. 996 if prec > 0 { 997 z.AndNot(z, newInt().Lsh(big.NewInt(-1), prec)) // z &^= (-1)<<prec 998 } 999 return makeInt(z) 1000 1001 case token.NOT: 1002 switch y := y.(type) { 1003 case unknownVal: 1004 return y 1005 case boolVal: 1006 // ElementsChange!!! 1007 //return !y 1008 return Value(!y) 1009 } 1010 } 1011 1012 Error: 1013 panic(fmt.Sprintf("invalid unary operation %s%v", op, y)) 1014 } 1015 1016 func ord(x Value) int { 1017 switch x.(type) { 1018 default: 1019 // force invalid value into "x position" in match 1020 // (don't panic here so that callers can provide a better error message) 1021 return -1 1022 case unknownVal: 1023 return 0 1024 case boolVal, *stringVal: 1025 return 1 1026 case int64Val: 1027 return 2 1028 case intVal: 1029 return 3 1030 case ratVal: 1031 return 4 1032 case floatVal: 1033 return 5 1034 case complexVal: 1035 return 6 1036 } 1037 } 1038 1039 // match returns the matching representation (same type) with the 1040 // smallest complexity for two values x and y. If one of them is 1041 // numeric, both of them must be numeric. If one of them is Unknown 1042 // or invalid (say, nil) both results are that value. 1043 // 1044 func match(x, y Value) (_, _ Value) { 1045 if ord(x) > ord(y) { 1046 y, x = match(y, x) 1047 return x, y 1048 } 1049 // ord(x) <= ord(y) 1050 1051 switch x := x.(type) { 1052 case boolVal, *stringVal, complexVal: 1053 // ElementsChange!!! 1054 //return x, y 1055 return Value(x), y 1056 1057 case int64Val: 1058 switch y := y.(type) { 1059 case int64Val: 1060 return x, y 1061 case intVal: 1062 return i64toi(x), y 1063 case ratVal: 1064 return i64tor(x), y 1065 case floatVal: 1066 return i64tof(x), y 1067 case complexVal: 1068 return vtoc(x), y 1069 } 1070 1071 case intVal: 1072 switch y := y.(type) { 1073 case intVal: 1074 return x, y 1075 case ratVal: 1076 return itor(x), y 1077 case floatVal: 1078 return itof(x), y 1079 case complexVal: 1080 return vtoc(x), y 1081 } 1082 1083 case ratVal: 1084 switch y := y.(type) { 1085 case ratVal: 1086 return x, y 1087 case floatVal: 1088 return rtof(x), y 1089 case complexVal: 1090 return vtoc(x), y 1091 } 1092 1093 case floatVal: 1094 switch y := y.(type) { 1095 case floatVal: 1096 return x, y 1097 case complexVal: 1098 return vtoc(x), y 1099 } 1100 } 1101 1102 // force unknown and invalid values into "x position" in callers of match 1103 // (don't panic here so that callers can provide a better error message) 1104 return x, x 1105 } 1106 1107 // BinaryOp returns the result of the binary expression x op y. 1108 // The operation must be defined for the operands. If one of the 1109 // operands is Unknown, the result is Unknown. 1110 // BinaryOp doesn't handle comparisons or shifts; use Compare 1111 // or Shift instead. 1112 // 1113 // To force integer division of Int operands, use op == token.QUO_ASSIGN 1114 // instead of token.QUO; the result is guaranteed to be Int in this case. 1115 // Division by zero leads to a run-time panic. 1116 // 1117 func BinaryOp(x_ Value, op token.Token, y_ Value) Value { 1118 x, y := match(x_, y_) 1119 1120 switch x := x.(type) { 1121 case unknownVal: 1122 return x 1123 1124 case boolVal: 1125 y := y.(boolVal) 1126 switch op { 1127 case token.LAND: 1128 return x && y 1129 case token.LOR: 1130 return x || y 1131 } 1132 1133 case int64Val: 1134 a := int64(x) 1135 b := int64(y.(int64Val)) 1136 var c int64 1137 switch op { 1138 case token.ADD: 1139 if !is63bit(a) || !is63bit(b) { 1140 return makeInt(newInt().Add(big.NewInt(a), big.NewInt(b))) 1141 } 1142 c = a + b 1143 case token.SUB: 1144 if !is63bit(a) || !is63bit(b) { 1145 return makeInt(newInt().Sub(big.NewInt(a), big.NewInt(b))) 1146 } 1147 c = a - b 1148 case token.MUL: 1149 if !is32bit(a) || !is32bit(b) { 1150 return makeInt(newInt().Mul(big.NewInt(a), big.NewInt(b))) 1151 } 1152 c = a * b 1153 case token.QUO: 1154 return makeRat(big.NewRat(a, b)) 1155 case token.QUO_ASSIGN: // force integer division 1156 c = a / b 1157 case token.REM: 1158 c = a % b 1159 case token.AND: 1160 c = a & b 1161 case token.OR: 1162 c = a | b 1163 case token.XOR: 1164 c = a ^ b 1165 case token.AND_NOT: 1166 c = a &^ b 1167 default: 1168 goto Error 1169 } 1170 return int64Val(c) 1171 1172 case intVal: 1173 a := x.val 1174 b := y.(intVal).val 1175 c := newInt() 1176 switch op { 1177 case token.ADD: 1178 c.Add(a, b) 1179 case token.SUB: 1180 c.Sub(a, b) 1181 case token.MUL: 1182 c.Mul(a, b) 1183 case token.QUO: 1184 return makeRat(newRat().SetFrac(a, b)) 1185 case token.QUO_ASSIGN: // force integer division 1186 c.Quo(a, b) 1187 case token.REM: 1188 c.Rem(a, b) 1189 case token.AND: 1190 c.And(a, b) 1191 case token.OR: 1192 c.Or(a, b) 1193 case token.XOR: 1194 c.Xor(a, b) 1195 case token.AND_NOT: 1196 c.AndNot(a, b) 1197 default: 1198 goto Error 1199 } 1200 return makeInt(c) 1201 1202 case ratVal: 1203 a := x.val 1204 b := y.(ratVal).val 1205 c := newRat() 1206 switch op { 1207 case token.ADD: 1208 c.Add(a, b) 1209 case token.SUB: 1210 c.Sub(a, b) 1211 case token.MUL: 1212 c.Mul(a, b) 1213 case token.QUO: 1214 c.Quo(a, b) 1215 default: 1216 goto Error 1217 } 1218 return makeRat(c) 1219 1220 case floatVal: 1221 a := x.val 1222 b := y.(floatVal).val 1223 c := newFloat() 1224 switch op { 1225 case token.ADD: 1226 c.Add(a, b) 1227 case token.SUB: 1228 c.Sub(a, b) 1229 case token.MUL: 1230 c.Mul(a, b) 1231 case token.QUO: 1232 c.Quo(a, b) 1233 default: 1234 goto Error 1235 } 1236 return makeFloat(c) 1237 1238 case complexVal: 1239 y := y.(complexVal) 1240 a, b := x.re, x.im 1241 c, d := y.re, y.im 1242 var re, im Value 1243 switch op { 1244 case token.ADD: 1245 // (a+c) + i(b+d) 1246 re = add(a, c) 1247 im = add(b, d) 1248 case token.SUB: 1249 // (a-c) + i(b-d) 1250 re = sub(a, c) 1251 im = sub(b, d) 1252 case token.MUL: 1253 // (ac-bd) + i(bc+ad) 1254 ac := mul(a, c) 1255 bd := mul(b, d) 1256 bc := mul(b, c) 1257 ad := mul(a, d) 1258 re = sub(ac, bd) 1259 im = add(bc, ad) 1260 case token.QUO: 1261 // (ac+bd)/s + i(bc-ad)/s, with s = cc + dd 1262 ac := mul(a, c) 1263 bd := mul(b, d) 1264 bc := mul(b, c) 1265 ad := mul(a, d) 1266 cc := mul(c, c) 1267 dd := mul(d, d) 1268 s := add(cc, dd) 1269 re = add(ac, bd) 1270 re = quo(re, s) 1271 im = sub(bc, ad) 1272 im = quo(im, s) 1273 default: 1274 goto Error 1275 } 1276 return makeComplex(re, im) 1277 1278 case *stringVal: 1279 if op == token.ADD { 1280 return &stringVal{l: x, r: y.(*stringVal)} 1281 } 1282 } 1283 1284 Error: 1285 panic(fmt.Sprintf("invalid binary operation %v %s %v", x_, op, y_)) 1286 } 1287 1288 func add(x, y Value) Value { return BinaryOp(x, token.ADD, y) } 1289 func sub(x, y Value) Value { return BinaryOp(x, token.SUB, y) } 1290 func mul(x, y Value) Value { return BinaryOp(x, token.MUL, y) } 1291 func quo(x, y Value) Value { return BinaryOp(x, token.QUO, y) } 1292 1293 // Shift returns the result of the shift expression x op s 1294 // with op == token.SHL or token.SHR (<< or >>). x must be 1295 // an Int or an Unknown. If x is Unknown, the result is x. 1296 // 1297 func Shift(x Value, op token.Token, s uint) Value { 1298 switch x := x.(type) { 1299 case unknownVal: 1300 return x 1301 1302 case int64Val: 1303 if s == 0 { 1304 return x 1305 } 1306 switch op { 1307 case token.SHL: 1308 z := i64toi(x).val 1309 return makeInt(z.Lsh(z, s)) 1310 case token.SHR: 1311 // ElementsChange!!! 1312 //return x >> s 1313 return Value(x >> s) 1314 } 1315 1316 case intVal: 1317 if s == 0 { 1318 return x 1319 } 1320 z := newInt() 1321 switch op { 1322 case token.SHL: 1323 return makeInt(z.Lsh(x.val, s)) 1324 case token.SHR: 1325 return makeInt(z.Rsh(x.val, s)) 1326 } 1327 } 1328 1329 panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s)) 1330 } 1331 1332 func cmpZero(x int, op token.Token) bool { 1333 switch op { 1334 case token.EQL: 1335 return x == 0 1336 case token.NEQ: 1337 return x != 0 1338 case token.LSS: 1339 return x < 0 1340 case token.LEQ: 1341 return x <= 0 1342 case token.GTR: 1343 return x > 0 1344 case token.GEQ: 1345 return x >= 0 1346 } 1347 panic(fmt.Sprintf("invalid comparison %v %s 0", x, op)) 1348 } 1349 1350 // Compare returns the result of the comparison x op y. 1351 // The comparison must be defined for the operands. 1352 // If one of the operands is Unknown, the result is 1353 // false. 1354 // 1355 func Compare(x_ Value, op token.Token, y_ Value) bool { 1356 x, y := match(x_, y_) 1357 1358 switch x := x.(type) { 1359 case unknownVal: 1360 return false 1361 1362 case boolVal: 1363 y := y.(boolVal) 1364 switch op { 1365 case token.EQL: 1366 return x == y 1367 case token.NEQ: 1368 return x != y 1369 } 1370 1371 case int64Val: 1372 y := y.(int64Val) 1373 switch op { 1374 case token.EQL: 1375 return x == y 1376 case token.NEQ: 1377 return x != y 1378 case token.LSS: 1379 return x < y 1380 case token.LEQ: 1381 return x <= y 1382 case token.GTR: 1383 return x > y 1384 case token.GEQ: 1385 return x >= y 1386 } 1387 1388 case intVal: 1389 return cmpZero(x.val.Cmp(y.(intVal).val), op) 1390 1391 case ratVal: 1392 return cmpZero(x.val.Cmp(y.(ratVal).val), op) 1393 1394 case floatVal: 1395 return cmpZero(x.val.Cmp(y.(floatVal).val), op) 1396 1397 case complexVal: 1398 y := y.(complexVal) 1399 re := Compare(x.re, token.EQL, y.re) 1400 im := Compare(x.im, token.EQL, y.im) 1401 switch op { 1402 case token.EQL: 1403 return re && im 1404 case token.NEQ: 1405 return !re || !im 1406 } 1407 1408 case *stringVal: 1409 xs := x.string() 1410 ys := y.(*stringVal).string() 1411 switch op { 1412 case token.EQL: 1413 return xs == ys 1414 case token.NEQ: 1415 return xs != ys 1416 case token.LSS: 1417 return xs < ys 1418 case token.LEQ: 1419 return xs <= ys 1420 case token.GTR: 1421 return xs > ys 1422 case token.GEQ: 1423 return xs >= ys 1424 } 1425 } 1426 1427 panic(fmt.Sprintf("invalid comparison %v %s %v", x_, op, y_)) 1428 }