Mercurial > projects > ddmd
annotate dmd/expression/Equal.d @ 84:be2ab491772e
Expressions -> Vector!Expression
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 30 Aug 2010 16:12:19 +0100 |
parents | ef02e2e203c2 |
children | e28b18c23469 |
rev | line source |
---|---|
0 | 1 module dmd.expression.Equal; |
2 | |
3 import dmd.Expression; | |
4 import dmd.Type; | |
5 import dmd.TOK; | |
73 | 6 import dmd.TY; |
0 | 7 import dmd.Loc; |
8 import dmd.StringExp; | |
9 import dmd.GlobalExpressions; | |
10 import dmd.ArrayLiteralExp; | |
11 import dmd.StructLiteralExp; | |
12 import dmd.Global; | |
13 import dmd.IntegerExp; | |
14 | |
15 import core.stdc.string; | |
16 | |
17 /* Also returns EXP_CANT_INTERPRET if cannot be computed. | |
18 */ | |
19 Expression Equal(TOK op, Type type, Expression e1, Expression e2) | |
20 { | |
21 Expression e; | |
22 Loc loc = e1.loc; | |
23 bool cmp; | |
24 real r1; | |
25 real r2; | |
26 | |
27 //printf("Equal(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars()); | |
28 | |
29 assert(op == TOK.TOKequal || op == TOK.TOKnotequal); | |
30 | |
31 if (e1.op == TOK.TOKnull) | |
32 { | |
33 if (e2.op == TOK.TOKnull) | |
34 cmp = true; | |
35 else if (e2.op == TOK.TOKstring) | |
36 { StringExp es2 = cast(StringExp)e2; | |
37 cmp = (0 == es2.len); | |
38 } | |
39 else if (e2.op == TOK.TOKarrayliteral) | |
40 { | |
41 ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; | |
42 cmp = !es2.elements || (0 == es2.elements.dim); | |
43 } | |
44 else | |
45 return EXP_CANT_INTERPRET; | |
46 } | |
47 else if (e2.op == TOK.TOKnull) | |
48 { | |
49 if (e1.op == TOK.TOKstring) | |
50 { | |
51 StringExp es1 = cast(StringExp)e1; | |
52 cmp = (0 == es1.len); | |
53 } | |
54 else if (e1.op == TOK.TOKarrayliteral) | |
55 { | |
56 ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; | |
57 cmp = !es1.elements || (0 == es1.elements.dim); | |
58 } | |
59 else | |
60 return EXP_CANT_INTERPRET; | |
61 } | |
62 else if (e1.op == TOK.TOKstring && e2.op == TOK.TOKstring) | |
63 { | |
64 StringExp es1 = cast(StringExp)e1; | |
65 StringExp es2 = cast(StringExp)e2; | |
66 | |
67 if (es1.sz != es2.sz) | |
68 { | |
69 assert(global.errors); | |
70 return EXP_CANT_INTERPRET; | |
71 } | |
72 if (es1.len == es2.len && memcmp(es1.string_, es2.string_, es1.sz * es1.len) == 0) | |
73 cmp = true; | |
74 else | |
75 cmp = false; | |
76 } | |
77 else if (e1.op == TOK.TOKarrayliteral && e2.op == TOK.TOKarrayliteral) | |
78 { | |
79 ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; | |
80 ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; | |
81 | |
82 if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim)) | |
83 cmp = true; // both arrays are empty | |
84 else if (!es1.elements || !es2.elements) | |
85 cmp = false; | |
86 else if (es1.elements.dim != es2.elements.dim) | |
87 cmp = false; | |
88 else | |
89 { | |
90 for (size_t i = 0; i < es1.elements.dim; i++) | |
91 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
92 auto ee1 = es1.elements[i]; |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
93 auto ee2 = es2.elements[i]; |
0 | 94 |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
95 auto v = Equal(TOK.TOKequal, Type.tint32, ee1, ee2); |
63 | 96 if (v is EXP_CANT_INTERPRET) |
0 | 97 return EXP_CANT_INTERPRET; |
98 long tmp = v.toInteger(); | |
99 cmp = (tmp != 0); | |
100 if (!cmp) | |
101 break; | |
102 } | |
103 } | |
104 } | |
105 else if (e1.op == TOK.TOKarrayliteral && e2.op == TOK.TOKstring) | |
106 { | |
107 // Swap operands and use common code | |
108 Expression ee = e1; | |
109 e1 = e2; | |
110 e2 = ee; | |
111 goto Lsa; | |
112 } | |
113 else if (e1.op == TOK.TOKstring && e2.op == TOK.TOKarrayliteral) | |
114 { | |
115 Lsa: | |
116 StringExp es1 = cast(StringExp)e1; | |
117 ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; | |
118 size_t dim1 = es1.len; | |
119 size_t dim2 = es2.elements ? es2.elements.dim : 0; | |
120 if (dim1 != dim2) | |
121 cmp = false; | |
122 else | |
123 { | |
124 for (size_t i = 0; i < dim1; i++) | |
125 { | |
126 ulong c = es1.charAt(i); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
127 auto ee2 = es2.elements[i]; |
0 | 128 if (ee2.isConst() != 1) |
129 return EXP_CANT_INTERPRET; | |
130 cmp = (c == ee2.toInteger()); | |
131 if (!cmp) | |
132 break; | |
133 } | |
134 } | |
135 } | |
136 else if (e1.op == TOK.TOKstructliteral && e2.op == TOK.TOKstructliteral) | |
137 { | |
138 StructLiteralExp es1 = cast(StructLiteralExp)e1; | |
139 StructLiteralExp es2 = cast(StructLiteralExp)e2; | |
140 | |
141 if (es1.sd != es2.sd) | |
142 cmp = false; | |
143 else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim)) | |
144 cmp = true; // both arrays are empty | |
145 else if (!es1.elements || !es2.elements) | |
146 cmp = false; | |
147 else if (es1.elements.dim != es2.elements.dim) | |
148 cmp = false; | |
149 else | |
150 { | |
151 cmp = true; | |
152 for (size_t i = 0; i < es1.elements.dim; i++) | |
153 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
154 auto ee1 = es1.elements[i]; |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
155 auto ee2 = es2.elements[i]; |
0 | 156 |
157 if (ee1 == ee2) | |
158 continue; | |
159 if (!ee1 || !ee2) | |
160 { | |
161 cmp = false; | |
162 break; | |
163 } | |
164 Expression v = Equal(TOK.TOKequal, Type.tint32, ee1, ee2); | |
63 | 165 if (v is EXP_CANT_INTERPRET) |
0 | 166 return EXP_CANT_INTERPRET; |
167 long tmp = v.toInteger(); | |
168 cmp = (tmp != 0); | |
169 if (!cmp) | |
170 break; | |
171 } | |
172 } | |
173 } | |
174 ///static if (false) { | |
175 /// else if (e1.op == TOKarrayliteral && e2.op == TOKstring) | |
176 /// { | |
177 /// } | |
178 ///} | |
179 else if (e1.isConst() != 1 || e2.isConst() != 1) | |
180 return EXP_CANT_INTERPRET; | |
181 else if (e1.type.isreal()) | |
182 { | |
183 r1 = e1.toReal(); | |
184 r2 = e2.toReal(); | |
185 goto L1; | |
186 } | |
187 else if (e1.type.isimaginary()) | |
188 { | |
189 r1 = e1.toImaginary(); | |
190 r2 = e2.toImaginary(); | |
191 L1: | |
192 cmp = (r1 == r2); | |
193 } | |
194 else if (e1.type.iscomplex()) | |
195 { | |
196 cmp = (e1.toComplex() == e2.toComplex()); | |
197 } | |
73 | 198 else if (e1.type.isintegral() || e1.type.ty == Tpointer) |
0 | 199 { |
200 cmp = (e1.toInteger() == e2.toInteger()); | |
201 } | |
202 else | |
203 return EXP_CANT_INTERPRET; | |
204 if (op == TOK.TOKnotequal) | |
205 cmp = !cmp; | |
206 | |
207 e = new IntegerExp(loc, cmp, type); | |
208 | |
209 return e; | |
210 } |