Mercurial > projects > ldc
annotate dmd/constfold.c @ 1622:a542ef277a84
Merge DMD r316: bugzilla 3628 can't cast null to int
---
dmd/constfold.c | 2 +-
dmd/optimize.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
author | Leandro Lucarella <llucax@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 15:18:22 -0300 |
parents | fb2e6707ad17 |
children |
rev | line source |
---|---|
336 | 1 |
2 // Compiler implementation of the D programming language | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
3 // Copyright (c) 1999-2009 by Digital Mars |
336 | 4 // All Rights Reserved |
5 // written by Walter Bright | |
6 // http://www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <assert.h> | |
14 #include <math.h> | |
15 | |
16 #if __DMC__ | |
17 #include <complex.h> | |
18 #endif | |
19 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
20 #include "rmem.h" |
336 | 21 #include "root.h" |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
22 #include "port.h" |
336 | 23 |
24 #include "mtype.h" | |
25 #include "expression.h" | |
26 #include "aggregate.h" | |
27 #include "declaration.h" | |
28 | |
29 #ifdef IN_GCC | |
30 #include "d-gcc-real.h" | |
31 | |
32 /* %% fix? */ | |
33 extern "C" bool real_isnan (const real_t *); | |
34 #endif | |
35 | |
36 static real_t zero; // work around DMC bug for now | |
37 | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
38 #if __FreeBSD__ |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
39 #define fmodl fmod // hack for now, fix later |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
40 #endif |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
41 |
336 | 42 #define LOG 0 |
43 | |
44 Expression *expType(Type *type, Expression *e) | |
45 { | |
46 if (type != e->type) | |
47 { | |
48 e = e->copy(); | |
49 e->type = type; | |
50 } | |
51 return e; | |
52 } | |
53 | |
54 /* ================================== isConst() ============================== */ | |
55 | |
56 int Expression::isConst() | |
57 { | |
58 //printf("Expression::isConst(): %s\n", toChars()); | |
59 return 0; | |
60 } | |
61 | |
62 int IntegerExp::isConst() | |
63 { | |
64 return 1; | |
65 } | |
66 | |
67 int RealExp::isConst() | |
68 { | |
69 return 1; | |
70 } | |
71 | |
72 int ComplexExp::isConst() | |
73 { | |
74 return 1; | |
75 } | |
76 | |
1587 | 77 int NullExp::isConst() |
78 { | |
79 return 1; | |
80 } | |
81 | |
336 | 82 int SymOffExp::isConst() |
83 { | |
84 return 2; | |
85 } | |
86 | |
87 /* =============================== constFold() ============================== */ | |
88 | |
89 /* The constFold() functions were redundant with the optimize() ones, | |
90 * and so have been folded in with them. | |
91 */ | |
92 | |
93 /* ========================================================================== */ | |
94 | |
95 Expression *Neg(Type *type, Expression *e1) | |
96 { Expression *e; | |
97 Loc loc = e1->loc; | |
98 | |
99 if (e1->type->isreal()) | |
100 { | |
101 e = new RealExp(loc, -e1->toReal(), type); | |
102 } | |
103 else if (e1->type->isimaginary()) | |
104 { | |
105 e = new RealExp(loc, -e1->toImaginary(), type); | |
106 } | |
107 else if (e1->type->iscomplex()) | |
108 { | |
109 e = new ComplexExp(loc, -e1->toComplex(), type); | |
110 } | |
111 else | |
112 e = new IntegerExp(loc, -e1->toInteger(), type); | |
113 return e; | |
114 } | |
115 | |
116 Expression *Com(Type *type, Expression *e1) | |
117 { Expression *e; | |
118 Loc loc = e1->loc; | |
119 | |
120 e = new IntegerExp(loc, ~e1->toInteger(), type); | |
121 return e; | |
122 } | |
123 | |
124 Expression *Not(Type *type, Expression *e1) | |
125 { Expression *e; | |
126 Loc loc = e1->loc; | |
127 | |
128 e = new IntegerExp(loc, e1->isBool(0), type); | |
129 return e; | |
130 } | |
131 | |
132 Expression *Bool(Type *type, Expression *e1) | |
133 { Expression *e; | |
134 Loc loc = e1->loc; | |
135 | |
136 e = new IntegerExp(loc, e1->isBool(1), type); | |
137 return e; | |
138 } | |
139 | |
140 Expression *Add(Type *type, Expression *e1, Expression *e2) | |
141 { Expression *e; | |
142 Loc loc = e1->loc; | |
143 | |
144 #if LOG | |
145 printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
146 #endif | |
147 if (type->isreal()) | |
148 { | |
149 e = new RealExp(loc, e1->toReal() + e2->toReal(), type); | |
150 } | |
151 else if (type->isimaginary()) | |
152 { | |
153 e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type); | |
154 } | |
155 else if (type->iscomplex()) | |
156 { | |
157 // This rigamarole is necessary so that -0.0 doesn't get | |
158 // converted to +0.0 by doing an extraneous add with +0.0 | |
159 complex_t c1; | |
160 real_t r1; | |
161 real_t i1; | |
162 | |
163 complex_t c2; | |
164 real_t r2; | |
165 real_t i2; | |
166 | |
167 complex_t v; | |
168 int x; | |
169 | |
170 if (e1->type->isreal()) | |
171 { r1 = e1->toReal(); | |
172 x = 0; | |
173 } | |
174 else if (e1->type->isimaginary()) | |
175 { i1 = e1->toImaginary(); | |
176 x = 3; | |
177 } | |
178 else | |
179 { c1 = e1->toComplex(); | |
180 x = 6; | |
181 } | |
182 | |
183 if (e2->type->isreal()) | |
184 { r2 = e2->toReal(); | |
185 } | |
186 else if (e2->type->isimaginary()) | |
187 { i2 = e2->toImaginary(); | |
188 x += 1; | |
189 } | |
190 else | |
191 { c2 = e2->toComplex(); | |
192 x += 2; | |
193 } | |
194 | |
195 switch (x) | |
196 { | |
197 #if __DMC__ | |
198 case 0+0: v = (complex_t) (r1 + r2); break; | |
199 case 0+1: v = r1 + i2 * I; break; | |
200 case 0+2: v = r1 + c2; break; | |
201 case 3+0: v = i1 * I + r2; break; | |
202 case 3+1: v = (complex_t) ((i1 + i2) * I); break; | |
203 case 3+2: v = i1 * I + c2; break; | |
204 case 6+0: v = c1 + r2; break; | |
205 case 6+1: v = c1 + i2 * I; break; | |
206 case 6+2: v = c1 + c2; break; | |
207 #else | |
208 case 0+0: v = complex_t(r1 + r2, 0); break; | |
209 case 0+1: v = complex_t(r1, i2); break; | |
210 case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break; | |
211 case 3+0: v = complex_t(r2, i1); break; | |
212 case 3+1: v = complex_t(0, i1 + i2); break; | |
213 case 3+2: v = complex_t(creall(c2), i1 + cimagl(c2)); break; | |
214 case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break; | |
215 case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break; | |
216 case 6+2: v = c1 + c2; break; | |
217 #endif | |
218 default: assert(0); | |
219 } | |
220 e = new ComplexExp(loc, v, type); | |
221 } | |
222 else if (e1->op == TOKsymoff) | |
223 { | |
224 SymOffExp *soe = (SymOffExp *)e1; | |
225 e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger()); | |
226 e->type = type; | |
227 } | |
228 else if (e2->op == TOKsymoff) | |
229 { | |
230 SymOffExp *soe = (SymOffExp *)e2; | |
231 e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger()); | |
232 e->type = type; | |
233 } | |
234 else | |
235 e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type); | |
236 return e; | |
237 } | |
238 | |
239 | |
240 Expression *Min(Type *type, Expression *e1, Expression *e2) | |
241 { Expression *e; | |
242 Loc loc = e1->loc; | |
243 | |
244 if (type->isreal()) | |
245 { | |
246 e = new RealExp(loc, e1->toReal() - e2->toReal(), type); | |
247 } | |
248 else if (type->isimaginary()) | |
249 { | |
250 e = new RealExp(loc, e1->toImaginary() - e2->toImaginary(), type); | |
251 } | |
252 else if (type->iscomplex()) | |
253 { | |
254 // This rigamarole is necessary so that -0.0 doesn't get | |
255 // converted to +0.0 by doing an extraneous add with +0.0 | |
256 complex_t c1; | |
257 real_t r1; | |
258 real_t i1; | |
259 | |
260 complex_t c2; | |
261 real_t r2; | |
262 real_t i2; | |
263 | |
264 complex_t v; | |
265 int x; | |
266 | |
267 if (e1->type->isreal()) | |
268 { r1 = e1->toReal(); | |
269 x = 0; | |
270 } | |
271 else if (e1->type->isimaginary()) | |
272 { i1 = e1->toImaginary(); | |
273 x = 3; | |
274 } | |
275 else | |
276 { c1 = e1->toComplex(); | |
277 x = 6; | |
278 } | |
279 | |
280 if (e2->type->isreal()) | |
281 { r2 = e2->toReal(); | |
282 } | |
283 else if (e2->type->isimaginary()) | |
284 { i2 = e2->toImaginary(); | |
285 x += 1; | |
286 } | |
287 else | |
288 { c2 = e2->toComplex(); | |
289 x += 2; | |
290 } | |
291 | |
292 switch (x) | |
293 { | |
294 #if __DMC__ | |
295 case 0+0: v = (complex_t) (r1 - r2); break; | |
296 case 0+1: v = r1 - i2 * I; break; | |
297 case 0+2: v = r1 - c2; break; | |
298 case 3+0: v = i1 * I - r2; break; | |
299 case 3+1: v = (complex_t) ((i1 - i2) * I); break; | |
300 case 3+2: v = i1 * I - c2; break; | |
301 case 6+0: v = c1 - r2; break; | |
302 case 6+1: v = c1 - i2 * I; break; | |
303 case 6+2: v = c1 - c2; break; | |
304 #else | |
305 case 0+0: v = complex_t(r1 - r2, 0); break; | |
306 case 0+1: v = complex_t(r1, -i2); break; | |
307 case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break; | |
308 case 3+0: v = complex_t(-r2, i1); break; | |
309 case 3+1: v = complex_t(0, i1 - i2); break; | |
310 case 3+2: v = complex_t(-creall(c2), i1 - cimagl(c2)); break; | |
311 case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break; | |
312 case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break; | |
313 case 6+2: v = c1 - c2; break; | |
314 #endif | |
315 default: assert(0); | |
316 } | |
317 e = new ComplexExp(loc, v, type); | |
318 } | |
319 else if (e1->op == TOKsymoff) | |
320 { | |
321 SymOffExp *soe = (SymOffExp *)e1; | |
322 e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger()); | |
323 e->type = type; | |
324 } | |
325 else | |
326 { | |
327 e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type); | |
328 } | |
329 return e; | |
330 } | |
331 | |
332 Expression *Mul(Type *type, Expression *e1, Expression *e2) | |
333 { Expression *e; | |
334 Loc loc = e1->loc; | |
335 | |
336 if (type->isfloating()) | |
337 { complex_t c; | |
338 #ifdef IN_GCC | |
339 real_t r; | |
340 #else | |
341 d_float80 r; | |
342 #endif | |
343 | |
344 if (e1->type->isreal()) | |
345 { | |
346 #if __DMC__ | |
347 c = e1->toReal() * e2->toComplex(); | |
348 #else | |
349 r = e1->toReal(); | |
350 c = e2->toComplex(); | |
351 c = complex_t(r * creall(c), r * cimagl(c)); | |
352 #endif | |
353 } | |
354 else if (e1->type->isimaginary()) | |
355 { | |
356 #if __DMC__ | |
357 c = e1->toImaginary() * I * e2->toComplex(); | |
358 #else | |
359 r = e1->toImaginary(); | |
360 c = e2->toComplex(); | |
361 c = complex_t(-r * cimagl(c), r * creall(c)); | |
362 #endif | |
363 } | |
364 else if (e2->type->isreal()) | |
365 { | |
366 #if __DMC__ | |
367 c = e2->toReal() * e1->toComplex(); | |
368 #else | |
369 r = e2->toReal(); | |
370 c = e1->toComplex(); | |
371 c = complex_t(r * creall(c), r * cimagl(c)); | |
372 #endif | |
373 } | |
374 else if (e2->type->isimaginary()) | |
375 { | |
376 #if __DMC__ | |
377 c = e1->toComplex() * e2->toImaginary() * I; | |
378 #else | |
379 r = e2->toImaginary(); | |
380 c = e1->toComplex(); | |
381 c = complex_t(-r * cimagl(c), r * creall(c)); | |
382 #endif | |
383 } | |
384 else | |
385 c = e1->toComplex() * e2->toComplex(); | |
386 | |
387 if (type->isreal()) | |
388 e = new RealExp(loc, creall(c), type); | |
389 else if (type->isimaginary()) | |
390 e = new RealExp(loc, cimagl(c), type); | |
391 else if (type->iscomplex()) | |
392 e = new ComplexExp(loc, c, type); | |
393 else | |
394 assert(0); | |
395 } | |
396 else | |
397 { | |
398 e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type); | |
399 } | |
400 return e; | |
401 } | |
402 | |
403 Expression *Div(Type *type, Expression *e1, Expression *e2) | |
404 { Expression *e; | |
405 Loc loc = e1->loc; | |
406 | |
407 if (type->isfloating()) | |
408 { complex_t c; | |
409 #ifdef IN_GCC | |
410 real_t r; | |
411 #else | |
412 d_float80 r; | |
413 #endif | |
414 | |
415 //e1->type->print(); | |
416 //e2->type->print(); | |
417 if (e2->type->isreal()) | |
418 { | |
419 if (e1->type->isreal()) | |
420 { | |
421 e = new RealExp(loc, e1->toReal() / e2->toReal(), type); | |
422 return e; | |
423 } | |
424 #if __DMC__ | |
425 //r = e2->toReal(); | |
426 //c = e1->toComplex(); | |
427 //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r); | |
428 | |
429 c = e1->toComplex() / e2->toReal(); | |
430 #else | |
431 r = e2->toReal(); | |
432 c = e1->toComplex(); | |
433 c = complex_t(creall(c) / r, cimagl(c) / r); | |
434 #endif | |
435 } | |
436 else if (e2->type->isimaginary()) | |
437 { | |
438 #if __DMC__ | |
439 //r = e2->toImaginary(); | |
440 //c = e1->toComplex(); | |
441 //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r); | |
442 | |
443 c = e1->toComplex() / (e2->toImaginary() * I); | |
444 #else | |
445 r = e2->toImaginary(); | |
446 c = e1->toComplex(); | |
447 c = complex_t(cimagl(c) / r, -creall(c) / r); | |
448 #endif | |
449 } | |
450 else | |
451 { | |
452 c = e1->toComplex() / e2->toComplex(); | |
453 } | |
454 | |
455 if (type->isreal()) | |
456 e = new RealExp(loc, creall(c), type); | |
457 else if (type->isimaginary()) | |
458 e = new RealExp(loc, cimagl(c), type); | |
459 else if (type->iscomplex()) | |
460 e = new ComplexExp(loc, c, type); | |
461 else | |
462 assert(0); | |
463 } | |
464 else | |
465 { sinteger_t n1; | |
466 sinteger_t n2; | |
467 sinteger_t n; | |
468 | |
469 n1 = e1->toInteger(); | |
470 n2 = e2->toInteger(); | |
471 if (n2 == 0) | |
472 { e2->error("divide by 0"); | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
473 e2 = new IntegerExp(loc, 1, e2->type); |
336 | 474 n2 = 1; |
475 } | |
476 if (e1->type->isunsigned() || e2->type->isunsigned()) | |
477 n = ((d_uns64) n1) / ((d_uns64) n2); | |
478 else | |
479 n = n1 / n2; | |
480 e = new IntegerExp(loc, n, type); | |
481 } | |
482 return e; | |
483 } | |
484 | |
485 Expression *Mod(Type *type, Expression *e1, Expression *e2) | |
486 { Expression *e; | |
487 Loc loc = e1->loc; | |
488 | |
489 if (type->isfloating()) | |
490 { | |
491 complex_t c; | |
492 | |
493 if (e2->type->isreal()) | |
494 { real_t r2 = e2->toReal(); | |
495 | |
496 #ifdef __DMC__ | |
497 c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I; | |
498 #elif defined(IN_GCC) | |
499 c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2); | |
735
eee9efe5b51f
Attempt at getting LLVM to provide a proper target data layout. Should assert now if things are borked.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
734
diff
changeset
|
500 #elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__) || defined(__thumb__) |
734
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
501 // freebsd is kinda messed up. the STABLE branch doesn't support C99's fmodl !?! |
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
502 // arm also doesn't like fmodl |
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
503 c = complex_t(fmod(e1->toReal(), r2), fmod(e1->toImaginary(), r2)); |
336 | 504 #else |
505 c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2)); | |
506 #endif | |
507 } | |
508 else if (e2->type->isimaginary()) | |
509 { real_t i2 = e2->toImaginary(); | |
510 | |
511 #ifdef __DMC__ | |
512 c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I; | |
513 #elif defined(IN_GCC) | |
514 c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2); | |
735
eee9efe5b51f
Attempt at getting LLVM to provide a proper target data layout. Should assert now if things are borked.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
734
diff
changeset
|
515 #elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__) || defined(__thumb__) |
637
29dc68c949b0
Applied the FreeBSD patch from Ralith, closes ticket #95 , slightly changed but basically the same. Thanx Ralith :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
336
diff
changeset
|
516 // freebsd is kinda messed up. the STABLE branch doesn't support C99's fmodl !?! |
734
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
517 // arm also doesn't like fmodl |
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
518 c = complex_t(fmod(e1->toReal(), i2), fmod(e1->toImaginary(), i2)); |
336 | 519 #else |
520 c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2)); | |
521 #endif | |
522 } | |
523 else | |
524 assert(0); | |
525 | |
526 if (type->isreal()) | |
527 e = new RealExp(loc, creall(c), type); | |
528 else if (type->isimaginary()) | |
529 e = new RealExp(loc, cimagl(c), type); | |
530 else if (type->iscomplex()) | |
531 e = new ComplexExp(loc, c, type); | |
532 else | |
533 assert(0); | |
534 } | |
535 else | |
536 { sinteger_t n1; | |
537 sinteger_t n2; | |
538 sinteger_t n; | |
539 | |
540 n1 = e1->toInteger(); | |
541 n2 = e2->toInteger(); | |
542 if (n2 == 0) | |
543 { e2->error("divide by 0"); | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
544 e2 = new IntegerExp(loc, 1, e2->type); |
336 | 545 n2 = 1; |
546 } | |
547 if (e1->type->isunsigned() || e2->type->isunsigned()) | |
548 n = ((d_uns64) n1) % ((d_uns64) n2); | |
549 else | |
550 n = n1 % n2; | |
551 e = new IntegerExp(loc, n, type); | |
552 } | |
553 return e; | |
554 } | |
555 | |
556 Expression *Shl(Type *type, Expression *e1, Expression *e2) | |
557 { Expression *e; | |
558 Loc loc = e1->loc; | |
559 | |
560 e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type); | |
561 return e; | |
562 } | |
563 | |
564 Expression *Shr(Type *type, Expression *e1, Expression *e2) | |
565 { Expression *e; | |
566 Loc loc = e1->loc; | |
567 unsigned count; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
568 dinteger_t value; |
336 | 569 |
570 value = e1->toInteger(); | |
571 count = e2->toInteger(); | |
572 switch (e1->type->toBasetype()->ty) | |
573 { | |
574 case Tint8: | |
575 value = (d_int8)(value) >> count; | |
576 break; | |
577 | |
578 case Tuns8: | |
579 value = (d_uns8)(value) >> count; | |
580 break; | |
581 | |
582 case Tint16: | |
583 value = (d_int16)(value) >> count; | |
584 break; | |
585 | |
586 case Tuns16: | |
587 value = (d_uns16)(value) >> count; | |
588 break; | |
589 | |
590 case Tint32: | |
591 value = (d_int32)(value) >> count; | |
592 break; | |
593 | |
594 case Tuns32: | |
595 value = (d_uns32)(value) >> count; | |
596 break; | |
597 | |
598 case Tint64: | |
599 value = (d_int64)(value) >> count; | |
600 break; | |
601 | |
602 case Tuns64: | |
603 value = (d_uns64)(value) >> count; | |
604 break; | |
605 | |
606 default: | |
607 assert(0); | |
608 } | |
609 e = new IntegerExp(loc, value, type); | |
610 return e; | |
611 } | |
612 | |
613 Expression *Ushr(Type *type, Expression *e1, Expression *e2) | |
614 { Expression *e; | |
615 Loc loc = e1->loc; | |
616 unsigned count; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
617 dinteger_t value; |
336 | 618 |
619 value = e1->toInteger(); | |
620 count = e2->toInteger(); | |
621 switch (e1->type->toBasetype()->ty) | |
622 { | |
623 case Tint8: | |
624 case Tuns8: | |
625 assert(0); // no way to trigger this | |
626 value = (value & 0xFF) >> count; | |
627 break; | |
628 | |
629 case Tint16: | |
630 case Tuns16: | |
631 assert(0); // no way to trigger this | |
632 value = (value & 0xFFFF) >> count; | |
633 break; | |
634 | |
635 case Tint32: | |
636 case Tuns32: | |
637 value = (value & 0xFFFFFFFF) >> count; | |
638 break; | |
639 | |
640 case Tint64: | |
641 case Tuns64: | |
642 value = (d_uns64)(value) >> count; | |
643 break; | |
644 | |
645 default: | |
646 assert(0); | |
647 } | |
648 e = new IntegerExp(loc, value, type); | |
649 return e; | |
650 } | |
651 | |
652 Expression *And(Type *type, Expression *e1, Expression *e2) | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
653 { |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
654 Expression *e; |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
655 e = new IntegerExp(e1->loc, e1->toInteger() & e2->toInteger(), type); |
336 | 656 return e; |
657 } | |
658 | |
659 Expression *Or(Type *type, Expression *e1, Expression *e2) | |
660 { Expression *e; | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
661 e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type); |
336 | 662 return e; |
663 } | |
664 | |
665 Expression *Xor(Type *type, Expression *e1, Expression *e2) | |
666 { Expression *e; | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
667 e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type); |
336 | 668 return e; |
669 } | |
670 | |
671 /* Also returns EXP_CANT_INTERPRET if cannot be computed. | |
672 */ | |
673 Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) | |
674 { Expression *e; | |
675 Loc loc = e1->loc; | |
676 int cmp; | |
677 real_t r1; | |
678 real_t r2; | |
679 | |
680 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
681 | |
682 assert(op == TOKequal || op == TOKnotequal); | |
683 | |
684 if (e1->op == TOKnull) | |
685 { | |
686 if (e2->op == TOKnull) | |
687 cmp = 1; | |
688 else if (e2->op == TOKstring) | |
689 { StringExp *es2 = (StringExp *)e2; | |
690 cmp = (0 == es2->len); | |
691 } | |
692 else if (e2->op == TOKarrayliteral) | |
693 { ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
694 cmp = !es2->elements || (0 == es2->elements->dim); | |
695 } | |
696 else | |
697 return EXP_CANT_INTERPRET; | |
698 } | |
699 else if (e2->op == TOKnull) | |
700 { | |
701 if (e1->op == TOKstring) | |
702 { StringExp *es1 = (StringExp *)e1; | |
703 cmp = (0 == es1->len); | |
704 } | |
705 else if (e1->op == TOKarrayliteral) | |
706 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
707 cmp = !es1->elements || (0 == es1->elements->dim); | |
708 } | |
709 else | |
710 return EXP_CANT_INTERPRET; | |
711 } | |
712 else if (e1->op == TOKstring && e2->op == TOKstring) | |
713 { StringExp *es1 = (StringExp *)e1; | |
714 StringExp *es2 = (StringExp *)e2; | |
715 | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
716 if (es1->sz != es2->sz) |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
717 { |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
718 assert(global.errors); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
719 return EXP_CANT_INTERPRET; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
720 } |
336 | 721 if (es1->len == es2->len && |
722 memcmp(es1->string, es2->string, es1->sz * es1->len) == 0) | |
723 cmp = 1; | |
724 else | |
725 cmp = 0; | |
726 } | |
727 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral) | |
728 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
729 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
730 | |
731 if ((!es1->elements || !es1->elements->dim) && | |
732 (!es2->elements || !es2->elements->dim)) | |
733 cmp = 1; // both arrays are empty | |
734 else if (!es1->elements || !es2->elements) | |
735 cmp = 0; | |
736 else if (es1->elements->dim != es2->elements->dim) | |
737 cmp = 0; | |
738 else | |
739 { | |
740 for (size_t i = 0; i < es1->elements->dim; i++) | |
741 { Expression *ee1 = (Expression *)es1->elements->data[i]; | |
742 Expression *ee2 = (Expression *)es2->elements->data[i]; | |
743 | |
744 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); | |
745 if (v == EXP_CANT_INTERPRET) | |
746 return EXP_CANT_INTERPRET; | |
747 cmp = v->toInteger(); | |
748 if (cmp == 0) | |
749 break; | |
750 } | |
751 } | |
752 } | |
753 else if (e1->op == TOKarrayliteral && e2->op == TOKstring) | |
754 { // Swap operands and use common code | |
755 Expression *e = e1; | |
756 e1 = e2; | |
757 e2 = e; | |
758 goto Lsa; | |
759 } | |
760 else if (e1->op == TOKstring && e2->op == TOKarrayliteral) | |
761 { | |
762 Lsa: | |
763 StringExp *es1 = (StringExp *)e1; | |
764 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
765 size_t dim1 = es1->len; | |
766 size_t dim2 = es2->elements ? es2->elements->dim : 0; | |
767 if (dim1 != dim2) | |
768 cmp = 0; | |
769 else | |
770 { | |
771 for (size_t i = 0; i < dim1; i++) | |
772 { | |
773 uinteger_t c = es1->charAt(i); | |
774 Expression *ee2 = (Expression *)es2->elements->data[i]; | |
775 if (ee2->isConst() != 1) | |
776 return EXP_CANT_INTERPRET; | |
777 cmp = (c == ee2->toInteger()); | |
778 if (cmp == 0) | |
779 break; | |
780 } | |
781 } | |
782 } | |
783 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) | |
784 { StructLiteralExp *es1 = (StructLiteralExp *)e1; | |
785 StructLiteralExp *es2 = (StructLiteralExp *)e2; | |
786 | |
787 if (es1->sd != es2->sd) | |
788 cmp = 0; | |
789 else if ((!es1->elements || !es1->elements->dim) && | |
790 (!es2->elements || !es2->elements->dim)) | |
791 cmp = 1; // both arrays are empty | |
792 else if (!es1->elements || !es2->elements) | |
793 cmp = 0; | |
794 else if (es1->elements->dim != es2->elements->dim) | |
795 cmp = 0; | |
796 else | |
797 { | |
798 cmp = 1; | |
799 for (size_t i = 0; i < es1->elements->dim; i++) | |
800 { Expression *ee1 = (Expression *)es1->elements->data[i]; | |
801 Expression *ee2 = (Expression *)es2->elements->data[i]; | |
802 | |
803 if (ee1 == ee2) | |
804 continue; | |
805 if (!ee1 || !ee2) | |
806 { cmp = 0; | |
807 break; | |
808 } | |
809 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); | |
810 if (v == EXP_CANT_INTERPRET) | |
811 return EXP_CANT_INTERPRET; | |
812 cmp = v->toInteger(); | |
813 if (cmp == 0) | |
814 break; | |
815 } | |
816 } | |
817 } | |
818 #if 0 // Should handle this | |
819 else if (e1->op == TOKarrayliteral && e2->op == TOKstring) | |
820 { | |
821 } | |
822 #endif | |
823 else if (e1->isConst() != 1 || e2->isConst() != 1) | |
824 return EXP_CANT_INTERPRET; | |
825 else if (e1->type->isreal()) | |
826 { | |
827 r1 = e1->toReal(); | |
828 r2 = e2->toReal(); | |
829 goto L1; | |
830 } | |
831 else if (e1->type->isimaginary()) | |
832 { | |
833 r1 = e1->toImaginary(); | |
834 r2 = e2->toImaginary(); | |
835 L1: | |
836 #if __DMC__ | |
837 cmp = (r1 == r2); | |
838 #else | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
839 if (Port::isNan(r1) || Port::isNan(r2)) // if unordered |
336 | 840 { |
841 cmp = 0; | |
842 } | |
843 else | |
844 { | |
845 cmp = (r1 == r2); | |
846 } | |
847 #endif | |
848 } | |
849 else if (e1->type->iscomplex()) | |
850 { | |
851 cmp = e1->toComplex() == e2->toComplex(); | |
852 } | |
1587 | 853 else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer) |
336 | 854 { |
855 cmp = (e1->toInteger() == e2->toInteger()); | |
856 } | |
857 else | |
858 return EXP_CANT_INTERPRET; | |
859 if (op == TOKnotequal) | |
860 cmp ^= 1; | |
861 e = new IntegerExp(loc, cmp, type); | |
862 return e; | |
863 } | |
864 | |
865 Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) | |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
866 { |
336 | 867 Loc loc = e1->loc; |
868 int cmp; | |
869 | |
1587 | 870 if (e1->op == TOKnull) |
336 | 871 { |
1587 | 872 cmp = (e2->op == TOKnull); |
873 } | |
874 else if (e2->op == TOKnull) | |
875 { | |
876 cmp = 0; | |
336 | 877 } |
878 else if (e1->op == TOKsymoff && e2->op == TOKsymoff) | |
879 { | |
880 SymOffExp *es1 = (SymOffExp *)e1; | |
881 SymOffExp *es2 = (SymOffExp *)e2; | |
882 | |
883 cmp = (es1->var == es2->var && es1->offset == es2->offset); | |
884 } | |
885 else if (e1->isConst() == 1 && e2->isConst() == 1) | |
886 return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, | |
887 type, e1, e2); | |
888 else | |
889 assert(0); | |
890 if (op == TOKnotidentity) | |
891 cmp ^= 1; | |
892 return new IntegerExp(loc, cmp, type); | |
893 } | |
894 | |
895 | |
896 Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) | |
897 { Expression *e; | |
898 Loc loc = e1->loc; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
899 dinteger_t n; |
336 | 900 real_t r1; |
901 real_t r2; | |
902 | |
903 if (e1->type->isreal()) | |
904 { | |
905 r1 = e1->toReal(); | |
906 r2 = e2->toReal(); | |
907 goto L1; | |
908 } | |
909 else if (e1->type->isimaginary()) | |
910 { | |
911 r1 = e1->toImaginary(); | |
912 r2 = e2->toImaginary(); | |
913 L1: | |
914 #if __DMC__ | |
915 // DMC is the only compiler I know of that handles NAN arguments | |
916 // correctly in comparisons. | |
917 switch (op) | |
918 { | |
919 case TOKlt: n = r1 < r2; break; | |
920 case TOKle: n = r1 <= r2; break; | |
921 case TOKgt: n = r1 > r2; break; | |
922 case TOKge: n = r1 >= r2; break; | |
923 | |
924 case TOKleg: n = r1 <>= r2; break; | |
925 case TOKlg: n = r1 <> r2; break; | |
926 case TOKunord: n = r1 !<>= r2; break; | |
927 case TOKue: n = r1 !<> r2; break; | |
928 case TOKug: n = r1 !<= r2; break; | |
929 case TOKuge: n = r1 !< r2; break; | |
930 case TOKul: n = r1 !>= r2; break; | |
931 case TOKule: n = r1 !> r2; break; | |
932 | |
933 default: | |
934 assert(0); | |
935 } | |
936 #else | |
937 // Don't rely on compiler, handle NAN arguments separately | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
938 if (Port::isNan(r1) || Port::isNan(r2)) // if unordered |
336 | 939 { |
940 switch (op) | |
941 { | |
942 case TOKlt: n = 0; break; | |
943 case TOKle: n = 0; break; | |
944 case TOKgt: n = 0; break; | |
945 case TOKge: n = 0; break; | |
946 | |
947 case TOKleg: n = 0; break; | |
948 case TOKlg: n = 0; break; | |
949 case TOKunord: n = 1; break; | |
950 case TOKue: n = 1; break; | |
951 case TOKug: n = 1; break; | |
952 case TOKuge: n = 1; break; | |
953 case TOKul: n = 1; break; | |
954 case TOKule: n = 1; break; | |
955 | |
956 default: | |
957 assert(0); | |
958 } | |
959 } | |
960 else | |
961 { | |
962 switch (op) | |
963 { | |
964 case TOKlt: n = r1 < r2; break; | |
965 case TOKle: n = r1 <= r2; break; | |
966 case TOKgt: n = r1 > r2; break; | |
967 case TOKge: n = r1 >= r2; break; | |
968 | |
969 case TOKleg: n = 1; break; | |
970 case TOKlg: n = r1 != r2; break; | |
971 case TOKunord: n = 0; break; | |
972 case TOKue: n = r1 == r2; break; | |
973 case TOKug: n = r1 > r2; break; | |
974 case TOKuge: n = r1 >= r2; break; | |
975 case TOKul: n = r1 < r2; break; | |
976 case TOKule: n = r1 <= r2; break; | |
977 | |
978 default: | |
979 assert(0); | |
980 } | |
981 } | |
982 #endif | |
983 } | |
984 else if (e1->type->iscomplex()) | |
985 { | |
986 assert(0); | |
987 } | |
988 else | |
989 { sinteger_t n1; | |
990 sinteger_t n2; | |
991 | |
992 n1 = e1->toInteger(); | |
993 n2 = e2->toInteger(); | |
994 if (e1->type->isunsigned() || e2->type->isunsigned()) | |
995 { | |
996 switch (op) | |
997 { | |
998 case TOKlt: n = ((d_uns64) n1) < ((d_uns64) n2); break; | |
999 case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2); break; | |
1000 case TOKgt: n = ((d_uns64) n1) > ((d_uns64) n2); break; | |
1001 case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2); break; | |
1002 | |
1003 case TOKleg: n = 1; break; | |
1004 case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2); break; | |
1005 case TOKunord: n = 0; break; | |
1006 case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2); break; | |
1007 case TOKug: n = ((d_uns64) n1) > ((d_uns64) n2); break; | |
1008 case TOKuge: n = ((d_uns64) n1) >= ((d_uns64) n2); break; | |
1009 case TOKul: n = ((d_uns64) n1) < ((d_uns64) n2); break; | |
1010 case TOKule: n = ((d_uns64) n1) <= ((d_uns64) n2); break; | |
1011 | |
1012 default: | |
1013 assert(0); | |
1014 } | |
1015 } | |
1016 else | |
1017 { | |
1018 switch (op) | |
1019 { | |
1020 case TOKlt: n = n1 < n2; break; | |
1021 case TOKle: n = n1 <= n2; break; | |
1022 case TOKgt: n = n1 > n2; break; | |
1023 case TOKge: n = n1 >= n2; break; | |
1024 | |
1025 case TOKleg: n = 1; break; | |
1026 case TOKlg: n = n1 != n2; break; | |
1027 case TOKunord: n = 0; break; | |
1028 case TOKue: n = n1 == n2; break; | |
1029 case TOKug: n = n1 > n2; break; | |
1030 case TOKuge: n = n1 >= n2; break; | |
1031 case TOKul: n = n1 < n2; break; | |
1032 case TOKule: n = n1 <= n2; break; | |
1033 | |
1034 default: | |
1035 assert(0); | |
1036 } | |
1037 } | |
1038 } | |
1039 e = new IntegerExp(loc, n, type); | |
1040 return e; | |
1041 } | |
1042 | |
1043 /* Also returns EXP_CANT_INTERPRET if cannot be computed. | |
1044 * to: type to cast to | |
1045 * type: type to paint the result | |
1046 */ | |
1047 | |
1048 Expression *Cast(Type *type, Type *to, Expression *e1) | |
1049 { Expression *e = EXP_CANT_INTERPRET; | |
1050 Loc loc = e1->loc; | |
1051 | |
1052 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); | |
1053 //printf("e1->type = %s\n", e1->type->toChars()); | |
1054 if (type->equals(e1->type) && to->equals(type)) | |
1055 return e1; | |
1056 | |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1057 Type *tb = to->toBasetype(); |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1058 Type *typeb = type->toBasetype(); |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1059 |
1587 | 1060 /* Allow casting from one string type to another |
1061 */ | |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1062 if (e1->op == TOKstring) |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1063 { |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1064 if (tb->ty == Tarray && typeb->ty == Tarray && |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1065 tb->nextOf()->size() == typeb->nextOf()->size()) |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1066 { |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1067 return expType(to, e1); |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1068 } |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1069 } |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1070 |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1071 if (e1->op == TOKarrayliteral && typeb == tb) |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1072 { |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1073 return e1; |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1074 } |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1075 |
336 | 1076 if (e1->isConst() != 1) |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1077 { |
336 | 1078 return EXP_CANT_INTERPRET; |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1079 } |
336 | 1080 |
1081 if (tb->ty == Tbool) | |
1082 e = new IntegerExp(loc, e1->toInteger() != 0, type); | |
1083 else if (type->isintegral()) | |
1084 { | |
1085 if (e1->type->isfloating()) | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1086 { dinteger_t result; |
336 | 1087 real_t r = e1->toReal(); |
1088 | |
1587 | 1089 switch (type->toBasetype()->ty) |
336 | 1090 { |
1091 case Tint8: result = (d_int8)r; break; | |
1092 case Tchar: | |
1093 case Tuns8: result = (d_uns8)r; break; | |
1094 case Tint16: result = (d_int16)r; break; | |
1095 case Twchar: | |
1096 case Tuns16: result = (d_uns16)r; break; | |
1097 case Tint32: result = (d_int32)r; break; | |
1098 case Tdchar: | |
1099 case Tuns32: result = (d_uns32)r; break; | |
1100 case Tint64: result = (d_int64)r; break; | |
1101 case Tuns64: result = (d_uns64)r; break; | |
1102 default: | |
1103 assert(0); | |
1104 } | |
1105 | |
1106 e = new IntegerExp(loc, result, type); | |
1107 } | |
1108 else if (type->isunsigned()) | |
1109 e = new IntegerExp(loc, e1->toUInteger(), type); | |
1110 else | |
1111 e = new IntegerExp(loc, e1->toInteger(), type); | |
1112 } | |
1113 else if (tb->isreal()) | |
1114 { real_t value = e1->toReal(); | |
1115 | |
1116 e = new RealExp(loc, value, type); | |
1117 } | |
1118 else if (tb->isimaginary()) | |
1119 { real_t value = e1->toImaginary(); | |
1120 | |
1121 e = new RealExp(loc, value, type); | |
1122 } | |
1123 else if (tb->iscomplex()) | |
1124 { complex_t value = e1->toComplex(); | |
1125 | |
1126 e = new ComplexExp(loc, value, type); | |
1127 } | |
1128 else if (tb->isscalar()) | |
1129 e = new IntegerExp(loc, e1->toInteger(), type); | |
1130 else if (tb->ty == Tvoid) | |
1131 e = EXP_CANT_INTERPRET; | |
1132 else if (tb->ty == Tstruct && e1->op == TOKint64) | |
1133 { // Struct = 0; | |
1134 StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration(); | |
1135 assert(sd); | |
1136 Expressions *elements = new Expressions; | |
1137 for (size_t i = 0; i < sd->fields.dim; i++) | |
1138 { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; | |
1139 VarDeclaration *v = s->isVarDeclaration(); | |
1140 assert(v); | |
1141 | |
1142 Expression *exp = new IntegerExp(0); | |
1143 exp = Cast(v->type, v->type, exp); | |
1144 if (exp == EXP_CANT_INTERPRET) | |
1145 return exp; | |
1146 elements->push(exp); | |
1147 } | |
1148 e = new StructLiteralExp(loc, sd, elements); | |
1149 e->type = type; | |
1150 } | |
1151 else | |
1152 { | |
1153 error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars()); | |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1154 e = new IntegerExp(loc, 0, Type::tint32); |
336 | 1155 } |
1156 return e; | |
1157 } | |
1158 | |
1159 | |
1160 Expression *ArrayLength(Type *type, Expression *e1) | |
1161 { Expression *e; | |
1162 Loc loc = e1->loc; | |
1163 | |
1164 if (e1->op == TOKstring) | |
1165 { StringExp *es1 = (StringExp *)e1; | |
1166 | |
1167 e = new IntegerExp(loc, es1->len, type); | |
1168 } | |
1169 else if (e1->op == TOKarrayliteral) | |
1170 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; | |
1171 size_t dim; | |
1172 | |
1173 dim = ale->elements ? ale->elements->dim : 0; | |
1174 e = new IntegerExp(loc, dim, type); | |
1175 } | |
1176 else if (e1->op == TOKassocarrayliteral) | |
1177 { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1; | |
1178 size_t dim = ale->keys->dim; | |
1179 | |
1180 e = new IntegerExp(loc, dim, type); | |
1181 } | |
1182 else | |
1183 e = EXP_CANT_INTERPRET; | |
1184 return e; | |
1185 } | |
1186 | |
1187 /* Also return EXP_CANT_INTERPRET if this fails | |
1188 */ | |
1189 Expression *Index(Type *type, Expression *e1, Expression *e2) | |
1190 { Expression *e = EXP_CANT_INTERPRET; | |
1191 Loc loc = e1->loc; | |
1192 | |
1193 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
1194 assert(e1->type); | |
1195 if (e1->op == TOKstring && e2->op == TOKint64) | |
1196 { StringExp *es1 = (StringExp *)e1; | |
1197 uinteger_t i = e2->toInteger(); | |
1198 | |
1199 if (i >= es1->len) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1200 e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len); |
336 | 1201 else |
1202 { unsigned value = es1->charAt(i); | |
1203 e = new IntegerExp(loc, value, type); | |
1204 } | |
1205 } | |
1206 else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64) | |
1207 { TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype(); | |
1208 uinteger_t length = tsa->dim->toInteger(); | |
1209 uinteger_t i = e2->toInteger(); | |
1210 | |
1211 if (i >= length) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1212 { e2->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length); |
336 | 1213 } |
1214 else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) | |
1215 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; | |
1216 e = (Expression *)ale->elements->data[i]; | |
1217 e->type = type; | |
1218 } | |
1219 } | |
1220 else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64) | |
1221 { | |
1222 uinteger_t i = e2->toInteger(); | |
1223 | |
1224 if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) | |
1225 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; | |
1226 if (i >= ale->elements->dim) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1227 { e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); |
336 | 1228 } |
1229 else | |
1230 { e = (Expression *)ale->elements->data[i]; | |
1231 e->type = type; | |
1232 } | |
1233 } | |
1234 } | |
1235 else if (e1->op == TOKassocarrayliteral && !e1->checkSideEffect(2)) | |
1236 { | |
1237 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1; | |
1238 /* Search the keys backwards, in case there are duplicate keys | |
1239 */ | |
1240 for (size_t i = ae->keys->dim; i;) | |
1241 { | |
1242 i--; | |
1243 Expression *ekey = (Expression *)ae->keys->data[i]; | |
1244 Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); | |
1245 if (ex == EXP_CANT_INTERPRET) | |
1246 return ex; | |
1247 if (ex->isBool(TRUE)) | |
1248 { e = (Expression *)ae->values->data[i]; | |
1249 e->type = type; | |
1250 break; | |
1251 } | |
1252 } | |
1253 } | |
1254 return e; | |
1255 } | |
1256 | |
1257 /* Also return EXP_CANT_INTERPRET if this fails | |
1258 */ | |
1259 Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) | |
1260 { Expression *e = EXP_CANT_INTERPRET; | |
1261 Loc loc = e1->loc; | |
1262 | |
1263 #if LOG | |
1264 printf("Slice()\n"); | |
1265 if (lwr) | |
1266 { printf("\te1 = %s\n", e1->toChars()); | |
1267 printf("\tlwr = %s\n", lwr->toChars()); | |
1268 printf("\tupr = %s\n", upr->toChars()); | |
1269 } | |
1270 #endif | |
1271 if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64) | |
1272 { StringExp *es1 = (StringExp *)e1; | |
1273 uinteger_t ilwr = lwr->toInteger(); | |
1274 uinteger_t iupr = upr->toInteger(); | |
1275 | |
1276 if (iupr > es1->len || ilwr > iupr) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1277 e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); |
336 | 1278 else |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1279 { dinteger_t value; |
336 | 1280 void *s; |
1281 size_t len = iupr - ilwr; | |
1282 int sz = es1->sz; | |
1283 StringExp *es; | |
1284 | |
1285 s = mem.malloc((len + 1) * sz); | |
1286 memcpy((unsigned char *)s, (unsigned char *)es1->string + ilwr * sz, len * sz); | |
1287 memset((unsigned char *)s + len * sz, 0, sz); | |
1288 | |
1289 es = new StringExp(loc, s, len, es1->postfix); | |
1290 es->sz = sz; | |
1291 es->committed = 1; | |
1292 es->type = type; | |
1293 e = es; | |
1294 } | |
1295 } | |
1296 else if (e1->op == TOKarrayliteral && | |
1297 lwr->op == TOKint64 && upr->op == TOKint64 && | |
1298 !e1->checkSideEffect(2)) | |
1299 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
1300 uinteger_t ilwr = lwr->toInteger(); | |
1301 uinteger_t iupr = upr->toInteger(); | |
1302 | |
1303 if (iupr > es1->elements->dim || ilwr > iupr) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1304 e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); |
336 | 1305 else |
1306 { | |
1307 Expressions *elements = new Expressions(); | |
1308 elements->setDim(iupr - ilwr); | |
1309 memcpy(elements->data, | |
1310 es1->elements->data + ilwr, | |
1311 (iupr - ilwr) * sizeof(es1->elements->data[0])); | |
1312 e = new ArrayLiteralExp(e1->loc, elements); | |
1313 e->type = type; | |
1314 } | |
1315 } | |
1316 return e; | |
1317 } | |
1318 | |
1319 /* Also return EXP_CANT_INTERPRET if this fails | |
1320 */ | |
1321 Expression *Cat(Type *type, Expression *e1, Expression *e2) | |
1322 { Expression *e = EXP_CANT_INTERPRET; | |
1323 Loc loc = e1->loc; | |
1324 Type *t; | |
717
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1325 Type *t1 = e1->type->toBasetype(); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1326 Type *t2 = e2->type->toBasetype(); |
336 | 1327 |
1328 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
1329 //printf("\tt1 = %s, t2 = %s\n", t1->toChars(), t2->toChars()); |
336 | 1330 |
1331 if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) | |
1332 { e = e2; | |
1333 goto L2; | |
1334 } | |
1335 else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull) | |
1336 { e = e1; | |
1337 L2: | |
1338 Type *tn = e->type->toBasetype(); | |
1339 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) | |
1340 { | |
1341 // Create a StringExp | |
1342 void *s; | |
1343 StringExp *es; | |
1344 size_t len = 1; | |
1345 int sz = tn->size(); | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1346 dinteger_t v = e->toInteger(); |
336 | 1347 |
1348 s = mem.malloc((len + 1) * sz); | |
1349 memcpy((unsigned char *)s, &v, sz); | |
1350 | |
1351 // Add terminating 0 | |
1352 memset((unsigned char *)s + len * sz, 0, sz); | |
1353 | |
1354 es = new StringExp(loc, s, len); | |
1355 es->sz = sz; | |
1356 es->committed = 1; | |
1357 e = es; | |
1358 } | |
1359 else | |
1360 { // Create an ArrayLiteralExp | |
1361 Expressions *elements = new Expressions(); | |
1362 elements->push(e); | |
1363 e = new ArrayLiteralExp(e->loc, elements); | |
1364 } | |
1365 e->type = type; | |
1366 return e; | |
1367 } | |
1368 else if (e1->op == TOKstring && e2->op == TOKstring) | |
1369 { | |
1370 // Concatenate the strings | |
1371 void *s; | |
1372 StringExp *es1 = (StringExp *)e1; | |
1373 StringExp *es2 = (StringExp *)e2; | |
1374 StringExp *es; | |
1375 Type *t; | |
1376 size_t len = es1->len + es2->len; | |
1377 int sz = es1->sz; | |
1378 | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1379 if (sz != es2->sz) |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1380 { |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1381 /* Can happen with: |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1382 * auto s = "foo"d ~ "bar"c; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1383 */ |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1384 assert(global.errors); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1385 return e; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1386 } |
336 | 1387 s = mem.malloc((len + 1) * sz); |
1388 memcpy(s, es1->string, es1->len * sz); | |
1389 memcpy((unsigned char *)s + es1->len * sz, es2->string, es2->len * sz); | |
1390 | |
1391 // Add terminating 0 | |
1392 memset((unsigned char *)s + len * sz, 0, sz); | |
1393 | |
1394 es = new StringExp(loc, s, len); | |
1395 es->sz = sz; | |
1396 es->committed = es1->committed | es2->committed; | |
1397 if (es1->committed) | |
1398 t = es1->type; | |
1399 else | |
1400 t = es2->type; | |
1401 es->type = type; | |
1402 e = es; | |
1403 } | |
1404 else if (e1->op == TOKstring && e2->op == TOKint64) | |
1405 { | |
1406 // Concatenate the strings | |
1407 void *s; | |
1408 StringExp *es1 = (StringExp *)e1; | |
1409 StringExp *es; | |
1410 Type *t; | |
1411 size_t len = es1->len + 1; | |
1412 int sz = es1->sz; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1413 dinteger_t v = e2->toInteger(); |
336 | 1414 |
1415 s = mem.malloc((len + 1) * sz); | |
1416 memcpy(s, es1->string, es1->len * sz); | |
1417 memcpy((unsigned char *)s + es1->len * sz, &v, sz); | |
1418 | |
1419 // Add terminating 0 | |
1420 memset((unsigned char *)s + len * sz, 0, sz); | |
1421 | |
1422 es = new StringExp(loc, s, len); | |
1423 es->sz = sz; | |
1424 es->committed = es1->committed; | |
1425 t = es1->type; | |
1426 es->type = type; | |
1427 e = es; | |
1428 } | |
1429 else if (e1->op == TOKint64 && e2->op == TOKstring) | |
1430 { | |
1431 // Concatenate the strings | |
1432 void *s; | |
1433 StringExp *es2 = (StringExp *)e2; | |
1434 StringExp *es; | |
1435 Type *t; | |
1436 size_t len = 1 + es2->len; | |
1437 int sz = es2->sz; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1438 dinteger_t v = e1->toInteger(); |
336 | 1439 |
1440 s = mem.malloc((len + 1) * sz); | |
1441 memcpy((unsigned char *)s, &v, sz); | |
1442 memcpy((unsigned char *)s + sz, es2->string, es2->len * sz); | |
1443 | |
1444 // Add terminating 0 | |
1445 memset((unsigned char *)s + len * sz, 0, sz); | |
1446 | |
1447 es = new StringExp(loc, s, len); | |
1448 es->sz = sz; | |
1449 es->committed = es2->committed; | |
1450 t = es2->type; | |
1451 es->type = type; | |
1452 e = es; | |
1453 } | |
1454 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && | |
1455 e1->type->equals(e2->type)) | |
1456 { | |
1457 // Concatenate the arrays | |
1458 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
1459 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
1460 | |
1461 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); | |
1462 es1->elements->insert(es1->elements->dim, es2->elements); | |
1463 e = es1; | |
1464 | |
1465 if (type->toBasetype()->ty == Tsarray) | |
1466 { | |
1467 e->type = new TypeSArray(e1->type->toBasetype()->next, new IntegerExp(0, es1->elements->dim, Type::tindex)); | |
1468 e->type = e->type->semantic(loc, NULL); | |
1469 } | |
1470 else | |
1471 e->type = type; | |
1472 } | |
717
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1473 else if (e1->op == TOKarrayliteral && e2->op == TOKnull && |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1474 t1->nextOf()->equals(t2->nextOf())) |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1475 { |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1476 e = e1; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1477 goto L3; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1478 } |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1479 else if (e1->op == TOKnull && e2->op == TOKarrayliteral && |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1480 t1->nextOf()->equals(t2->nextOf())) |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1481 { |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1482 e = e2; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1483 L3: |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1484 // Concatenate the array with null |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1485 ArrayLiteralExp *es = (ArrayLiteralExp *)e; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1486 |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1487 es = new ArrayLiteralExp(es->loc, (Expressions *)es->elements->copy()); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1488 e = es; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1489 |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1490 if (type->toBasetype()->ty == Tsarray) |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1491 { |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1492 e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es->elements->dim, Type::tindex)); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1493 e->type = e->type->semantic(loc, NULL); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1494 } |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1495 else |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1496 e->type = type; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1497 } |
336 | 1498 else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) && |
1499 e1->type->toBasetype()->nextOf()->equals(e2->type)) | |
1500 { | |
1501 ArrayLiteralExp *es1; | |
1502 if (e1->op == TOKarrayliteral) | |
1503 { es1 = (ArrayLiteralExp *)e1; | |
1504 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); | |
1505 es1->elements->push(e2); | |
1506 } | |
1507 else | |
1508 { | |
1509 es1 = new ArrayLiteralExp(e1->loc, e2); | |
1510 } | |
1511 e = es1; | |
1512 | |
1513 if (type->toBasetype()->ty == Tsarray) | |
1514 { | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
1515 e->type = new TypeSArray(e2->type, new IntegerExp(loc, es1->elements->dim, Type::tindex)); |
336 | 1516 e->type = e->type->semantic(loc, NULL); |
1517 } | |
1518 else | |
1519 e->type = type; | |
1520 } | |
1521 else if (e2->op == TOKarrayliteral && | |
1522 e2->type->toBasetype()->nextOf()->equals(e1->type)) | |
1523 { | |
1524 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
1525 | |
1526 es2 = new ArrayLiteralExp(es2->loc, (Expressions *)es2->elements->copy()); | |
1527 es2->elements->shift(e1); | |
1528 e = es2; | |
1529 | |
1530 if (type->toBasetype()->ty == Tsarray) | |
1531 { | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
1532 e->type = new TypeSArray(e1->type, new IntegerExp(loc, es2->elements->dim, Type::tindex)); |
336 | 1533 e->type = e->type->semantic(loc, NULL); |
1534 } | |
1535 else | |
1536 e->type = type; | |
1537 } | |
1538 else if (e1->op == TOKnull && e2->op == TOKstring) | |
1539 { | |
1540 t = e1->type; | |
1541 e = e2; | |
1542 goto L1; | |
1543 } | |
1544 else if (e1->op == TOKstring && e2->op == TOKnull) | |
1545 { e = e1; | |
1546 t = e2->type; | |
1547 L1: | |
1548 Type *tb = t->toBasetype(); | |
1549 if (tb->ty == Tarray && tb->nextOf()->equals(e->type)) | |
1550 { Expressions *expressions = new Expressions(); | |
1551 expressions->push(e); | |
1552 e = new ArrayLiteralExp(loc, expressions); | |
1553 e->type = t; | |
1554 } | |
1555 if (!e->type->equals(type)) | |
1556 { StringExp *se = (StringExp *)e->copy(); | |
1557 e = se->castTo(NULL, type); | |
1558 } | |
1559 } | |
1560 return e; | |
1561 } | |
1562 | |
1563 Expression *Ptr(Type *type, Expression *e1) | |
1564 { | |
1565 //printf("Ptr(e1 = %s)\n", e1->toChars()); | |
1566 if (e1->op == TOKadd) | |
1567 { AddExp *ae = (AddExp *)e1; | |
1568 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) | |
1569 { AddrExp *ade = (AddrExp *)ae->e1; | |
1570 if (ade->e1->op == TOKstructliteral) | |
1571 { StructLiteralExp *se = (StructLiteralExp *)ade->e1; | |
1572 unsigned offset = ae->e2->toInteger(); | |
1573 Expression *e = se->getField(type, offset); | |
1574 if (!e) | |
1575 e = EXP_CANT_INTERPRET; | |
1576 return e; | |
1577 } | |
1578 } | |
1579 } | |
1580 return EXP_CANT_INTERPRET; | |
1581 } | |
1582 |