Fixed some lexing problems with DOS line-endings
[delight/core.git] / dmd / constfold.c
blobfc6ab23b5947b419dd553caefcceb721af6dbea7
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.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, September 2004
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <assert.h>
20 #include <math.h>
22 #if __DMC__
23 #include <complex.h>
24 #endif
26 #include "mem.h"
27 #include "root.h"
29 #include "mtype.h"
30 #include "expression.h"
31 #include "aggregate.h"
32 #include "declaration.h"
34 #ifdef IN_GCC
35 #include "d-gcc-real.h"
36 #endif
38 static real_t zero; // work around DMC bug for now
40 #define LOG 0
42 Expression *expType(Type *type, Expression *e)
44 if (type != e->type)
46 e = e->copy();
47 e->type = type;
49 return e;
52 /* ================================== isConst() ============================== */
54 int Expression::isConst()
56 //printf("Expression::isConst(): %s\n", toChars());
57 return 0;
60 int IntegerExp::isConst()
62 return 1;
65 int RealExp::isConst()
67 return 1;
70 int ComplexExp::isConst()
72 return 1;
75 int SymOffExp::isConst()
77 return 2;
80 /* =============================== constFold() ============================== */
82 /* The constFold() functions were redundant with the optimize() ones,
83 * and so have been folded in with them.
86 /* ========================================================================== */
88 Expression *Neg(Type *type, Expression *e1)
89 { Expression *e;
90 Loc loc = e1->loc;
92 if (e1->type->isreal())
94 e = new RealExp(loc, -e1->toReal(), type);
96 else if (e1->type->isimaginary())
98 e = new RealExp(loc, -e1->toImaginary(), type);
100 else if (e1->type->iscomplex())
102 e = new ComplexExp(loc, -e1->toComplex(), type);
104 else
105 e = new IntegerExp(loc, -e1->toInteger(), type);
106 return e;
109 Expression *Com(Type *type, Expression *e1)
110 { Expression *e;
111 Loc loc = e1->loc;
113 e = new IntegerExp(loc, ~e1->toInteger(), type);
114 return e;
117 Expression *Not(Type *type, Expression *e1)
118 { Expression *e;
119 Loc loc = e1->loc;
121 e = new IntegerExp(loc, e1->isBool(0), type);
122 return e;
125 Expression *Bool(Type *type, Expression *e1)
126 { Expression *e;
127 Loc loc = e1->loc;
129 e = new IntegerExp(loc, e1->isBool(1), type);
130 return e;
133 Expression *Add(Type *type, Expression *e1, Expression *e2)
134 { Expression *e;
135 Loc loc = e1->loc;
137 #if LOG
138 printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
139 #endif
140 if (type->isreal())
142 e = new RealExp(loc, e1->toReal() + e2->toReal(), type);
144 else if (type->isimaginary())
146 e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type);
148 else if (type->iscomplex())
150 // This rigamarole is necessary so that -0.0 doesn't get
151 // converted to +0.0 by doing an extraneous add with +0.0
152 complex_t c1;
153 real_t r1;
154 real_t i1;
156 complex_t c2;
157 real_t r2;
158 real_t i2;
160 complex_t v;
161 int x;
163 if (e1->type->isreal())
164 { r1 = e1->toReal();
165 x = 0;
167 else if (e1->type->isimaginary())
168 { i1 = e1->toImaginary();
169 x = 3;
171 else
172 { c1 = e1->toComplex();
173 x = 6;
176 if (e2->type->isreal())
177 { r2 = e2->toReal();
179 else if (e2->type->isimaginary())
180 { i2 = e2->toImaginary();
181 x += 1;
183 else
184 { c2 = e2->toComplex();
185 x += 2;
188 switch (x)
190 #if __DMC__
191 case 0+0: v = (complex_t) (r1 + r2); break;
192 case 0+1: v = r1 + i2 * I; break;
193 case 0+2: v = r1 + c2; break;
194 case 3+0: v = i1 * I + r2; break;
195 case 3+1: v = (complex_t) ((i1 + i2) * I); break;
196 case 3+2: v = i1 * I + c2; break;
197 case 6+0: v = c1 + r2; break;
198 case 6+1: v = c1 + i2 * I; break;
199 case 6+2: v = c1 + c2; break;
200 #else
201 case 0+0: v = complex_t(r1 + r2, 0); break;
202 case 0+1: v = complex_t(r1, i2); break;
203 case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break;
204 case 3+0: v = complex_t(r2, i1); break;
205 case 3+1: v = complex_t(0, i1 + i2); break;
206 case 3+2: v = complex_t(creall(c2), i1 + cimagl(c2)); break;
207 case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break;
208 case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break;
209 case 6+2: v = c1 + c2; break;
210 #endif
211 default: assert(0);
213 e = new ComplexExp(loc, v, type);
215 else if (e1->op == TOKsymoff)
217 SymOffExp *soe = (SymOffExp *)e1;
218 e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger());
219 e->type = type;
221 else if (e2->op == TOKsymoff)
223 SymOffExp *soe = (SymOffExp *)e2;
224 e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger());
225 e->type = type;
227 else
228 e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type);
229 return e;
233 Expression *Min(Type *type, Expression *e1, Expression *e2)
234 { Expression *e;
235 Loc loc = e1->loc;
237 if (type->isreal())
239 e = new RealExp(loc, e1->toReal() - e2->toReal(), type);
241 else if (type->isimaginary())
243 e = new RealExp(loc, e1->toImaginary() - e2->toImaginary(), type);
245 else if (type->iscomplex())
247 // This rigamarole is necessary so that -0.0 doesn't get
248 // converted to +0.0 by doing an extraneous add with +0.0
249 complex_t c1;
250 real_t r1;
251 real_t i1;
253 complex_t c2;
254 real_t r2;
255 real_t i2;
257 complex_t v;
258 int x;
260 if (e1->type->isreal())
261 { r1 = e1->toReal();
262 x = 0;
264 else if (e1->type->isimaginary())
265 { i1 = e1->toImaginary();
266 x = 3;
268 else
269 { c1 = e1->toComplex();
270 x = 6;
273 if (e2->type->isreal())
274 { r2 = e2->toReal();
276 else if (e2->type->isimaginary())
277 { i2 = e2->toImaginary();
278 x += 1;
280 else
281 { c2 = e2->toComplex();
282 x += 2;
285 switch (x)
287 #if __DMC__
288 case 0+0: v = (complex_t) (r1 - r2); break;
289 case 0+1: v = r1 - i2 * I; break;
290 case 0+2: v = r1 - c2; break;
291 case 3+0: v = i1 * I - r2; break;
292 case 3+1: v = (complex_t) ((i1 - i2) * I); break;
293 case 3+2: v = i1 * I - c2; break;
294 case 6+0: v = c1 - r2; break;
295 case 6+1: v = c1 - i2 * I; break;
296 case 6+2: v = c1 - c2; break;
297 #else
298 case 0+0: v = complex_t(r1 - r2, 0); break;
299 case 0+1: v = complex_t(r1, -i2); break;
300 case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break;
301 case 3+0: v = complex_t(-r2, i1); break;
302 case 3+1: v = complex_t(0, i1 - i2); break;
303 case 3+2: v = complex_t(-creall(c2), i1 - cimagl(c2)); break;
304 case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break;
305 case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break;
306 case 6+2: v = c1 - c2; break;
307 #endif
308 default: assert(0);
310 e = new ComplexExp(loc, v, type);
312 else if (e1->op == TOKsymoff)
314 SymOffExp *soe = (SymOffExp *)e1;
315 e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger());
316 e->type = type;
318 else
320 e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type);
322 return e;
325 Expression *Mul(Type *type, Expression *e1, Expression *e2)
326 { Expression *e;
327 Loc loc = e1->loc;
329 if (type->isfloating())
330 { complex_t c;
331 #ifdef IN_GCC
332 real_t r;
333 #else
334 d_float80 r;
335 #endif
337 if (e1->type->isreal())
339 #if __DMC__
340 c = e1->toReal() * e2->toComplex();
341 #else
342 r = e1->toReal();
343 c = e2->toComplex();
344 c = complex_t(r * creall(c), r * cimagl(c));
345 #endif
347 else if (e1->type->isimaginary())
349 #if __DMC__
350 c = e1->toImaginary() * I * e2->toComplex();
351 #else
352 r = e1->toImaginary();
353 c = e2->toComplex();
354 c = complex_t(-r * cimagl(c), r * creall(c));
355 #endif
357 else if (e2->type->isreal())
359 #if __DMC__
360 c = e2->toReal() * e1->toComplex();
361 #else
362 r = e2->toReal();
363 c = e1->toComplex();
364 c = complex_t(r * creall(c), r * cimagl(c));
365 #endif
367 else if (e2->type->isimaginary())
369 #if __DMC__
370 c = e1->toComplex() * e2->toImaginary() * I;
371 #else
372 r = e2->toImaginary();
373 c = e1->toComplex();
374 c = complex_t(-r * cimagl(c), r * creall(c));
375 #endif
377 else
378 c = e1->toComplex() * e2->toComplex();
380 if (type->isreal())
381 e = new RealExp(loc, creall(c), type);
382 else if (type->isimaginary())
383 e = new RealExp(loc, cimagl(c), type);
384 else if (type->iscomplex())
385 e = new ComplexExp(loc, c, type);
386 else
387 assert(0);
389 else
391 e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type);
393 return e;
396 Expression *Div(Type *type, Expression *e1, Expression *e2)
397 { Expression *e;
398 Loc loc = e1->loc;
400 if (type->isfloating())
401 { complex_t c;
402 #ifdef IN_GCC
403 real_t r;
404 #else
405 d_float80 r;
406 #endif
408 //e1->type->print();
409 //e2->type->print();
410 if (e2->type->isreal())
412 if (e1->type->isreal())
414 e = new RealExp(loc, e1->toReal() / e2->toReal(), type);
415 return e;
417 #if __DMC__
418 //r = e2->toReal();
419 //c = e1->toComplex();
420 //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r);
422 c = e1->toComplex() / e2->toReal();
423 #else
424 r = e2->toReal();
425 c = e1->toComplex();
426 c = complex_t(creall(c) / r, cimagl(c) / r);
427 #endif
429 else if (e2->type->isimaginary())
431 #if __DMC__
432 //r = e2->toImaginary();
433 //c = e1->toComplex();
434 //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r);
436 c = e1->toComplex() / (e2->toImaginary() * I);
437 #else
438 r = e2->toImaginary();
439 c = e1->toComplex();
440 c = complex_t(cimagl(c) / r, -creall(c) / r);
441 #endif
443 else
445 c = e1->toComplex() / e2->toComplex();
448 if (type->isreal())
449 e = new RealExp(loc, creall(c), type);
450 else if (type->isimaginary())
451 e = new RealExp(loc, cimagl(c), type);
452 else if (type->iscomplex())
453 e = new ComplexExp(loc, c, type);
454 else
455 assert(0);
457 else
458 { sinteger_t n1;
459 sinteger_t n2;
460 sinteger_t n;
462 n1 = e1->toInteger();
463 n2 = e2->toInteger();
464 if (n2 == 0)
465 { e2->error("divide by 0");
466 e2 = new IntegerExp(0, 1, e2->type);
467 n2 = 1;
469 if (e1->type->isunsigned() || e2->type->isunsigned())
470 n = ((d_uns64) n1) / ((d_uns64) n2);
471 else
472 n = n1 / n2;
473 e = new IntegerExp(loc, n, type);
475 return e;
478 Expression *Mod(Type *type, Expression *e1, Expression *e2)
479 { Expression *e;
480 Loc loc = e1->loc;
482 if (type->isfloating())
484 complex_t c;
486 if (e2->type->isreal())
487 { real_t r2 = e2->toReal();
489 #ifdef __DMC__
490 c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I;
491 #elif defined(IN_GCC)
492 c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
493 #else
494 c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2));
495 #endif
497 else if (e2->type->isimaginary())
498 { real_t i2 = e2->toImaginary();
500 #ifdef __DMC__
501 c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I;
502 #elif defined(IN_GCC)
503 c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
504 #else
505 c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2));
506 #endif
508 else
509 assert(0);
511 if (type->isreal())
512 e = new RealExp(loc, creall(c), type);
513 else if (type->isimaginary())
514 e = new RealExp(loc, cimagl(c), type);
515 else if (type->iscomplex())
516 e = new ComplexExp(loc, c, type);
517 else
518 assert(0);
520 else
521 { sinteger_t n1;
522 sinteger_t n2;
523 sinteger_t n;
525 n1 = e1->toInteger();
526 n2 = e2->toInteger();
527 if (n2 == 0)
528 { e2->error("divide by 0");
529 e2 = new IntegerExp(0, 1, e2->type);
530 n2 = 1;
532 if (e1->type->isunsigned() || e2->type->isunsigned())
533 n = ((d_uns64) n1) % ((d_uns64) n2);
534 else
535 n = n1 % n2;
536 e = new IntegerExp(loc, n, type);
538 return e;
541 Expression *Shl(Type *type, Expression *e1, Expression *e2)
542 { Expression *e;
543 Loc loc = e1->loc;
545 e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
546 return e;
549 Expression *Shr(Type *type, Expression *e1, Expression *e2)
550 { Expression *e;
551 Loc loc = e1->loc;
552 unsigned count;
553 integer_t value;
555 value = e1->toInteger();
556 count = e2->toInteger();
557 switch (e1->type->toBasetype()->ty)
559 case Tint8:
560 value = (d_int8)(value) >> count;
561 break;
563 case Tuns8:
564 value = (d_uns8)(value) >> count;
565 break;
567 case Tint16:
568 value = (d_int16)(value) >> count;
569 break;
571 case Tuns16:
572 value = (d_uns16)(value) >> count;
573 break;
575 case Tint32:
576 value = (d_int32)(value) >> count;
577 break;
579 case Tuns32:
580 value = (d_uns32)(value) >> count;
581 break;
583 case Tint64:
584 value = (d_int64)(value) >> count;
585 break;
587 case Tuns64:
588 value = (d_uns64)(value) >> count;
589 break;
591 default:
592 assert(0);
594 e = new IntegerExp(loc, value, type);
595 return e;
598 Expression *Ushr(Type *type, Expression *e1, Expression *e2)
599 { Expression *e;
600 Loc loc = e1->loc;
601 unsigned count;
602 integer_t value;
604 value = e1->toInteger();
605 count = e2->toInteger();
606 switch (e1->type->toBasetype()->ty)
608 case Tint8:
609 case Tuns8:
610 assert(0); // no way to trigger this
611 value = (value & 0xFF) >> count;
612 break;
614 case Tint16:
615 case Tuns16:
616 assert(0); // no way to trigger this
617 value = (value & 0xFFFF) >> count;
618 break;
620 case Tint32:
621 case Tuns32:
622 value = (value & 0xFFFFFFFF) >> count;
623 break;
625 case Tint64:
626 case Tuns64:
627 value = (d_uns64)(value) >> count;
628 break;
630 default:
631 assert(0);
633 e = new IntegerExp(loc, value, type);
634 return e;
637 Expression *And(Type *type, Expression *e1, Expression *e2)
638 { Expression *e;
639 Loc loc = e1->loc;
641 e = new IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
642 return e;
645 Expression *Or(Type *type, Expression *e1, Expression *e2)
646 { Expression *e;
647 Loc loc = e1->loc;
649 e = new IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
650 return e;
653 Expression *Xor(Type *type, Expression *e1, Expression *e2)
654 { Expression *e;
655 Loc loc = e1->loc;
657 e = new IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
658 return e;
661 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
663 Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2)
664 { Expression *e;
665 Loc loc = e1->loc;
666 int cmp;
667 real_t r1;
668 real_t r2;
670 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
672 assert(op == TOKequal || op == TOKnotequal);
674 if (e1->op == TOKnull)
676 if (e2->op == TOKnull)
677 cmp = 1;
678 else if (e2->op == TOKstring)
679 { StringExp *es2 = (StringExp *)e2;
680 cmp = (0 == es2->len);
682 else if (e2->op == TOKarrayliteral)
683 { ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
684 cmp = !es2->elements || (0 == es2->elements->dim);
686 else
687 return EXP_CANT_INTERPRET;
689 else if (e2->op == TOKnull)
691 if (e1->op == TOKstring)
692 { StringExp *es1 = (StringExp *)e1;
693 cmp = (0 == es1->len);
695 else if (e1->op == TOKarrayliteral)
696 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
697 cmp = !es1->elements || (0 == es1->elements->dim);
699 else
700 return EXP_CANT_INTERPRET;
702 else if (e1->op == TOKstring && e2->op == TOKstring)
703 { StringExp *es1 = (StringExp *)e1;
704 StringExp *es2 = (StringExp *)e2;
706 assert(es1->sz == es2->sz);
707 if (es1->len == es2->len &&
708 memcmp(es1->string, es2->string, es1->sz * es1->len) == 0)
709 cmp = 1;
710 else
711 cmp = 0;
713 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral)
714 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
715 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
717 if ((!es1->elements || !es1->elements->dim) &&
718 (!es2->elements || !es2->elements->dim))
719 cmp = 1; // both arrays are empty
720 else if (!es1->elements || !es2->elements)
721 cmp = 0;
722 else if (es1->elements->dim != es2->elements->dim)
723 cmp = 0;
724 else
726 for (size_t i = 0; i < es1->elements->dim; i++)
727 { Expression *ee1 = (Expression *)es1->elements->data[i];
728 Expression *ee2 = (Expression *)es2->elements->data[i];
730 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2);
731 if (v == EXP_CANT_INTERPRET)
732 return EXP_CANT_INTERPRET;
733 cmp = v->toInteger();
734 if (cmp == 0)
735 break;
739 else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
740 { // Swap operands and use common code
741 Expression *e = e1;
742 e1 = e2;
743 e2 = e;
744 goto Lsa;
746 else if (e1->op == TOKstring && e2->op == TOKarrayliteral)
748 Lsa:
749 StringExp *es1 = (StringExp *)e1;
750 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
751 size_t dim1 = es1->len;
752 size_t dim2 = es2->elements ? es2->elements->dim : 0;
753 if (dim1 != dim2)
754 cmp = 0;
755 else
757 for (size_t i = 0; i < dim1; i++)
759 uinteger_t c = es1->charAt(i);
760 Expression *ee2 = (Expression *)es2->elements->data[i];
761 if (ee2->isConst() != 1)
762 return EXP_CANT_INTERPRET;
763 cmp = (c == ee2->toInteger());
764 if (cmp == 0)
765 break;
769 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral)
770 { StructLiteralExp *es1 = (StructLiteralExp *)e1;
771 StructLiteralExp *es2 = (StructLiteralExp *)e2;
773 if (es1->sd != es2->sd)
774 cmp = 0;
775 else if ((!es1->elements || !es1->elements->dim) &&
776 (!es2->elements || !es2->elements->dim))
777 cmp = 1; // both arrays are empty
778 else if (!es1->elements || !es2->elements)
779 cmp = 0;
780 else if (es1->elements->dim != es2->elements->dim)
781 cmp = 0;
782 else
784 cmp = 1;
785 for (size_t i = 0; i < es1->elements->dim; i++)
786 { Expression *ee1 = (Expression *)es1->elements->data[i];
787 Expression *ee2 = (Expression *)es2->elements->data[i];
789 if (ee1 == ee2)
790 continue;
791 if (!ee1 || !ee2)
792 { cmp = 0;
793 break;
795 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2);
796 if (v == EXP_CANT_INTERPRET)
797 return EXP_CANT_INTERPRET;
798 cmp = v->toInteger();
799 if (cmp == 0)
800 break;
804 #if 0 // Should handle this
805 else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
808 #endif
809 else if (e1->isConst() != 1 || e2->isConst() != 1)
810 return EXP_CANT_INTERPRET;
811 else if (e1->type->isreal())
813 r1 = e1->toReal();
814 r2 = e2->toReal();
815 goto L1;
817 else if (e1->type->isimaginary())
819 r1 = e1->toImaginary();
820 r2 = e2->toImaginary();
822 #if __DMC__
823 cmp = (r1 == r2);
824 #else
825 # if IN_GCC
826 if (r1.isNan() || r2.isNan()) // if unordered
827 # else
828 if (isnan(r1) || isnan(r2)) // if unordered
829 # endif
831 cmp = 0;
833 else
835 cmp = (r1 == r2);
837 #endif
839 else if (e1->type->iscomplex())
841 cmp = e1->toComplex() == e2->toComplex();
843 else if (e1->type->isintegral())
845 cmp = (e1->toInteger() == e2->toInteger());
847 else
848 return EXP_CANT_INTERPRET;
849 if (op == TOKnotequal)
850 cmp ^= 1;
851 e = new IntegerExp(loc, cmp, type);
852 return e;
855 Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2)
856 { Expression *e;
857 Loc loc = e1->loc;
858 int cmp;
860 if (e1->op == TOKnull && e2->op == TOKnull)
862 cmp = 1;
864 else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
866 SymOffExp *es1 = (SymOffExp *)e1;
867 SymOffExp *es2 = (SymOffExp *)e2;
869 cmp = (es1->var == es2->var && es1->offset == es2->offset);
871 else if (e1->isConst() == 1 && e2->isConst() == 1)
872 return Equal((op == TOKidentity) ? TOKequal : TOKnotequal,
873 type, e1, e2);
874 else
875 assert(0);
876 if (op == TOKnotidentity)
877 cmp ^= 1;
878 return new IntegerExp(loc, cmp, type);
882 Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2)
883 { Expression *e;
884 Loc loc = e1->loc;
885 integer_t n;
886 real_t r1;
887 real_t r2;
889 if (e1->type->isreal())
891 r1 = e1->toReal();
892 r2 = e2->toReal();
893 goto L1;
895 else if (e1->type->isimaginary())
897 r1 = e1->toImaginary();
898 r2 = e2->toImaginary();
900 #if __DMC__
901 // DMC is the only compiler I know of that handles NAN arguments
902 // correctly in comparisons.
903 switch (op)
905 case TOKlt: n = r1 < r2; break;
906 case TOKle: n = r1 <= r2; break;
907 case TOKgt: n = r1 > r2; break;
908 case TOKge: n = r1 >= r2; break;
910 case TOKleg: n = r1 <>= r2; break;
911 case TOKlg: n = r1 <> r2; break;
912 case TOKunord: n = r1 !<>= r2; break;
913 case TOKue: n = r1 !<> r2; break;
914 case TOKug: n = r1 !<= r2; break;
915 case TOKuge: n = r1 !< r2; break;
916 case TOKul: n = r1 !>= r2; break;
917 case TOKule: n = r1 !> r2; break;
919 default:
920 assert(0);
922 #else
923 // Don't rely on compiler, handle NAN arguments separately
924 #if IN_GCC
925 if (r1.isNan() || r2.isNan()) // if unordered
926 #else
927 if (isnan(r1) || isnan(r2)) // if unordered
928 #endif
930 switch (op)
932 case TOKlt: n = 0; break;
933 case TOKle: n = 0; break;
934 case TOKgt: n = 0; break;
935 case TOKge: n = 0; break;
937 case TOKleg: n = 0; break;
938 case TOKlg: n = 0; break;
939 case TOKunord: n = 1; break;
940 case TOKue: n = 1; break;
941 case TOKug: n = 1; break;
942 case TOKuge: n = 1; break;
943 case TOKul: n = 1; break;
944 case TOKule: n = 1; break;
946 default:
947 assert(0);
950 else
952 switch (op)
954 case TOKlt: n = r1 < r2; break;
955 case TOKle: n = r1 <= r2; break;
956 case TOKgt: n = r1 > r2; break;
957 case TOKge: n = r1 >= r2; break;
959 case TOKleg: n = 1; break;
960 case TOKlg: n = r1 != r2; break;
961 case TOKunord: n = 0; break;
962 case TOKue: n = r1 == r2; break;
963 case TOKug: n = r1 > r2; break;
964 case TOKuge: n = r1 >= r2; break;
965 case TOKul: n = r1 < r2; break;
966 case TOKule: n = r1 <= r2; break;
968 default:
969 assert(0);
972 #endif
974 else if (e1->type->iscomplex())
976 assert(0);
978 else
979 { sinteger_t n1;
980 sinteger_t n2;
982 n1 = e1->toInteger();
983 n2 = e2->toInteger();
984 if (e1->type->isunsigned() || e2->type->isunsigned())
986 switch (op)
988 case TOKlt: n = ((d_uns64) n1) < ((d_uns64) n2); break;
989 case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2); break;
990 case TOKgt: n = ((d_uns64) n1) > ((d_uns64) n2); break;
991 case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2); break;
993 case TOKleg: n = 1; break;
994 case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2); break;
995 case TOKunord: n = 0; break;
996 case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2); break;
997 case TOKug: n = ((d_uns64) n1) > ((d_uns64) n2); break;
998 case TOKuge: n = ((d_uns64) n1) >= ((d_uns64) n2); break;
999 case TOKul: n = ((d_uns64) n1) < ((d_uns64) n2); break;
1000 case TOKule: n = ((d_uns64) n1) <= ((d_uns64) n2); break;
1002 default:
1003 assert(0);
1006 else
1008 switch (op)
1010 case TOKlt: n = n1 < n2; break;
1011 case TOKle: n = n1 <= n2; break;
1012 case TOKgt: n = n1 > n2; break;
1013 case TOKge: n = n1 >= n2; break;
1015 case TOKleg: n = 1; break;
1016 case TOKlg: n = n1 != n2; break;
1017 case TOKunord: n = 0; break;
1018 case TOKue: n = n1 == n2; break;
1019 case TOKug: n = n1 > n2; break;
1020 case TOKuge: n = n1 >= n2; break;
1021 case TOKul: n = n1 < n2; break;
1022 case TOKule: n = n1 <= n2; break;
1024 default:
1025 assert(0);
1029 e = new IntegerExp(loc, n, type);
1030 return e;
1033 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
1034 * to: type to cast to
1035 * type: type to paint the result
1038 Expression *Cast(Type *type, Type *to, Expression *e1)
1039 { Expression *e = EXP_CANT_INTERPRET;
1040 Loc loc = e1->loc;
1042 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars());
1043 //printf("e1->type = %s\n", e1->type->toChars());
1044 if (type->equals(e1->type) && to->equals(type))
1045 return e1;
1047 if (e1->isConst() != 1)
1048 return EXP_CANT_INTERPRET;
1050 Type *tb = to->toBasetype();
1051 if (tb->ty == Tbool)
1052 e = new IntegerExp(loc, e1->toInteger() != 0, type);
1053 else if (type->isintegral())
1055 if (e1->type->isfloating())
1056 { integer_t result;
1057 #ifdef IN_GCC
1058 Type * rt = e1->type;
1059 if (rt->iscomplex())
1061 switch (rt->toBasetype()->ty)
1063 case Tcomplex32: rt = Type::tfloat32; break;
1064 case Tcomplex64: rt = Type::tfloat64; break;
1065 case Tcomplex80: rt = Type::tfloat80; break;
1066 default: assert(0);
1069 d_int64 r = e1->toReal().toInt(rt, type);
1070 #else
1071 real_t r = e1->toReal();
1072 #endif
1074 switch (type->toBasetype()->ty)
1076 case Tint8: result = (d_int8)r; break;
1077 case Tchar:
1078 case Tuns8: result = (d_uns8)r; break;
1079 case Tint16: result = (d_int16)r; break;
1080 case Twchar:
1081 case Tuns16: result = (d_uns16)r; break;
1082 case Tint32: result = (d_int32)r; break;
1083 case Tdchar:
1084 case Tuns32: result = (d_uns32)r; break;
1085 case Tint64: result = (d_int64)r; break;
1086 case Tuns64: result = (d_uns64)r; break;
1087 default:
1088 assert(0);
1091 e = new IntegerExp(loc, result, type);
1093 else if (type->isunsigned())
1094 e = new IntegerExp(loc, e1->toUInteger(), type);
1095 else
1096 e = new IntegerExp(loc, e1->toInteger(), type);
1098 else if (tb->isreal())
1099 { real_t value = e1->toReal();
1101 e = new RealExp(loc, value, type);
1103 else if (tb->isimaginary())
1104 { real_t value = e1->toImaginary();
1106 e = new RealExp(loc, value, type);
1108 else if (tb->iscomplex())
1109 { complex_t value = e1->toComplex();
1111 e = new ComplexExp(loc, value, type);
1113 else if (tb->isscalar())
1114 e = new IntegerExp(loc, e1->toInteger(), type);
1115 else if (tb->ty == Tvoid)
1116 e = EXP_CANT_INTERPRET;
1117 else if (tb->ty == Tstruct && e1->op == TOKint64)
1118 { // Struct = 0;
1119 StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration();
1120 assert(sd);
1121 Expressions *elements = new Expressions;
1122 for (size_t i = 0; i < sd->fields.dim; i++)
1123 { Dsymbol *s = (Dsymbol *)sd->fields.data[i];
1124 VarDeclaration *v = s->isVarDeclaration();
1125 assert(v);
1127 Expression *exp = new IntegerExp(0);
1128 exp = Cast(v->type, v->type, exp);
1129 if (exp == EXP_CANT_INTERPRET)
1130 return exp;
1131 elements->push(exp);
1133 e = new StructLiteralExp(loc, sd, elements);
1134 e->type = type;
1136 else
1138 error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars());
1139 e = new IntegerExp(loc, 0, type);
1141 return e;
1145 Expression *ArrayLength(Type *type, Expression *e1)
1146 { Expression *e;
1147 Loc loc = e1->loc;
1149 if (e1->op == TOKstring)
1150 { StringExp *es1 = (StringExp *)e1;
1152 e = new IntegerExp(loc, es1->len, type);
1154 else if (e1->op == TOKarrayliteral)
1155 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1156 size_t dim;
1158 dim = ale->elements ? ale->elements->dim : 0;
1159 e = new IntegerExp(loc, dim, type);
1161 else if (e1->op == TOKassocarrayliteral)
1162 { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1;
1163 size_t dim = ale->keys->dim;
1165 e = new IntegerExp(loc, dim, type);
1167 else
1168 e = EXP_CANT_INTERPRET;
1169 return e;
1172 /* Also return EXP_CANT_INTERPRET if this fails
1174 Expression *Index(Type *type, Expression *e1, Expression *e2)
1175 { Expression *e = EXP_CANT_INTERPRET;
1176 Loc loc = e1->loc;
1178 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1179 assert(e1->type);
1180 if (e1->op == TOKstring && e2->op == TOKint64)
1181 { StringExp *es1 = (StringExp *)e1;
1182 uinteger_t i = e2->toInteger();
1184 if (i >= es1->len)
1185 e1->error("string index %"PRIuMAX" is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len);
1186 else
1187 { unsigned value = es1->charAt(i);
1188 e = new IntegerExp(loc, value, type);
1191 else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64)
1192 { TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype();
1193 uinteger_t length = tsa->dim->toInteger();
1194 uinteger_t i = e2->toInteger();
1196 if (i >= length)
1197 { e2->error("array index %"PRIuMAX" is out of bounds %s[0 .. %"PRIuMAX"]", i, e1->toChars(), length);
1199 else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
1200 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1201 e = (Expression *)ale->elements->data[i];
1202 e->type = type;
1205 else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64)
1207 uinteger_t i = e2->toInteger();
1209 if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
1210 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1211 if (i >= ale->elements->dim)
1212 { e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
1214 else
1215 { e = (Expression *)ale->elements->data[i];
1216 e->type = type;
1220 else if (e1->op == TOKassocarrayliteral && !e1->checkSideEffect(2))
1222 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1;
1223 /* Search the keys backwards, in case there are duplicate keys
1225 for (size_t i = ae->keys->dim; i;)
1227 i--;
1228 Expression *ekey = (Expression *)ae->keys->data[i];
1229 Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2);
1230 if (ex == EXP_CANT_INTERPRET)
1231 return ex;
1232 if (ex->isBool(TRUE))
1233 { e = (Expression *)ae->values->data[i];
1234 e->type = type;
1235 break;
1239 return e;
1242 /* Also return EXP_CANT_INTERPRET if this fails
1244 Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
1245 { Expression *e = EXP_CANT_INTERPRET;
1246 Loc loc = e1->loc;
1248 #if LOG
1249 printf("Slice()\n");
1250 if (lwr)
1251 { printf("\te1 = %s\n", e1->toChars());
1252 printf("\tlwr = %s\n", lwr->toChars());
1253 printf("\tupr = %s\n", upr->toChars());
1255 #endif
1256 if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64)
1257 { StringExp *es1 = (StringExp *)e1;
1258 uinteger_t ilwr = lwr->toInteger();
1259 uinteger_t iupr = upr->toInteger();
1261 if (iupr > es1->len || ilwr > iupr)
1262 e1->error("string slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", ilwr, iupr);
1263 else
1264 { integer_t value;
1265 void *s;
1266 size_t len = iupr - ilwr;
1267 int sz = es1->sz;
1268 StringExp *es;
1270 s = mem.malloc((len + 1) * sz);
1271 memcpy((unsigned char *)s, (unsigned char *)es1->string + ilwr * sz, len * sz);
1272 memset((unsigned char *)s + len * sz, 0, sz);
1274 es = new StringExp(loc, s, len, es1->postfix);
1275 es->sz = sz;
1276 es->committed = 1;
1277 es->type = type;
1278 e = es;
1281 else if (e1->op == TOKarrayliteral &&
1282 lwr->op == TOKint64 && upr->op == TOKint64 &&
1283 !e1->checkSideEffect(2))
1284 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1285 uinteger_t ilwr = lwr->toInteger();
1286 uinteger_t iupr = upr->toInteger();
1288 if (iupr > es1->elements->dim || ilwr > iupr)
1289 e1->error("array slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", ilwr, iupr);
1290 else
1292 Expressions *elements = new Expressions();
1293 elements->setDim(iupr - ilwr);
1294 memcpy(elements->data,
1295 es1->elements->data + ilwr,
1296 (iupr - ilwr) * sizeof(es1->elements->data[0]));
1297 e = new ArrayLiteralExp(e1->loc, elements);
1298 e->type = type;
1301 return e;
1304 /* Also return EXP_CANT_INTERPRET if this fails
1306 Expression *Cat(Type *type, Expression *e1, Expression *e2)
1307 { Expression *e = EXP_CANT_INTERPRET;
1308 Loc loc = e1->loc;
1309 Type *t;
1311 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1313 if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
1314 { e = e2;
1315 goto L2;
1317 else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
1318 { e = e1;
1320 Type *tn = e->type->toBasetype();
1321 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
1323 // Create a StringExp
1324 void *s;
1325 StringExp *es;
1326 size_t len = 1;
1327 int sz = tn->size();
1328 integer_t v = e->toInteger();
1330 s = mem.malloc((len + 1) * sz);
1331 switch (sz)
1333 case 1: *(d_uns8*)s = v; break;
1334 case 2: *(d_uns16*)s = v; break;
1335 case 4: *(d_uns32*)s = v; break;
1336 default: assert(0);
1339 // Add terminating 0
1340 memset((unsigned char *)s + len * sz, 0, sz);
1342 es = new StringExp(loc, s, len);
1343 es->sz = sz;
1344 es->committed = 1;
1345 e = es;
1347 else
1348 { // Create an ArrayLiteralExp
1349 Expressions *elements = new Expressions();
1350 elements->push(e);
1351 e = new ArrayLiteralExp(e->loc, elements);
1353 e->type = type;
1354 return e;
1356 else if (e1->op == TOKstring && e2->op == TOKstring)
1358 // Concatenate the strings
1359 void *s;
1360 StringExp *es1 = (StringExp *)e1;
1361 StringExp *es2 = (StringExp *)e2;
1362 StringExp *es;
1363 Type *t;
1364 size_t len = es1->len + es2->len;
1365 int sz = es1->sz;
1367 assert(sz == es2->sz);
1368 s = mem.malloc((len + 1) * sz);
1369 memcpy(s, es1->string, es1->len * sz);
1370 memcpy((unsigned char *)s + es1->len * sz, es2->string, es2->len * sz);
1372 // Add terminating 0
1373 memset((unsigned char *)s + len * sz, 0, sz);
1375 es = new StringExp(loc, s, len);
1376 es->sz = sz;
1377 es->committed = es1->committed | es2->committed;
1378 if (es1->committed)
1379 t = es1->type;
1380 else
1381 t = es2->type;
1382 es->type = type;
1383 e = es;
1385 else if (e1->op == TOKstring && e2->op == TOKint64)
1387 // Concatenate the strings
1388 void *s;
1389 void *sch;
1390 StringExp *es1 = (StringExp *)e1;
1391 StringExp *es;
1392 Type *t;
1393 size_t len = es1->len + 1;
1394 int sz = es1->sz;
1395 integer_t v = e2->toInteger();
1397 s = mem.malloc((len + 1) * sz);
1398 memcpy(s, es1->string, es1->len * sz);
1399 sch = (unsigned char *)s + es1->len * sz;
1400 switch (sz)
1402 case 1: *(d_uns8*)sch = v; break;
1403 case 2: *(d_uns16*)sch = v; break;
1404 case 4: *(d_uns32*)sch = v; break;
1405 default: assert(0);
1408 // Add terminating 0
1409 memset((unsigned char *)s + len * sz, 0, sz);
1411 es = new StringExp(loc, s, len);
1412 es->sz = sz;
1413 es->committed = es1->committed;
1414 t = es1->type;
1415 es->type = type;
1416 e = es;
1418 else if (e1->op == TOKint64 && e2->op == TOKstring)
1420 // Concatenate the strings
1421 void *s;
1422 StringExp *es2 = (StringExp *)e2;
1423 StringExp *es;
1424 Type *t;
1425 size_t len = 1 + es2->len;
1426 int sz = es2->sz;
1427 integer_t v = e1->toInteger();
1429 s = mem.malloc((len + 1) * sz);
1430 switch (sz)
1432 case 1: *(d_uns8*)s = v; break;
1433 case 2: *(d_uns16*)s = v; break;
1434 case 4: *(d_uns32*)s = v; break;
1435 default: assert(0);
1437 memcpy((unsigned char *)s + sz, es2->string, es2->len * sz);
1439 // Add terminating 0
1440 memset((unsigned char *)s + len * sz, 0, sz);
1442 es = new StringExp(loc, s, len);
1443 es->sz = sz;
1444 es->committed = es2->committed;
1445 t = es2->type;
1446 es->type = type;
1447 e = es;
1449 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral &&
1450 e1->type->equals(e2->type))
1452 // Concatenate the arrays
1453 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1454 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
1456 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy());
1457 es1->elements->insert(es1->elements->dim, es2->elements);
1458 e = es1;
1460 if (type->toBasetype()->ty == Tsarray)
1462 e->type = new TypeSArray(e1->type->toBasetype()->next, new IntegerExp(0, es1->elements->dim, Type::tindex));
1463 e->type = e->type->semantic(loc, NULL);
1465 else
1466 e->type = type;
1468 else if (e1->op == TOKarrayliteral &&
1469 e1->type->toBasetype()->nextOf()->equals(e2->type))
1471 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1473 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy());
1474 es1->elements->push(e2);
1475 e = es1;
1477 if (type->toBasetype()->ty == Tsarray)
1479 e->type = new TypeSArray(e2->type, new IntegerExp(0, es1->elements->dim, Type::tindex));
1480 e->type = e->type->semantic(loc, NULL);
1482 else
1483 e->type = type;
1485 else if (e2->op == TOKarrayliteral &&
1486 e2->type->toBasetype()->nextOf()->equals(e1->type))
1488 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
1490 es2 = new ArrayLiteralExp(es2->loc, (Expressions *)es2->elements->copy());
1491 es2->elements->shift(e1);
1492 e = es2;
1494 if (type->toBasetype()->ty == Tsarray)
1496 e->type = new TypeSArray(e1->type, new IntegerExp(0, es2->elements->dim, Type::tindex));
1497 e->type = e->type->semantic(loc, NULL);
1499 else
1500 e->type = type;
1502 else if (e1->op == TOKnull && e2->op == TOKstring)
1504 t = e1->type;
1505 e = e2;
1506 goto L1;
1508 else if (e1->op == TOKstring && e2->op == TOKnull)
1509 { e = e1;
1510 t = e2->type;
1512 Type *tb = t->toBasetype();
1513 if (tb->ty == Tarray && tb->nextOf()->equals(e->type))
1514 { Expressions *expressions = new Expressions();
1515 expressions->push(e);
1516 e = new ArrayLiteralExp(loc, expressions);
1517 e->type = t;
1519 if (!e->type->equals(type))
1520 { StringExp *se = (StringExp *)e->copy();
1521 e = se->castTo(NULL, type);
1524 return e;
1527 Expression *Ptr(Type *type, Expression *e1)
1529 //printf("Ptr(e1 = %s)\n", e1->toChars());
1530 if (e1->op == TOKadd)
1531 { AddExp *ae = (AddExp *)e1;
1532 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
1533 { AddrExp *ade = (AddrExp *)ae->e1;
1534 if (ade->e1->op == TOKstructliteral)
1535 { StructLiteralExp *se = (StructLiteralExp *)ade->e1;
1536 unsigned offset = ae->e2->toInteger();
1537 Expression *e = se->getField(type, offset);
1538 if (!e)
1539 e = EXP_CANT_INTERPRET;
1540 return e;
1544 return EXP_CANT_INTERPRET;