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