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 return vtoc(x), y
1087 }
1088
1089
1090
1091 return x, x
1092 }
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103 func BinaryOp(x_ Value, op token.Token, y_ Value) Value {
1104 x, y := match(x_, y_)
1105
1106 switch x := x.(type) {
1107 case unknownVal:
1108 return x
1109
1110 case boolVal:
1111 y := y.(boolVal)
1112 switch op {
1113 case token.LAND:
1114 return x && y
1115 case token.LOR:
1116 return x || y
1117 }
1118
1119 case int64Val:
1120 a := int64(x)
1121 b := int64(y.(int64Val))
1122 var c int64
1123 switch op {
1124 case token.ADD:
1125 if !is63bit(a) || !is63bit(b) {
1126 return makeInt(newInt().Add(big.NewInt(a), big.NewInt(b)))
1127 }
1128 c = a + b
1129 case token.SUB:
1130 if !is63bit(a) || !is63bit(b) {
1131 return makeInt(newInt().Sub(big.NewInt(a), big.NewInt(b)))
1132 }
1133 c = a - b
1134 case token.MUL:
1135 if !is32bit(a) || !is32bit(b) {
1136 return makeInt(newInt().Mul(big.NewInt(a), big.NewInt(b)))
1137 }
1138 c = a * b
1139 case token.QUO:
1140 return makeRat(big.NewRat(a, b))
1141 case token.QUO_ASSIGN:
1142 c = a / b
1143 case token.REM:
1144 c = a % b
1145 case token.AND:
1146 c = a & b
1147 case token.OR:
1148 c = a | b
1149 case token.XOR:
1150 c = a ^ b
1151 case token.AND_NOT:
1152 c = a &^ b
1153 default:
1154 goto Error
1155 }
1156 return int64Val(c)
1157
1158 case intVal:
1159 a := x.val
1160 b := y.(intVal).val
1161 c := newInt()
1162 switch op {
1163 case token.ADD:
1164 c.Add(a, b)
1165 case token.SUB:
1166 c.Sub(a, b)
1167 case token.MUL:
1168 c.Mul(a, b)
1169 case token.QUO:
1170 return makeRat(newRat().SetFrac(a, b))
1171 case token.QUO_ASSIGN:
1172 c.Quo(a, b)
1173 case token.REM:
1174 c.Rem(a, b)
1175 case token.AND:
1176 c.And(a, b)
1177 case token.OR:
1178 c.Or(a, b)
1179 case token.XOR:
1180 c.Xor(a, b)
1181 case token.AND_NOT:
1182 c.AndNot(a, b)
1183 default:
1184 goto Error
1185 }
1186 return makeInt(c)
1187
1188 case ratVal:
1189 a := x.val
1190 b := y.(ratVal).val
1191 c := newRat()
1192 switch op {
1193 case token.ADD:
1194 c.Add(a, b)
1195 case token.SUB:
1196 c.Sub(a, b)
1197 case token.MUL:
1198 c.Mul(a, b)
1199 case token.QUO:
1200 c.Quo(a, b)
1201 default:
1202 goto Error
1203 }
1204 return makeRat(c)
1205
1206 case floatVal:
1207 a := x.val
1208 b := y.(floatVal).val
1209 c := newFloat()
1210 switch op {
1211 case token.ADD:
1212 c.Add(a, b)
1213 case token.SUB:
1214 c.Sub(a, b)
1215 case token.MUL:
1216 c.Mul(a, b)
1217 case token.QUO:
1218 c.Quo(a, b)
1219 default:
1220 goto Error
1221 }
1222 return makeFloat(c)
1223
1224 case complexVal:
1225 y := y.(complexVal)
1226 a, b := x.re, x.im
1227 c, d := y.re, y.im
1228 var re, im Value
1229 switch op {
1230 case token.ADD:
1231
1232 re = add(a, c)
1233 im = add(b, d)
1234 case token.SUB:
1235
1236 re = sub(a, c)
1237 im = sub(b, d)
1238 case token.MUL:
1239
1240 ac := mul(a, c)
1241 bd := mul(b, d)
1242 bc := mul(b, c)
1243 ad := mul(a, d)
1244 re = sub(ac, bd)
1245 im = add(bc, ad)
1246 case token.QUO:
1247
1248 ac := mul(a, c)
1249 bd := mul(b, d)
1250 bc := mul(b, c)
1251 ad := mul(a, d)
1252 cc := mul(c, c)
1253 dd := mul(d, d)
1254 s := add(cc, dd)
1255 re = add(ac, bd)
1256 re = quo(re, s)
1257 im = sub(bc, ad)
1258 im = quo(im, s)
1259 default:
1260 goto Error
1261 }
1262 return makeComplex(re, im)
1263
1264 case *stringVal:
1265 if op == token.ADD {
1266 return &stringVal{l: x, r: y.(*stringVal)}
1267 }
1268 }
1269
1270 Error:
1271 panic(fmt.Sprintf("invalid binary operation %v %s %v", x_, op, y_))
1272 }
1273
1274 func add(x, y Value) Value { return BinaryOp(x, token.ADD, y) }
1275 func sub(x, y Value) Value { return BinaryOp(x, token.SUB, y) }
1276 func mul(x, y Value) Value { return BinaryOp(x, token.MUL, y) }
1277 func quo(x, y Value) Value { return BinaryOp(x, token.QUO, y) }
1278
1279
1280
1281
1282 func Shift(x Value, op token.Token, s uint) Value {
1283 switch x := x.(type) {
1284 case unknownVal:
1285 return x
1286
1287 case int64Val:
1288 if s == 0 {
1289 return x
1290 }
1291 switch op {
1292 case token.SHL:
1293 z := i64toi(x).val
1294 return makeInt(z.Lsh(z, s))
1295 case token.SHR:
1296 return x >> s
1297 }
1298
1299 case intVal:
1300 if s == 0 {
1301 return x
1302 }
1303 z := newInt()
1304 switch op {
1305 case token.SHL:
1306 return makeInt(z.Lsh(x.val, s))
1307 case token.SHR:
1308 return makeInt(z.Rsh(x.val, s))
1309 }
1310 }
1311
1312 panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s))
1313 }
1314
1315 func cmpZero(x int, op token.Token) bool {
1316 switch op {
1317 case token.EQL:
1318 return x == 0
1319 case token.NEQ:
1320 return x != 0
1321 case token.LSS:
1322 return x < 0
1323 case token.LEQ:
1324 return x <= 0
1325 case token.GTR:
1326 return x > 0
1327 case token.GEQ:
1328 return x >= 0
1329 }
1330 panic(fmt.Sprintf("invalid comparison %v %s 0", x, op))
1331 }
1332
1333
1334
1335
1336
1337 func Compare(x_ Value, op token.Token, y_ Value) bool {
1338 x, y := match(x_, y_)
1339
1340 switch x := x.(type) {
1341 case unknownVal:
1342 return false
1343
1344 case boolVal:
1345 y := y.(boolVal)
1346 switch op {
1347 case token.EQL:
1348 return x == y
1349 case token.NEQ:
1350 return x != y
1351 }
1352
1353 case int64Val:
1354 y := y.(int64Val)
1355 switch op {
1356 case token.EQL:
1357 return x == y
1358 case token.NEQ:
1359 return x != y
1360 case token.LSS:
1361 return x < y
1362 case token.LEQ:
1363 return x <= y
1364 case token.GTR:
1365 return x > y
1366 case token.GEQ:
1367 return x >= y
1368 }
1369
1370 case intVal:
1371 return cmpZero(x.val.Cmp(y.(intVal).val), op)
1372
1373 case ratVal:
1374 return cmpZero(x.val.Cmp(y.(ratVal).val), op)
1375
1376 case floatVal:
1377 return cmpZero(x.val.Cmp(y.(floatVal).val), op)
1378
1379 case complexVal:
1380 y := y.(complexVal)
1381 re := Compare(x.re, token.EQL, y.re)
1382 im := Compare(x.im, token.EQL, y.im)
1383 switch op {
1384 case token.EQL:
1385 return re && im
1386 case token.NEQ:
1387 return !re || !im
1388 }
1389
1390 case *stringVal:
1391 xs := x.string()
1392 ys := y.(*stringVal).string()
1393 switch op {
1394 case token.EQL:
1395 return xs == ys
1396 case token.NEQ:
1397 return xs != ys
1398 case token.LSS:
1399 return xs < ys
1400 case token.LEQ:
1401 return xs <= ys
1402 case token.GTR:
1403 return xs > ys
1404 case token.GEQ:
1405 return xs >= ys
1406 }
1407 }
1408
1409 panic(fmt.Sprintf("invalid comparison %v %s %v", x_, op, y_))
1410 }
1411
View as plain text