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