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