LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file implements operations on ideal constants. | 5 // This file implements operations on ideal constants. |
6 | 6 |
7 package types | 7 package types |
8 | 8 |
9 import ( | 9 import ( |
10 "big" | 10 "big" |
11 "go/token" | 11 "go/token" |
12 "strconv" | 12 "strconv" |
13 ) | 13 ) |
14 | 14 |
| 15 |
| 16 // TODO(gri) Consider changing the API so Const is an interface |
| 17 // and operations on consts don't have to type switch. |
15 | 18 |
16 // A Const implements an ideal constant Value. | 19 // A Const implements an ideal constant Value. |
17 // The zero value z for a Const is not a valid constant value. | 20 // The zero value z for a Const is not a valid constant value. |
18 type Const struct { | 21 type Const struct { |
19 // representation of constant values: | 22 // representation of constant values: |
20 // ideal bool -> bool | 23 // ideal bool -> bool |
21 // ideal int -> *big.Int | 24 // ideal int -> *big.Int |
22 // ideal float -> *big.Rat | 25 // ideal float -> *big.Rat |
23 // ideal complex -> cmplx | 26 // ideal complex -> cmplx |
24 // ideal string -> string | 27 // ideal string -> string |
25 val interface{} | 28 val interface{} |
26 } | 29 } |
27 | 30 |
28 | 31 |
29 // Representation of complex values. | 32 // Representation of complex values. |
30 type cmplx struct { | 33 type cmplx struct { |
31 re, im *big.Rat | 34 re, im *big.Rat |
32 } | 35 } |
33 | 36 |
34 | 37 |
35 func assert(cond bool) { | 38 func assert(cond bool) { |
36 if !cond { | 39 if !cond { |
37 panic("go/types internal error: assertion failed") | 40 panic("go/types internal error: assertion failed") |
38 } | 41 } |
39 } | 42 } |
40 | 43 |
41 | 44 |
42 // NewConst creates a new ideal constant from literal | 45 // MakeConst makes an ideal constant from a literal |
43 // token and the corresponding literal string. | 46 // token and the corresponding literal string. |
44 func NewConst(kind token.Token, lit string) Const { | 47 func MakeConst(tok token.Token, lit string) Const { |
45 » switch kind { | 48 » switch tok { |
46 case token.INT: | 49 case token.INT: |
47 var x big.Int | 50 var x big.Int |
48 _, ok := x.SetString(lit, 0) | 51 _, ok := x.SetString(lit, 0) |
49 assert(ok) | 52 assert(ok) |
50 return Const{&x} | 53 return Const{&x} |
51 case token.FLOAT: | 54 case token.FLOAT: |
52 var y big.Rat | 55 var y big.Rat |
53 _, ok := y.SetString(lit) | 56 _, ok := y.SetString(lit) |
54 assert(ok) | 57 assert(ok) |
55 return Const{&y} | 58 return Const{&y} |
(...skipping 10 matching lines...) Expand all Loading... |
66 return Const{big.NewInt(int64(code))} | 69 return Const{big.NewInt(int64(code))} |
67 case token.STRING: | 70 case token.STRING: |
68 s, err := strconv.Unquote(lit) | 71 s, err := strconv.Unquote(lit) |
69 assert(err == nil) | 72 assert(err == nil) |
70 return Const{s} | 73 return Const{s} |
71 } | 74 } |
72 panic("unreachable") | 75 panic("unreachable") |
73 } | 76 } |
74 | 77 |
75 | 78 |
76 // NewZero creates a new zero constant for the given type. | 79 // MakeZero returns the zero constant for the given type. |
77 func NewZero(typ *Type) Const { | 80 func MakeZero(typ *Type) Const { |
78 // TODO(gri) fix this | 81 // TODO(gri) fix this |
79 return Const{0} | 82 return Const{0} |
80 } | |
81 | |
82 | |
83 // IsValid returns true if x represents a constant value. | |
84 func (x Const) IsValid() bool { | |
85 return x.val != nil | |
86 } | 83 } |
87 | 84 |
88 | 85 |
89 // Match attempts to match the internal constant representations of x and y. | 86 // Match attempts to match the internal constant representations of x and y. |
90 // If the attempt is successful, the result is the values of x and y, | 87 // If the attempt is successful, the result is the values of x and y, |
91 // if necessary converted to have the same internal representation; otherwise | 88 // if necessary converted to have the same internal representation; otherwise |
92 // the results are invalid. | 89 // the results are invalid. |
93 func (x Const) Match(y Const) (u, v Const) { | 90 func (x Const) Match(y Const) (u, v Const) { |
94 switch a := x.val.(type) { | 91 switch a := x.val.(type) { |
95 case bool: | 92 case bool: |
96 if _, ok := y.val.(bool); ok { | 93 if _, ok := y.val.(bool); ok { |
97 u, v = x, y | 94 u, v = x, y |
98 } | 95 } |
99 case *big.Int: | 96 case *big.Int: |
100 » » switch b := y.val.(type) { | 97 » » switch y.val.(type) { |
101 case *big.Int: | 98 case *big.Int: |
102 u, v = x, y | 99 u, v = x, y |
103 case *big.Rat: | 100 case *big.Rat: |
104 var z big.Rat | 101 var z big.Rat |
105 z.SetInt(a) | 102 z.SetInt(a) |
106 u, v = Const{&z}, y | 103 u, v = Const{&z}, y |
107 case cmplx: | 104 case cmplx: |
108 var z big.Rat | 105 var z big.Rat |
109 z.SetInt(a) | 106 z.SetInt(a) |
110 u, v = Const{cmplx{&z, big.NewRat(0, 1)}}, y | 107 u, v = Const{cmplx{&z, big.NewRat(0, 1)}}, y |
111 } | 108 } |
112 case *big.Rat: | 109 case *big.Rat: |
113 » » switch b := y.val.(type) { | 110 » » switch y.val.(type) { |
114 case *big.Int: | 111 case *big.Int: |
115 v, u = y.Match(x) | 112 v, u = y.Match(x) |
116 case *big.Rat: | 113 case *big.Rat: |
117 u, v = x, y | 114 u, v = x, y |
118 case cmplx: | 115 case cmplx: |
119 u, v = Const{cmplx{a, big.NewRat(0, 0)}}, y | 116 u, v = Const{cmplx{a, big.NewRat(0, 0)}}, y |
120 } | 117 } |
121 case cmplx: | 118 case cmplx: |
122 » » switch b := y.val.(type) { | 119 » » switch y.val.(type) { |
123 case *big.Int, *big.Rat: | 120 case *big.Int, *big.Rat: |
124 v, u = y.Match(x) | 121 v, u = y.Match(x) |
125 case cmplx: | 122 case cmplx: |
126 u, v = x, y | 123 u, v = x, y |
127 } | 124 } |
128 case string: | 125 case string: |
129 if _, ok := y.val.(string); ok { | 126 if _, ok := y.val.(string); ok { |
130 u, v = x, y | 127 u, v = x, y |
131 } | 128 } |
132 default: | 129 default: |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 return x < y | 338 return x < y |
342 case token.LEQ: | 339 case token.LEQ: |
343 return x <= y | 340 return x <= y |
344 case token.GTR: | 341 case token.GTR: |
345 return x > y | 342 return x > y |
346 case token.GEQ: | 343 case token.GEQ: |
347 return x >= y | 344 return x >= y |
348 } | 345 } |
349 panic("unreachable") | 346 panic("unreachable") |
350 } | 347 } |
LEFT | RIGHT |