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