Mercurial > projects > ddmd
comparison dmd/AssocArrayLiteralExp.d @ 90:39648eb578f6
more Expressions work
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 30 Aug 2010 20:27:56 +0100 |
parents | be2ab491772e |
children | 6da99741178e |
comparison
equal
deleted
inserted
replaced
88:23280d154c5b | 90:39648eb578f6 |
---|---|
57 printf("AssocArrayLiteralExp.semantic('%s')\n", toChars()); | 57 printf("AssocArrayLiteralExp.semantic('%s')\n", toChars()); |
58 } | 58 } |
59 | 59 |
60 // Run semantic() on each element | 60 // Run semantic() on each element |
61 for (size_t i = 0; i < keys.dim; i++) | 61 for (size_t i = 0; i < keys.dim; i++) |
62 { Expression key = cast(Expression)keys.data[i]; | 62 { auto key = keys[i]; |
63 Expression value = cast(Expression)values.data[i]; | 63 auto value = values[i]; |
64 | 64 |
65 key = key.semantic(sc); | 65 key = key.semantic(sc); |
66 value = value.semantic(sc); | 66 value = value.semantic(sc); |
67 | 67 |
68 keys.data[i] = key; | 68 keys[i] = key; |
69 values.data[i] = value; | 69 values[i] = value; |
70 } | 70 } |
71 expandTuples(keys); | 71 expandTuples(keys); |
72 expandTuples(values); | 72 expandTuples(values); |
73 if (keys.dim != values.dim) | 73 if (keys.dim != values.dim) |
74 { | 74 { |
75 error("number of keys is %u, must match number of values %u", keys.dim, values.dim); | 75 error("number of keys is %u, must match number of values %u", keys.dim, values.dim); |
76 keys.setDim(0); | 76 keys.setDim(0); |
77 values.setDim(0); | 77 values.setDim(0); |
78 } | 78 } |
79 for (size_t i = 0; i < keys.dim; i++) | 79 for (size_t i = 0; i < keys.dim; i++) |
80 { Expression key = cast(Expression)keys.data[i]; | 80 { auto key = keys[i]; |
81 Expression value = cast(Expression)values.data[i]; | 81 auto value = values[i]; |
82 | 82 |
83 if (!key.type) | 83 if (!key.type) |
84 error("%s has no value", key.toChars()); | 84 error("%s has no value", key.toChars()); |
85 if (!value.type) | 85 if (!value.type) |
86 error("%s has no value", value.toChars()); | 86 error("%s has no value", value.toChars()); |
89 | 89 |
90 if (!tkey) | 90 if (!tkey) |
91 tkey = key.type; | 91 tkey = key.type; |
92 else | 92 else |
93 key = key.implicitCastTo(sc, tkey); | 93 key = key.implicitCastTo(sc, tkey); |
94 keys.data[i] = key; | 94 keys[i] = key; |
95 | 95 |
96 if (!tvalue) | 96 if (!tvalue) |
97 tvalue = value.type; | 97 tvalue = value.type; |
98 else | 98 else |
99 value = value.implicitCastTo(sc, tvalue); | 99 value = value.implicitCastTo(sc, tvalue); |
100 values.data[i] = value; | 100 values[i] = value; |
101 } | 101 } |
102 | 102 |
103 if (!tkey) | 103 if (!tkey) |
104 tkey = Type.tvoid; | 104 tkey = Type.tvoid; |
105 if (!tvalue) | 105 if (!tvalue) |
123 //printf("AssocArrayLiteralExp.toElem() %s\n", toChars()); | 123 //printf("AssocArrayLiteralExp.toElem() %s\n", toChars()); |
124 dim = keys.dim; | 124 dim = keys.dim; |
125 e = el_long(TYint, dim); | 125 e = el_long(TYint, dim); |
126 for (size_t i = 0; i < dim; i++) | 126 for (size_t i = 0; i < dim; i++) |
127 { | 127 { |
128 Expression el = cast(Expression)keys.data[i]; | 128 auto el = keys[i]; |
129 | 129 |
130 for (int j = 0; j < 2; j++) | 130 for (int j = 0; j < 2; j++) |
131 { | 131 { |
132 elem* ep = el.toElem(irs); | 132 elem* ep = el.toElem(irs); |
133 | 133 |
137 ep.Enumbytes = cast(uint)el.type.size(); | 137 ep.Enumbytes = cast(uint)el.type.size(); |
138 } | 138 } |
139 //printf("[%d] %s\n", i, el.toChars()); | 139 //printf("[%d] %s\n", i, el.toChars()); |
140 //elem_print(ep); | 140 //elem_print(ep); |
141 e = el_param(ep, e); | 141 e = el_param(ep, e); |
142 el = cast(Expression)values.data[i]; | 142 el = values[i]; |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 Type t = type.toBasetype().mutableOf(); | 146 Type t = type.toBasetype().mutableOf(); |
147 assert(t.ty == Taarray); | 147 assert(t.ty == Taarray); |
148 TypeAArray ta = cast(TypeAArray)t; | 148 auto ta = cast(TypeAArray)t; |
149 | 149 |
150 /* Unfortunately, the hash function for Aa (array of chars) is custom and | 150 /* Unfortunately, the hash function for Aa (array of chars) is custom and |
151 * different from Axa and Aya, which get the generic hash function. | 151 * different from Axa and Aya, which get the generic hash function. |
152 * So, rewrite the type of the AArray so that if it's key type | 152 * So, rewrite the type of the AArray so that if it's key type |
153 * is an array of const or invariant, make it an array of mutable. | 153 * is an array of const or invariant, make it an array of mutable. |
173 override bool checkSideEffect(int flag) | 173 override bool checkSideEffect(int flag) |
174 { | 174 { |
175 bool f = false; | 175 bool f = false; |
176 | 176 |
177 for (size_t i = 0; i < keys.dim; i++) | 177 for (size_t i = 0; i < keys.dim; i++) |
178 { Expression key = cast(Expression)keys.data[i]; | 178 { auto key = keys[i]; |
179 Expression value = cast(Expression)values.data[i]; | 179 auto value = values[i]; |
180 | 180 |
181 f |= key.checkSideEffect(2); | 181 f |= key.checkSideEffect(2); |
182 f |= value.checkSideEffect(2); | 182 f |= value.checkSideEffect(2); |
183 } | 183 } |
184 if (flag == 0 && f == 0) | 184 if (flag == 0 && f == 0) |
188 | 188 |
189 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) | 189 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
190 { | 190 { |
191 buf.writeByte('['); | 191 buf.writeByte('['); |
192 for (size_t i = 0; i < keys.dim; i++) | 192 for (size_t i = 0; i < keys.dim; i++) |
193 { Expression key = cast(Expression)keys.data[i]; | 193 { auto key = keys[i]; |
194 Expression value = cast(Expression)values.data[i]; | 194 auto value = values[i]; |
195 | 195 |
196 if (i) | 196 if (i) |
197 buf.writeByte(','); | 197 buf.writeByte(','); |
198 expToCBuffer(buf, hgs, key, PREC.PREC_assign); | 198 expToCBuffer(buf, hgs, key, PREC.PREC_assign); |
199 buf.writeByte(':'); | 199 buf.writeByte(':'); |
205 override void toMangleBuffer(OutBuffer buf) | 205 override void toMangleBuffer(OutBuffer buf) |
206 { | 206 { |
207 size_t dim = keys.dim; | 207 size_t dim = keys.dim; |
208 buf.printf("A%u", dim); | 208 buf.printf("A%u", dim); |
209 for (size_t i = 0; i < dim; i++) | 209 for (size_t i = 0; i < dim; i++) |
210 { Expression key = cast(Expression)keys.data[i]; | 210 { auto key = keys[i]; |
211 Expression value = cast(Expression)values.data[i]; | 211 auto value = values[i]; |
212 | 212 |
213 key.toMangleBuffer(buf); | 213 key.toMangleBuffer(buf); |
214 value.toMangleBuffer(buf); | 214 value.toMangleBuffer(buf); |
215 } | 215 } |
216 } | 216 } |
221 } | 221 } |
222 | 222 |
223 override Expression optimize(int result) | 223 override Expression optimize(int result) |
224 { | 224 { |
225 assert(keys.dim == values.dim); | 225 assert(keys.dim == values.dim); |
226 for (size_t i = 0; i < keys.dim; i++) | 226 foreach (size_t i, Expression e; keys) |
227 { | 227 { |
228 Expression e = cast(Expression)keys.data[i]; | |
229 | |
230 e = e.optimize(WANTvalue | (result & WANTinterpret)); | 228 e = e.optimize(WANTvalue | (result & WANTinterpret)); |
231 keys.data[i] = e; | 229 keys[i] = e; |
232 | 230 |
233 e = cast(Expression)values.data[i]; | 231 e = values[i]; |
234 e = e.optimize(WANTvalue | (result & WANTinterpret)); | 232 e = e.optimize(WANTvalue | (result & WANTinterpret)); |
235 values.data[i] = e; | 233 values[i] = e; |
236 } | 234 } |
237 return this; | 235 return this; |
238 } | 236 } |
239 | 237 |
240 override Expression interpret(InterState istate) | 238 override Expression interpret(InterState istate) |
245 version (LOG) { | 243 version (LOG) { |
246 printf("AssocArrayLiteralExp.interpret() %s\n", toChars()); | 244 printf("AssocArrayLiteralExp.interpret() %s\n", toChars()); |
247 } | 245 } |
248 for (size_t i = 0; i < keys.dim; i++) | 246 for (size_t i = 0; i < keys.dim; i++) |
249 { | 247 { |
250 Expression ekey = cast(Expression)keys.data[i]; | 248 auto ekey = keys[i]; |
251 Expression evalue = cast(Expression)values.data[i]; | 249 auto evalue = values[i]; |
252 Expression ex; | 250 Expression ex; |
253 | 251 |
254 ex = ekey.interpret(istate); | 252 ex = ekey.interpret(istate); |
255 if (ex is EXP_CANT_INTERPRET) | 253 if (ex is EXP_CANT_INTERPRET) |
256 goto Lerr; | 254 goto Lerr; |
259 */ | 257 */ |
260 if (ex != ekey) | 258 if (ex != ekey) |
261 { | 259 { |
262 if (keysx == keys) | 260 if (keysx == keys) |
263 keysx = cast(Expressions)keys.copy(); | 261 keysx = cast(Expressions)keys.copy(); |
264 keysx.data[i] = ex; | 262 keysx[i] = ex; |
265 } | 263 } |
266 | 264 |
267 ex = evalue.interpret(istate); | 265 ex = evalue.interpret(istate); |
268 if (ex is EXP_CANT_INTERPRET) | 266 if (ex is EXP_CANT_INTERPRET) |
269 goto Lerr; | 267 goto Lerr; |
272 */ | 270 */ |
273 if (ex != evalue) | 271 if (ex != evalue) |
274 { | 272 { |
275 if (valuesx == values) | 273 if (valuesx == values) |
276 valuesx = values.copy(); | 274 valuesx = values.copy(); |
277 valuesx.data[i] = ex; | 275 valuesx[i] = ex; |
278 } | 276 } |
279 } | 277 } |
280 | 278 |
281 if (keysx != keys) | 279 if (keysx != keys) |
282 expandTuples(keysx); | 280 expandTuples(keysx); |
287 | 285 |
288 /* Remove duplicate keys | 286 /* Remove duplicate keys |
289 */ | 287 */ |
290 for (size_t i = 1; i < keysx.dim; i++) | 288 for (size_t i = 1; i < keysx.dim; i++) |
291 { | 289 { |
292 Expression ekey = cast(Expression)keysx.data[i - 1]; | 290 auto ekey = keysx[i - 1]; |
293 | 291 |
294 for (size_t j = i; j < keysx.dim; j++) | 292 for (size_t j = i; j < keysx.dim; j++) |
295 { | 293 { |
296 Expression ekey2 = cast(Expression)keysx.data[j]; | 294 auto ekey2 = keysx[j]; |
297 Expression ex = Equal(TOKequal, Type.tbool, ekey, ekey2); | 295 Expression ex = Equal(TOKequal, Type.tbool, ekey, ekey2); |
298 if (ex is EXP_CANT_INTERPRET) | 296 if (ex is EXP_CANT_INTERPRET) |
299 goto Lerr; | 297 goto Lerr; |
300 if (ex.isBool(true)) // if a match | 298 if (ex.isBool(true)) // if a match |
301 { | 299 { |
337 Type tb = t.toBasetype(); | 335 Type tb = t.toBasetype(); |
338 if (tb.ty == Taarray && typeb.ty == Taarray) | 336 if (tb.ty == Taarray && typeb.ty == Taarray) |
339 { | 337 { |
340 for (size_t i = 0; i < keys.dim; i++) | 338 for (size_t i = 0; i < keys.dim; i++) |
341 { | 339 { |
342 Expression e = cast(Expression)keys.data[i]; | 340 auto e = keys[i]; |
343 MATCH m = cast(MATCH)e.implicitConvTo((cast(TypeAArray)tb).index); | 341 auto m = cast(MATCH)e.implicitConvTo((cast(TypeAArray)tb).index); |
344 if (m < result) | 342 if (m < result) |
345 result = m; // remember worst match | 343 result = m; // remember worst match |
346 if (result == MATCHnomatch) | 344 if (result == MATCHnomatch) |
347 break; // no need to check for worse | 345 break; // no need to check for worse |
348 e = cast(Expression)values.data[i]; | 346 e = values[i]; |
349 m = cast(MATCH)e.implicitConvTo(tb.nextOf()); | 347 m = cast(MATCH)e.implicitConvTo(tb.nextOf()); |
350 if (m < result) | 348 if (m < result) |
351 result = m; // remember worst match | 349 result = m; // remember worst match |
352 if (result == MATCHnomatch) | 350 if (result == MATCHnomatch) |
353 break; // no need to check for worse | 351 break; // no need to check for worse |
371 e.keys = cast(Expressions)keys.copy(); | 369 e.keys = cast(Expressions)keys.copy(); |
372 e.values = cast(Expressions)values.copy(); | 370 e.values = cast(Expressions)values.copy(); |
373 assert(keys.dim == values.dim); | 371 assert(keys.dim == values.dim); |
374 for (size_t i = 0; i < keys.dim; i++) | 372 for (size_t i = 0; i < keys.dim; i++) |
375 { | 373 { |
376 Expression ex = cast(Expression)values.data[i]; | 374 auto ex = values[i]; |
377 ex = ex.castTo(sc, tb.nextOf()); | 375 ex = ex.castTo(sc, tb.nextOf()); |
378 e.values.data[i] = ex; | 376 e.values[i] = ex; |
379 | 377 |
380 ex = cast(Expression)keys.data[i]; | 378 ex = keys[i]; |
381 ex = ex.castTo(sc, (cast(TypeAArray)tb).index); | 379 ex = ex.castTo(sc, (cast(TypeAArray)tb).index); |
382 e.keys.data[i] = ex; | 380 e.keys[i] = ex; |
383 } | 381 } |
384 e.type = t; | 382 e.type = t; |
385 return e; | 383 return e; |
386 } | 384 } |
387 L1: | 385 L1: |