1
2
3
4
5
6
7
8
9
10
11
12 package constant
13
14 import (
15 "fmt"
16 "go/token"
17 "math"
18 "math/big"
19 "math/bits"
20 "strconv"
21 "strings"
22 "sync"
23 "unicode/utf8"
24 )
25
26
27
28
29 type Kind int
30
31 const (
32
33 Unknown Kind = iota
34
35
36 Bool
37 String
38
39
40 Int
41 Float
42 Complex
43 )
44
45
46 type Value interface {
47
48 Kind() Kind
49
50
51
52
53
54 String() string
55
56
57
58 ExactString() string
59
60
61 implementsValue()
62 }
63
64
65
66
67
68
69 const prec = 512
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 type (
88 unknownVal struct{}
89 boolVal bool
90 stringVal struct {
91
92 mu sync.Mutex
93 s string
94 l, r *stringVal
95 }
96 int64Val int64
97 intVal struct{ val *big.Int }
98 ratVal struct{ val *big.Rat }
99 floatVal struct{ val *big.Float }
100 complexVal struct{ re, im Value }
101 )
102
103 func (unknownVal) Kind() Kind { return Unknown }
104 func (boolVal) Kind() Kind { return Bool }
105 func (*stringVal) Kind() Kind { return String }
106 func (int64Val) Kind() Kind { return Int }
107 func (intVal) Kind() Kind { return Int }
108 func (ratVal) Kind() Kind { return Float }
109 func (floatVal) Kind() Kind { return Float }
110 func (complexVal) Kind() Kind { return Complex }
111
112 func (unknownVal) String() string { return "unknown" }
113 func (x boolVal) String() string { return strconv.FormatBool(bool(x)) }
114
115
116 func (x *stringVal) String() string {
117 const maxLen = 72
118 s := strconv.Quote(x.string())
119 if utf8.RuneCountInString(s) > maxLen {
120
121
122
123 i := 0
124 for n := 0; n < maxLen-3; n++ {
125 _, size := utf8.DecodeRuneInString(s[i:])
126 i += size
127 }
128 s = s[:i] + "..."
129 }
130 return s
131 }
132
133
134
135
136
137
138 func (x *stringVal) string() string {
139 x.mu.Lock()
140 if x.l != nil {
141 x.s = strings.Join(reverse(x.appendReverse(nil)), "")
142 x.l = nil
143 x.r = nil
144 }
145 s := x.s
146 x.mu.Unlock()
147
148 return s
149 }
150
151
152 func reverse(x []string) []string {
153 n := len(x)
154 for i := 0; i+i < n; i++ {
155 x[i], x[n-1-i] = x[n-1-i], x[i]
156 }
157 return x
158 }
159
160
161
162
163
164
165
166 func (x *stringVal) appendReverse(list []string) []string {
167 y := x
168 for y.r != nil {
169 y.r.mu.Lock()
170 list = y.r.appendReverse(list)
171 y.r.mu.Unlock()
172
173 l := y.l
174 if y != x {
175 y.mu.Unlock()
176 }
177 l.mu.Lock()
178 y = l
179 }
180 s := y.s
181 if y != x {
182 y.mu.Unlock()
183 }
184 return append(list, s)
185 }
186
187 func (x int64Val) String() string { return strconv.FormatInt(int64(x), 10) }
188 func (x intVal) String() string { return x.val.String() }
189 func (x ratVal) String() string { return rtof(x).String() }
190
191
192 func (x floatVal) String() string {
193 f := x.val
194
195
196 if f.IsInf() {
197 return f.String()
198 }
199
200
201
202 if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
203 s := fmt.Sprintf("%.6g", x)
204 if !f.IsInt() && strings.IndexByte(s, '.') < 0 {
205
206
207 s = fmt.Sprintf("%g", x)
208 }
209 return s
210 }
211
212
213
214
215
216 var mant big.Float
217 exp := f.MantExp(&mant)
218
219
220
221 m, _ := mant.Float64()
222 d := float64(exp) * (math.Ln2 / math.Ln10)
223
224
225 e := int64(d)
226 m *= math.Pow(10, d-float64(e))
227
228
229 switch am := math.Abs(m); {
230 case am < 1-0.5e-6:
231
232
233
234 m *= 10
235 e--
236 case am >= 10:
237 m /= 10
238 e++
239 }
240
241 return fmt.Sprintf("%.6ge%+d", m, e)
242 }
243
244 func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
245
246 func (x unknownVal) ExactString() string { return x.String() }
247 func (x boolVal) ExactString() string { return x.String() }
248 func (x *stringVal) ExactString() string { return strconv.Quote(x.string()) }
249 func (x int64Val) ExactString() string { return x.String() }
250 func (x intVal) ExactString() string { return x.String() }
251
252 func (x ratVal) ExactString() string {
253 r := x.val
254 if r.IsInt() {
255 return r.Num().String()
256 }
257 return r.String()
258 }
259
260 func (x floatVal) ExactString() string { return x.val.Text('p', 0) }
261
262 func (x complexVal) ExactString() string {
263 return fmt.Sprintf("(%s + %si)", x.re.ExactString(), x.im.ExactString())
264 }
265
266 func (unknownVal) implementsValue() {}
267 func (boolVal) implementsValue() {}
268 func (*stringVal) implementsValue() {}
269 func (int64Val) implementsValue() {}
270 func (ratVal) implementsValue() {}
271 func (intVal) implementsValue() {}
272 func (floatVal) implementsValue() {}
273 func (complexVal) implementsValue() {}
274
275 func newInt() *big.Int { return new(big.Int) }
276 func newRat() *big.Rat { return new(big.Rat) }
277 func newFloat() *big.Float { return new(big.Float).SetPrec(prec) }
278
279 func i64toi(x int64Val) intVal { return intVal{newInt().SetInt64(int64(x))} }
280 func i64tor(x int64Val) ratVal { return ratVal{newRat().SetInt64(int64(x))} }
281 func i64tof(x int64Val) floatVal { return floatVal{newFloat().SetInt64(int64(x))} }
282 func itor(x intVal) ratVal { return ratVal{newRat().SetInt(x.val)} }
283 func itof(x intVal) floatVal { return floatVal{newFloat().SetInt(x.val)} }
284 func rtof(x ratVal) floatVal { return floatVal{newFloat().SetRat(x.val)} }
285 func vtoc(x Value) complexVal { return complexVal{x, int64Val(0)} }
286
287 func makeInt(x *big.Int) Value {
288 if x.IsInt64() {
289 return int64Val(x.Int64())
290 }
291 return intVal{x}
292 }
293
294 func makeRat(x *big.Rat) Value {
295 a := x.Num()
296 b := x.Denom()
297 if smallInt(a) && smallInt(b) {
298
299 return ratVal{x}
300 }
301
302 return floatVal{newFloat().SetRat(x)}
303 }
304
305 var floatVal0 = floatVal{newFloat()}
306
307 func makeFloat(x *big.Float) Value {
308
309 if x.Sign() == 0 {
310 return floatVal0
311 }
312 if x.IsInf() {
313 return unknownVal{}
314 }
315
316
317
318 return floatVal{x}
319 }
320
321 func makeComplex(re, im Value) Value {
322 if re.Kind() == Unknown || im.Kind() == Unknown {
323 return unknownVal{}
324 }
325 return complexVal{re, im}
326 }
327
328 func makeFloatFromLiteral(lit string) Value {
329 if f, ok := newFloat().SetString(lit); ok {
330 if smallFloat(f) {
331
332 if f.Sign() == 0 {
333
334
335
336
337 lit = "0"
338 }
339 if r, ok := newRat().SetString(lit); ok {
340 return ratVal{r}
341 }
342 }
343
344 return makeFloat(f)
345 }
346 return nil
347 }
348
349
350
351 const maxExp = 4 << 10
352
353
354
355 func smallInt(x *big.Int) bool {
356 return x.BitLen() < maxExp
357 }
358
359
360
361 func smallFloat64(x float64) bool {
362 if math.IsInf(x, 0) {
363 return false
364 }
365 _, e := math.Frexp(x)
366 return -maxExp < e && e < maxExp
367 }
368
369
370
371 func smallFloat(x *big.Float) bool {
372 if x.IsInf() {
373 return false
374 }
375 e := x.MantExp(nil)
376 return -maxExp < e && e < maxExp
377 }
378
379
380
381
382
383 func MakeUnknown() Value { return unknownVal{} }
384
385
386 func MakeBool(b bool) Value { return boolVal(b) }
387
388
389 func MakeString(s string) Value {
390 if s == "" {
391 return &emptyString
392 }
393 return &stringVal{s: s}
394 }
395
396 var emptyString stringVal
397
398
399 func MakeInt64(x int64) Value { return int64Val(x) }
400
401
402 func MakeUint64(x uint64) Value {
403 if x < 1<<63 {
404 return int64Val(int64(x))
405 }
406 return intVal{newInt().SetUint64(x)}
407 }
408
409
410
411
412 func MakeFloat64(x float64) Value {
413 if math.IsInf(x, 0) || math.IsNaN(x) {
414 return unknownVal{}
415 }
416 if smallFloat64(x) {
417 return ratVal{newRat().SetFloat64(x + 0)}
418 }
419 return floatVal{newFloat().SetFloat64(x + 0)}
420 }
421
422
423
424
425
426
427 func MakeFromLiteral(lit string, tok token.Token, zero uint) Value {
428 if zero != 0 {
429 panic("MakeFromLiteral called with non-zero last argument")
430 }
431
432 switch tok {
433 case token.INT:
434 if x, err := strconv.ParseInt(lit, 0, 64); err == nil {
435 return int64Val(x)
436 }
437 if x, ok := newInt().SetString(lit, 0); ok {
438 return intVal{x}
439 }
440
441 case token.FLOAT:
442 if x := makeFloatFromLiteral(lit); x != nil {
443 return x
444 }
445
446 case token.IMAG:
447 if n := len(lit); n > 0 && lit[n-1] == 'i' {
448 if im := makeFloatFromLiteral(lit[:n-1]); im != nil {
449 return makeComplex(int64Val(0), im)
450 }
451 }
452
453 case token.CHAR:
454 if n := len(lit); n >= 2 {
455 if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil {
456 return MakeInt64(int64(code))
457 }
458 }
459
460 case token.STRING:
461 if s, err := strconv.Unquote(lit); err == nil {
462 return MakeString(s)
463 }
464
465 default:
466 panic(fmt.Sprintf("%v is not a valid token", tok))
467 }
468
469 return unknownVal{}
470 }
471
472
473
474
475
476
477
478
479
480 func BoolVal(x Value) bool {
481 switch x := x.(type) {
482 case boolVal:
483 return bool(x)
484 case unknownVal:
485 return false
486 default:
487 panic(fmt.Sprintf("%v not a Bool", x))
488 }
489 }
490
491
492
493 func StringVal(x Value) string {
494 switch x := x.(type) {
495 case *stringVal:
496 return x.string()
497 case unknownVal:
498 return ""
499 default:
500 panic(fmt.Sprintf("%v not a String", x))
501 }
502 }
503
504
505
506
507 func Int64Val(x Value) (int64, bool) {
508 switch x := x.(type) {
509 case int64Val:
510 return int64(x), true
511 case intVal:
512 return x.val.Int64(), false
513 case unknownVal:
514 return 0, false
515 default:
516 panic(fmt.Sprintf("%v not an Int", x))
517 }
518 }
519
520
521
522
523 func Uint64Val(x Value) (uint64, bool) {
524 switch x := x.(type) {
525 case int64Val:
526 return uint64(x), x >= 0
527 case intVal:
528 return x.val.Uint64(), x.val.IsUint64()
529 case unknownVal:
530 return 0, false
531 default:
532 panic(fmt.Sprintf("%v not an Int", x))
533 }
534 }
535
536
537 func Float32Val(x Value) (float32, bool) {
538 switch x := x.(type) {
539 case int64Val:
540 f := float32(x)
541 return f, int64Val(f) == x
542 case intVal:
543 f, acc := newFloat().SetInt(x.val).Float32()
544 return f, acc == big.Exact
545 case ratVal:
546 return x.val.Float32()
547 case floatVal:
548 f, acc := x.val.Float32()
549 return f, acc == big.Exact
550 case unknownVal:
551 return 0, false
552 default:
553 panic(fmt.Sprintf("%v not a Float", x))
554 }
555 }
556
557
558
559
560
561
562 func Float64Val(x Value) (float64, bool) {
563 switch x := x.(type) {
564 case int64Val:
565 f := float64(int64(x))
566 return f, int64Val(f) == x
567 case intVal:
568 f, acc := newFloat().SetInt(x.val).Float64()
569 return f, acc == big.Exact
570 case ratVal:
571 return x.val.Float64()
572 case floatVal:
573 f, acc := x.val.Float64()
574 return f, acc == big.Exact
575 case unknownVal:
576 return 0, false
577 default:
578 panic(fmt.Sprintf("%v not a Float", x))
579 }
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593 func Val(x Value) any {
594 switch x := x.(type) {
595 case boolVal:
596 return bool(x)
597 case *stringVal:
598 return x.string()
599 case int64Val:
600 return int64(x)
601 case intVal:
602 return x.val
603 case ratVal:
604 return x.val
605 case floatVal:
606 return x.val
607 default:
608 return nil
609 }
610 }
611
612
613
614
615
616
617
618
619
620
621
622
623 func Make(x any) Value {
624 switch x := x.(type) {
625 case bool:
626 return boolVal(x)
627 case string:
628 return &stringVal{s: x}
629 case int64:
630 return int64Val(x)
631 case *big.Int:
632 return makeInt(x)
633 case *big.Rat:
634 return makeRat(x)
635 case *big.Float:
636 return makeFloat(x)
637 default:
638 return unknownVal{}
639 }
640 }
641
642
643
644
645 func BitLen(x Value) int {
646 switch x := x.(type) {
647 case int64Val:
648 u := uint64(x)
649 if x < 0 {
650 u = uint64(-x)
651 }
652 return 64 - bits.LeadingZeros64(u)
653 case intVal:
654 return x.val.BitLen()
655 case unknownVal:
656 return 0
657 default:
658 panic(fmt.Sprintf("%v not an Int", x))
659 }
660 }
661
662
663
664
665 func Sign(x Value) int {
666 switch x := x.(type) {
667 case int64Val:
668 switch {
669 case x < 0:
670 return -1
671 case x > 0:
672 return 1
673 }
674 return 0
675 case intVal:
676 return x.val.Sign()
677 case ratVal:
678 return x.val.Sign()
679 case floatVal:
680 return x.val.Sign()
681 case complexVal:
682 return Sign(x.re) | Sign(x.im)
683 case unknownVal:
684 return 1
685 default:
686 panic(fmt.Sprintf("%v not numeric", x))
687 }
688 }
689
690
691
692
693 const (
694
695 _m = ^big.Word(0)
696 _log = _m>>8&1 + _m>>16&1 + _m>>32&1
697 wordSize = 1 << _log
698 )
699
700
701
702 func Bytes(x Value) []byte {
703 var t intVal
704 switch x := x.(type) {
705 case int64Val:
706 t = i64toi(x)
707 case intVal:
708 t = x
709 default:
710 panic(fmt.Sprintf("%v not an Int", x))
711 }
712
713 words := t.val.Bits()
714 bytes := make([]byte, len(words)*wordSize)
715
716 i := 0
717 for _, w := range words {
718 for j := 0; j < wordSize; j++ {
719 bytes[i] = byte(w)
720 w >>= 8
721 i++
722 }
723 }
724
725 for i > 0 && bytes[i-1] == 0 {
726 i--
727 }
728
729 return bytes[:i]
730 }
731
732
733
734 func MakeFromBytes(bytes []byte) Value {
735 words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize)
736
737 i := 0
738 var w big.Word
739 var s uint
740 for _, b := range bytes {
741 w |= big.Word(b) << s
742 if s += 8; s == wordSize*8 {
743 words[i] = w
744 i++
745 w = 0
746 s = 0
747 }
748 }
749
750 if i < len(words) {
751 words[i] = w
752 i++
753 }
754
755 for i > 0 && words[i-1] == 0 {
756 i--
757 }
758
759 return makeInt(newInt().SetBits(words[:i]))
760 }
761
762
763
764
765
766 func Num(x Value) Value {
767 switch x := x.(type) {
768 case int64Val, intVal:
769 return x
770 case ratVal:
771 return makeInt(x.val.Num())
772 case floatVal:
773 if smallFloat(x.val) {
774 r, _ := x.val.Rat(nil)
775 return makeInt(r.Num())
776 }
777 case unknownVal:
778 break
779 default:
780 panic(fmt.Sprintf("%v not Int or Float", x))
781 }
782 return unknownVal{}
783 }
784
785
786
787
788 func Denom(x Value) Value {
789 switch x := x.(type) {
790 case int64Val, intVal:
791 return int64Val(1)
792 case ratVal:
793 return makeInt(x.val.Denom())
794 case floatVal:
795 if smallFloat(x.val) {
796 r, _ := x.val.Rat(nil)
797 return makeInt(r.Denom())
798 }
799 case unknownVal:
800 break
801 default:
802 panic(fmt.Sprintf("%v not Int or Float", x))
803 }
804 return unknownVal{}
805 }
806
807
808
809
810 func MakeImag(x Value) Value {
811 switch x.(type) {
812 case unknownVal:
813 return x
814 case int64Val, intVal, ratVal, floatVal:
815 return makeComplex(int64Val(0), x)
816 default:
817 panic(fmt.Sprintf("%v not Int or Float", x))
818 }
819 }
820
821
822
823 func Real(x Value) Value {
824 switch x := x.(type) {
825 case unknownVal, int64Val, intVal, ratVal, floatVal:
826 return x
827 case complexVal:
828 return x.re
829 default:
830 panic(fmt.Sprintf("%v not numeric", x))
831 }
832 }
833
834
835
836 func Imag(x Value) Value {
837 switch x := x.(type) {
838 case unknownVal:
839 return x
840 case int64Val, intVal, ratVal, floatVal:
841 return int64Val(0)
842 case complexVal:
843 return x.im
844 default:
845 panic(fmt.Sprintf("%v not numeric", x))
846 }
847 }
848
849
850
851
852
853
854 func ToInt(x Value) Value {
855 switch x := x.(type) {
856 case int64Val, intVal:
857 return x
858
859 case ratVal:
860 if x.val.IsInt() {
861 return makeInt(x.val.Num())
862 }
863
864 case floatVal:
865
866
867
868 if smallFloat(x.val) {
869 i := newInt()
870 if _, acc := x.val.Int(i); acc == big.Exact {
871 return makeInt(i)
872 }
873
874
875
876
877
878 const delta = 4
879 var t big.Float
880 t.SetPrec(prec - delta)
881
882
883 t.SetMode(big.ToZero)
884 t.Set(x.val)
885 if _, acc := t.Int(i); acc == big.Exact {
886 return makeInt(i)
887 }
888
889
890 t.SetMode(big.AwayFromZero)
891 t.Set(x.val)
892 if _, acc := t.Int(i); acc == big.Exact {
893 return makeInt(i)
894 }
895 }
896
897 case complexVal:
898 if re := ToFloat(x); re.Kind() == Float {
899 return ToInt(re)
900 }
901 }
902
903 return unknownVal{}
904 }
905
906
907
908 func ToFloat(x Value) Value {
909 switch x := x.(type) {
910 case int64Val:
911 return i64tor(x)
912 case intVal:
913 if smallInt(x.val) {
914 return itor(x)
915 }
916 return itof(x)
917 case ratVal, floatVal:
918 return x
919 case complexVal:
920 if Sign(x.im) == 0 {
921 return ToFloat(x.re)
922 }
923 }
924 return unknownVal{}
925 }
926
927
928
929 func ToComplex(x Value) Value {
930 switch x := x.(type) {
931 case int64Val, intVal, ratVal, floatVal:
932 return vtoc(x)
933 case complexVal:
934 return x
935 }
936 return unknownVal{}
937 }
938
939
940
941
942
943 func is32bit(x int64) bool {
944 const s = 32
945 return -1<<(s-1) <= x && x <= 1<<(s-1)-1
946 }
947
948
949 func is63bit(x int64) bool {
950 const s = 63
951 return -1<<(s-1) <= x && x <= 1<<(s-1)-1
952 }
953
954
955
956
957
958 func UnaryOp(op token.Token, y Value, prec uint) Value {
959 switch op {
960 case token.ADD:
961 switch y.(type) {
962 case unknownVal, int64Val, intVal, ratVal, floatVal, complexVal:
963 return y
964 }
965
966 case token.SUB:
967 switch y := y.(type) {
968 case unknownVal:
969 return y
970 case int64Val:
971 if z := -y; z != y {
972 return z
973 }
974 return makeInt(newInt().Neg(big.NewInt(int64(y))))
975 case intVal:
976 return makeInt(newInt().Neg(y.val))
977 case ratVal:
978 return makeRat(newRat().Neg(y.val))
979 case floatVal:
980 return makeFloat(newFloat().Neg(y.val))
981 case complexVal:
982 re := UnaryOp(token.SUB, y.re, 0)
983 im := UnaryOp(token.SUB, y.im, 0)
984 return makeComplex(re, im)
985 }
986
987 case token.XOR:
988 z := newInt()
989 switch y := y.(type) {
990 case unknownVal:
991 return y
992 case int64Val:
993 z.Not(big.NewInt(int64(y)))
994 case intVal:
995 z.Not(y.val)
996 default:
997 goto Error
998 }
999
1000
1001
1002 if prec > 0 {
1003 z.AndNot(z, newInt().Lsh(big.NewInt(-1), prec))
1004 }
1005 return makeInt(z)
1006
1007 case token.NOT:
1008 switch y := y.(type) {
1009 case unknownVal:
1010 return y
1011 case boolVal:
1012 return !y
1013 }
1014 }
1015
1016 Error:
1017 panic(fmt.Sprintf("invalid unary operation %s%v", op, y))
1018 }
1019
1020 func ord(x Value) int {
1021 switch x.(type) {
1022 default:
1023
1024
1025 return -1
1026 case unknownVal:
1027 return 0
1028 case boolVal, *stringVal:
1029 return 1
1030 case int64Val:
1031 return 2
1032 case intVal:
1033 return 3
1034 case ratVal:
1035 return 4
1036 case floatVal:
1037 return 5
1038 case complexVal:
1039 return 6
1040 }
1041 }
1042
1043
1044
1045
1046
1047 func match(x, y Value) (_, _ Value) {
1048 switch ox, oy := ord(x), ord(y); {
1049 case ox < oy:
1050 x, y = match0(x, y)
1051 case ox > oy:
1052 y, x = match0(y, x)
1053 }
1054 return x, y
1055 }
1056
1057
1058
1059 func match0(x, y Value) (_, _ Value) {
1060
1061
1062
1063 switch y.(type) {
1064 case intVal:
1065 switch x1 := x.(type) {
1066 case int64Val:
1067 return i64toi(x1), y
1068 }
1069 case ratVal:
1070 switch x1 := x.(type) {
1071 case int64Val:
1072 return i64tor(x1), y
1073 case intVal:
1074 return itor(x1), y
1075 }
1076 case floatVal:
1077 switch x1 := x.(type) {
1078 case int64Val:
1079 return i64tof(x1), y
1080 case intVal:
1081 return itof(x1), y
1082 case ratVal:
1083 return rtof(x1), y
1084 }
1085 case complexVal:
1086 switch x1 := x.(type) {
1087 case int64Val, intVal, ratVal, floatVal:
1088 return vtoc(x1), y
1089 }
1090 }
1091
1092
1093
1094 return x, x
1095 }
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106 func BinaryOp(x_ Value, op token.Token, y_ Value) Value {
1107 x, y := match(x_, y_)
1108
1109 switch x := x.(type) {
1110 case unknownVal:
1111 return x
1112
1113 case boolVal:
1114 y := y.(boolVal)
1115 switch op {
1116 case token.LAND:
1117 return x && y
1118 case token.LOR:
1119 return x || y
1120 }
1121
1122 case int64Val:
1123 a := int64(x)
1124 b := int64(y.(int64Val))
1125 var c int64
1126 switch op {
1127 case token.ADD:
1128 if !is63bit(a) || !is63bit(b) {
1129 return makeInt(newInt().Add(big.NewInt(a), big.NewInt(b)))
1130 }
1131 c = a + b
1132 case token.SUB:
1133 if !is63bit(a) || !is63bit(b) {
1134 return makeInt(newInt().Sub(big.NewInt(a), big.NewInt(b)))
1135 }
1136 c = a - b
1137 case token.MUL:
1138 if !is32bit(a) || !is32bit(b) {
1139 return makeInt(newInt().Mul(big.NewInt(a), big.NewInt(b)))
1140 }
1141 c = a * b
1142 case token.QUO:
1143 return makeRat(big.NewRat(a, b))
1144 case token.QUO_ASSIGN:
1145 c = a / b
1146 case token.REM:
1147 c = a % b
1148 case token.AND:
1149 c = a & b
1150 case token.OR:
1151 c = a | b
1152 case token.XOR:
1153 c = a ^ b
1154 case token.AND_NOT:
1155 c = a &^ b
1156 default:
1157 goto Error
1158 }
1159 return int64Val(c)
1160
1161 case intVal:
1162 a := x.val
1163 b := y.(intVal).val
1164 c := newInt()
1165 switch op {
1166 case token.ADD:
1167 c.Add(a, b)
1168 case token.SUB:
1169 c.Sub(a, b)
1170 case token.MUL:
1171 c.Mul(a, b)
1172 case token.QUO:
1173 return makeRat(newRat().SetFrac(a, b))
1174 case token.QUO_ASSIGN:
1175 c.Quo(a, b)
1176 case token.REM:
1177 c.Rem(a, b)
1178 case token.AND:
1179 c.And(a, b)
1180 case token.OR:
1181 c.Or(a, b)
1182 case token.XOR:
1183 c.Xor(a, b)
1184 case token.AND_NOT:
1185 c.AndNot(a, b)
1186 default:
1187 goto Error
1188 }
1189 return makeInt(c)
1190
1191 case ratVal:
1192 a := x.val
1193 b := y.(ratVal).val
1194 c := newRat()
1195 switch op {
1196 case token.ADD:
1197 c.Add(a, b)
1198 case token.SUB:
1199 c.Sub(a, b)
1200 case token.MUL:
1201 c.Mul(a, b)
1202 case token.QUO:
1203 c.Quo(a, b)
1204 default:
1205 goto Error
1206 }
1207 return makeRat(c)
1208
1209 case floatVal:
1210 a := x.val
1211 b := y.(floatVal).val
1212 c := newFloat()
1213 switch op {
1214 case token.ADD:
1215 c.Add(a, b)
1216 case token.SUB:
1217 c.Sub(a, b)
1218 case token.MUL:
1219 c.Mul(a, b)
1220 case token.QUO:
1221 c.Quo(a, b)
1222 default:
1223 goto Error
1224 }
1225 return makeFloat(c)
1226
1227 case complexVal:
1228 y := y.(complexVal)
1229 a, b := x.re, x.im
1230 c, d := y.re, y.im
1231 var re, im Value
1232 switch op {
1233 case token.ADD:
1234
1235 re = add(a, c)
1236 im = add(b, d)
1237 case token.SUB:
1238
1239 re = sub(a, c)
1240 im = sub(b, d)
1241 case token.MUL:
1242
1243 ac := mul(a, c)
1244 bd := mul(b, d)
1245 bc := mul(b, c)
1246 ad := mul(a, d)
1247 re = sub(ac, bd)
1248 im = add(bc, ad)
1249 case token.QUO:
1250
1251 ac := mul(a, c)
1252 bd := mul(b, d)
1253 bc := mul(b, c)
1254 ad := mul(a, d)
1255 cc := mul(c, c)
1256 dd := mul(d, d)
1257 s := add(cc, dd)
1258 re = add(ac, bd)
1259 re = quo(re, s)
1260 im = sub(bc, ad)
1261 im = quo(im, s)
1262 default:
1263 goto Error
1264 }
1265 return makeComplex(re, im)
1266
1267 case *stringVal:
1268 if op == token.ADD {
1269 return &stringVal{l: x, r: y.(*stringVal)}
1270 }
1271 }
1272
1273 Error:
1274 panic(fmt.Sprintf("invalid binary operation %v %s %v", x_, op, y_))
1275 }
1276
1277 func add(x, y Value) Value { return BinaryOp(x, token.ADD, y) }
1278 func sub(x, y Value) Value { return BinaryOp(x, token.SUB, y) }
1279 func mul(x, y Value) Value { return BinaryOp(x, token.MUL, y) }
1280 func quo(x, y Value) Value { return BinaryOp(x, token.QUO, y) }
1281
1282
1283
1284
1285 func 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
1318 func 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
1337
1338
1339
1340 func Compare(x_ Value, op token.Token, y_ Value) bool {
1341 x, y := match(x_, y_)
1342
1343 switch x := x.(type) {
1344 case unknownVal:
1345 return false
1346
1347 case boolVal:
1348 y := y.(boolVal)
1349 switch op {
1350 case token.EQL:
1351 return x == y
1352 case token.NEQ:
1353 return x != y
1354 }
1355
1356 case int64Val:
1357 y := y.(int64Val)
1358 switch op {
1359 case token.EQL:
1360 return x == y
1361 case token.NEQ:
1362 return x != y
1363 case token.LSS:
1364 return x < y
1365 case token.LEQ:
1366 return x <= y
1367 case token.GTR:
1368 return x > y
1369 case token.GEQ:
1370 return x >= y
1371 }
1372
1373 case intVal:
1374 return cmpZero(x.val.Cmp(y.(intVal).val), op)
1375
1376 case ratVal:
1377 return cmpZero(x.val.Cmp(y.(ratVal).val), op)
1378
1379 case floatVal:
1380 return cmpZero(x.val.Cmp(y.(floatVal).val), op)
1381
1382 case complexVal:
1383 y := y.(complexVal)
1384 re := Compare(x.re, token.EQL, y.re)
1385 im := Compare(x.im, token.EQL, y.im)
1386 switch op {
1387 case token.EQL:
1388 return re && im
1389 case token.NEQ:
1390 return !re || !im
1391 }
1392
1393 case *stringVal:
1394 xs := x.string()
1395 ys := y.(*stringVal).string()
1396 switch op {
1397 case token.EQL:
1398 return xs == ys
1399 case token.NEQ:
1400 return xs != ys
1401 case token.LSS:
1402 return xs < ys
1403 case token.LEQ:
1404 return xs <= ys
1405 case token.GTR:
1406 return xs > ys
1407 case token.GEQ:
1408 return xs >= ys
1409 }
1410 }
1411
1412 panic(fmt.Sprintf("invalid comparison %v %s %v", x_, op, y_))
1413 }
1414
View as plain text