comparison dmd/constfold.c @ 1:c53b6e3fe49a trunk

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