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