2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
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
30 #include "expression.h"
31 #include "aggregate.h"
32 #include "declaration.h"
35 #include "d-gcc-real.h"
38 static real_t zero
; // work around DMC bug for now
42 Expression
*expType(Type
*type
, Expression
*e
)
52 /* ================================== isConst() ============================== */
54 int Expression::isConst()
56 //printf("Expression::isConst(): %s\n", toChars());
60 int IntegerExp::isConst()
65 int RealExp::isConst()
70 int ComplexExp::isConst()
75 int SymOffExp::isConst()
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
)
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
);
105 e
= new IntegerExp(loc
, -e1
->toInteger(), type
);
109 Expression
*Com(Type
*type
, Expression
*e1
)
113 e
= new IntegerExp(loc
, ~e1
->toInteger(), type
);
117 Expression
*Not(Type
*type
, Expression
*e1
)
121 e
= new IntegerExp(loc
, e1
->isBool(0), type
);
125 Expression
*Bool(Type
*type
, Expression
*e1
)
129 e
= new IntegerExp(loc
, e1
->isBool(1), type
);
133 Expression
*Add(Type
*type
, Expression
*e1
, Expression
*e2
)
138 printf("Add(e1 = %s, e2 = %s)\n", e1
->toChars(), e2
->toChars());
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
163 if (e1
->type
->isreal())
167 else if (e1
->type
->isimaginary())
168 { i1
= e1
->toImaginary();
172 { c1
= e1
->toComplex();
176 if (e2
->type
->isreal())
179 else if (e2
->type
->isimaginary())
180 { i2
= e2
->toImaginary();
184 { c2
= e2
->toComplex();
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;
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;
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());
221 else if (e2
->op
== TOKsymoff
)
223 SymOffExp
*soe
= (SymOffExp
*)e2
;
224 e
= new SymOffExp(loc
, soe
->var
, soe
->offset
+ e1
->toInteger());
228 e
= new IntegerExp(loc
, e1
->toInteger() + e2
->toInteger(), type
);
233 Expression
*Min(Type
*type
, Expression
*e1
, Expression
*e2
)
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
260 if (e1
->type
->isreal())
264 else if (e1
->type
->isimaginary())
265 { i1
= e1
->toImaginary();
269 { c1
= e1
->toComplex();
273 if (e2
->type
->isreal())
276 else if (e2
->type
->isimaginary())
277 { i2
= e2
->toImaginary();
281 { c2
= e2
->toComplex();
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;
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;
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());
320 e
= new IntegerExp(loc
, e1
->toInteger() - e2
->toInteger(), type
);
325 Expression
*Mul(Type
*type
, Expression
*e1
, Expression
*e2
)
329 if (type
->isfloating())
337 if (e1
->type
->isreal())
340 c
= e1
->toReal() * e2
->toComplex();
344 c
= complex_t(r
* creall(c
), r
* cimagl(c
));
347 else if (e1
->type
->isimaginary())
350 c
= e1
->toImaginary() * I
* e2
->toComplex();
352 r
= e1
->toImaginary();
354 c
= complex_t(-r
* cimagl(c
), r
* creall(c
));
357 else if (e2
->type
->isreal())
360 c
= e2
->toReal() * e1
->toComplex();
364 c
= complex_t(r
* creall(c
), r
* cimagl(c
));
367 else if (e2
->type
->isimaginary())
370 c
= e1
->toComplex() * e2
->toImaginary() * I
;
372 r
= e2
->toImaginary();
374 c
= complex_t(-r
* cimagl(c
), r
* creall(c
));
378 c
= e1
->toComplex() * e2
->toComplex();
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
);
391 e
= new IntegerExp(loc
, e1
->toInteger() * e2
->toInteger(), type
);
396 Expression
*Div(Type
*type
, Expression
*e1
, Expression
*e2
)
400 if (type
->isfloating())
410 if (e2
->type
->isreal())
412 if (e1
->type
->isreal())
414 e
= new RealExp(loc
, e1
->toReal() / e2
->toReal(), type
);
419 //c = e1->toComplex();
420 //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r);
422 c
= e1
->toComplex() / e2
->toReal();
426 c
= complex_t(creall(c
) / r
, cimagl(c
) / r
);
429 else if (e2
->type
->isimaginary())
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
);
438 r
= e2
->toImaginary();
440 c
= complex_t(cimagl(c
) / r
, -creall(c
) / r
);
445 c
= e1
->toComplex() / e2
->toComplex();
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
);
462 n1
= e1
->toInteger();
463 n2
= e2
->toInteger();
465 { e2
->error("divide by 0");
466 e2
= new IntegerExp(0, 1, e2
->type
);
469 if (e1
->type
->isunsigned() || e2
->type
->isunsigned())
470 n
= ((d_uns64
) n1
) / ((d_uns64
) n2
);
473 e
= new IntegerExp(loc
, n
, type
);
478 Expression
*Mod(Type
*type
, Expression
*e1
, Expression
*e2
)
482 if (type
->isfloating())
486 if (e2
->type
->isreal())
487 { real_t r2
= e2
->toReal();
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
);
494 c
= complex_t(fmodl(e1
->toReal(), r2
), fmodl(e1
->toImaginary(), r2
));
497 else if (e2
->type
->isimaginary())
498 { real_t i2
= e2
->toImaginary();
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
);
505 c
= complex_t(fmodl(e1
->toReal(), i2
), fmodl(e1
->toImaginary(), i2
));
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
);
525 n1
= e1
->toInteger();
526 n2
= e2
->toInteger();
528 { e2
->error("divide by 0");
529 e2
= new IntegerExp(0, 1, e2
->type
);
532 if (e1
->type
->isunsigned() || e2
->type
->isunsigned())
533 n
= ((d_uns64
) n1
) % ((d_uns64
) n2
);
536 e
= new IntegerExp(loc
, n
, type
);
541 Expression
*Shl(Type
*type
, Expression
*e1
, Expression
*e2
)
545 e
= new IntegerExp(loc
, e1
->toInteger() << e2
->toInteger(), type
);
549 Expression
*Shr(Type
*type
, Expression
*e1
, Expression
*e2
)
555 value
= e1
->toInteger();
556 count
= e2
->toInteger();
557 switch (e1
->type
->toBasetype()->ty
)
560 value
= (d_int8
)(value
) >> count
;
564 value
= (d_uns8
)(value
) >> count
;
568 value
= (d_int16
)(value
) >> count
;
572 value
= (d_uns16
)(value
) >> count
;
576 value
= (d_int32
)(value
) >> count
;
580 value
= (d_uns32
)(value
) >> count
;
584 value
= (d_int64
)(value
) >> count
;
588 value
= (d_uns64
)(value
) >> count
;
594 e
= new IntegerExp(loc
, value
, type
);
598 Expression
*Ushr(Type
*type
, Expression
*e1
, Expression
*e2
)
604 value
= e1
->toInteger();
605 count
= e2
->toInteger();
606 switch (e1
->type
->toBasetype()->ty
)
610 assert(0); // no way to trigger this
611 value
= (value
& 0xFF) >> count
;
616 assert(0); // no way to trigger this
617 value
= (value
& 0xFFFF) >> count
;
622 value
= (value
& 0xFFFFFFFF) >> count
;
627 value
= (d_uns64
)(value
) >> count
;
633 e
= new IntegerExp(loc
, value
, type
);
637 Expression
*And(Type
*type
, Expression
*e1
, Expression
*e2
)
641 e
= new IntegerExp(loc
, e1
->toInteger() & e2
->toInteger(), type
);
645 Expression
*Or(Type
*type
, Expression
*e1
, Expression
*e2
)
649 e
= new IntegerExp(loc
, e1
->toInteger() | e2
->toInteger(), type
);
653 Expression
*Xor(Type
*type
, Expression
*e1
, Expression
*e2
)
657 e
= new IntegerExp(loc
, e1
->toInteger() ^ e2
->toInteger(), type
);
661 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
663 Expression
*Equal(enum TOK op
, Type
*type
, Expression
*e1
, Expression
*e2
)
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
)
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
);
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
);
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)
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
)
722 else if (es1
->elements
->dim
!= es2
->elements
->dim
)
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();
739 else if (e1
->op
== TOKarrayliteral
&& e2
->op
== TOKstring
)
740 { // Swap operands and use common code
746 else if (e1
->op
== TOKstring
&& e2
->op
== TOKarrayliteral
)
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;
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());
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
)
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
)
780 else if (es1
->elements
->dim
!= es2
->elements
->dim
)
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
];
795 Expression
*v
= Equal(TOKequal
, Type::tint32
, ee1
, ee2
);
796 if (v
== EXP_CANT_INTERPRET
)
797 return EXP_CANT_INTERPRET
;
798 cmp
= v
->toInteger();
804 #if 0 // Should handle this
805 else if (e1
->op
== TOKarrayliteral
&& e2
->op
== TOKstring
)
809 else if (e1
->isConst() != 1 || e2
->isConst() != 1)
810 return EXP_CANT_INTERPRET
;
811 else if (e1
->type
->isreal())
817 else if (e1
->type
->isimaginary())
819 r1
= e1
->toImaginary();
820 r2
= e2
->toImaginary();
826 if (r1
.isNan() || r2
.isNan()) // if unordered
828 if (isnan(r1
) || isnan(r2
)) // if unordered
839 else if (e1
->type
->iscomplex())
841 cmp
= e1
->toComplex() == e2
->toComplex();
843 else if (e1
->type
->isintegral())
845 cmp
= (e1
->toInteger() == e2
->toInteger());
848 return EXP_CANT_INTERPRET
;
849 if (op
== TOKnotequal
)
851 e
= new IntegerExp(loc
, cmp
, type
);
855 Expression
*Identity(enum TOK op
, Type
*type
, Expression
*e1
, Expression
*e2
)
860 if (e1
->op
== TOKnull
&& e2
->op
== TOKnull
)
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
,
876 if (op
== TOKnotidentity
)
878 return new IntegerExp(loc
, cmp
, type
);
882 Expression
*Cmp(enum TOK op
, Type
*type
, Expression
*e1
, Expression
*e2
)
889 //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
891 if (e1
->op
== TOKstring
&& e2
->op
== TOKstring
)
892 { StringExp
*es1
= (StringExp
*)e1
;
893 StringExp
*es2
= (StringExp
*)e2
;
895 assert(sz
== es2
->sz
);
897 size_t len
= es1
->len
;
903 cmp
= memcmp(es1
->string
, es2
->string
, sz
* len
);
906 const d_uns16
* p1
= (const d_uns16
*) es1
->string
;
907 const d_uns16
* p2
= (const d_uns16
*) es2
->string
;
908 for (size_t i
= 0; i
< len
; ++i
)
911 else if (p1
[i
] < p2
[i
])
916 const d_uns32
* p1
= (const d_uns32
*) es1
->string
;
917 const d_uns32
* p2
= (const d_uns32
*) es2
->string
;
918 for (size_t i
= 0; i
< len
; ++i
)
921 else if (p1
[i
] < p2
[i
])
928 cmp
= es1
->len
- es2
->len
;
932 case TOKlt
: n
= cmp
< 0; break;
933 case TOKle
: n
= cmp
<= 0; break;
934 case TOKgt
: n
= cmp
> 0; break;
935 case TOKge
: n
= cmp
>= 0; break;
937 case TOKleg
: n
= 1; break;
938 case TOKlg
: n
= cmp
!= 0; break;
939 case TOKunord
: n
= 0; break;
940 case TOKue
: n
= cmp
== 0; break;
941 case TOKug
: n
= cmp
> 0; break;
942 case TOKuge
: n
= cmp
>= 0; break;
943 case TOKul
: n
= cmp
< 0; break;
944 case TOKule
: n
= cmp
<= 0; break;
950 else if (e1
->isConst() != 1 || e2
->isConst() != 1)
951 return EXP_CANT_INTERPRET
;
952 else if (e1
->type
->isreal())
958 else if (e1
->type
->isimaginary())
960 r1
= e1
->toImaginary();
961 r2
= e2
->toImaginary();
964 // DMC is the only compiler I know of that handles NAN arguments
965 // correctly in comparisons.
968 case TOKlt
: n
= r1
< r2
; break;
969 case TOKle
: n
= r1
<= r2
; break;
970 case TOKgt
: n
= r1
> r2
; break;
971 case TOKge
: n
= r1
>= r2
; break;
973 case TOKleg
: n
= r1
<>= r2
; break;
974 case TOKlg
: n
= r1
<> r2
; break;
975 case TOKunord
: n
= r1
!<>= r2
; break;
976 case TOKue
: n
= r1
!<> r2
; break;
977 case TOKug
: n
= r1
!<= r2
; break;
978 case TOKuge
: n
= r1
!< r2
; break;
979 case TOKul
: n
= r1
!>= r2
; break;
980 case TOKule
: n
= r1
!> r2
; break;
986 // Don't rely on compiler, handle NAN arguments separately
988 if (r1
.isNan() || r2
.isNan()) // if unordered
990 if (isnan(r1
) || isnan(r2
)) // if unordered
995 case TOKlt
: n
= 0; break;
996 case TOKle
: n
= 0; break;
997 case TOKgt
: n
= 0; break;
998 case TOKge
: n
= 0; break;
1000 case TOKleg
: n
= 0; break;
1001 case TOKlg
: n
= 0; break;
1002 case TOKunord
: n
= 1; break;
1003 case TOKue
: n
= 1; break;
1004 case TOKug
: n
= 1; break;
1005 case TOKuge
: n
= 1; break;
1006 case TOKul
: n
= 1; break;
1007 case TOKule
: n
= 1; break;
1017 case TOKlt
: n
= r1
< r2
; break;
1018 case TOKle
: n
= r1
<= r2
; break;
1019 case TOKgt
: n
= r1
> r2
; break;
1020 case TOKge
: n
= r1
>= r2
; break;
1022 case TOKleg
: n
= 1; break;
1023 case TOKlg
: n
= r1
!= r2
; break;
1024 case TOKunord
: n
= 0; break;
1025 case TOKue
: n
= r1
== r2
; break;
1026 case TOKug
: n
= r1
> r2
; break;
1027 case TOKuge
: n
= r1
>= r2
; break;
1028 case TOKul
: n
= r1
< r2
; break;
1029 case TOKule
: n
= r1
<= r2
; break;
1037 else if (e1
->type
->iscomplex())
1045 n1
= e1
->toInteger();
1046 n2
= e2
->toInteger();
1047 if (e1
->type
->isunsigned() || e2
->type
->isunsigned())
1051 case TOKlt
: n
= ((d_uns64
) n1
) < ((d_uns64
) n2
); break;
1052 case TOKle
: n
= ((d_uns64
) n1
) <= ((d_uns64
) n2
); break;
1053 case TOKgt
: n
= ((d_uns64
) n1
) > ((d_uns64
) n2
); break;
1054 case TOKge
: n
= ((d_uns64
) n1
) >= ((d_uns64
) n2
); break;
1056 case TOKleg
: n
= 1; break;
1057 case TOKlg
: n
= ((d_uns64
) n1
) != ((d_uns64
) n2
); break;
1058 case TOKunord
: n
= 0; break;
1059 case TOKue
: n
= ((d_uns64
) n1
) == ((d_uns64
) n2
); break;
1060 case TOKug
: n
= ((d_uns64
) n1
) > ((d_uns64
) n2
); break;
1061 case TOKuge
: n
= ((d_uns64
) n1
) >= ((d_uns64
) n2
); break;
1062 case TOKul
: n
= ((d_uns64
) n1
) < ((d_uns64
) n2
); break;
1063 case TOKule
: n
= ((d_uns64
) n1
) <= ((d_uns64
) n2
); break;
1073 case TOKlt
: n
= n1
< n2
; break;
1074 case TOKle
: n
= n1
<= n2
; break;
1075 case TOKgt
: n
= n1
> n2
; break;
1076 case TOKge
: n
= n1
>= n2
; break;
1078 case TOKleg
: n
= 1; break;
1079 case TOKlg
: n
= n1
!= n2
; break;
1080 case TOKunord
: n
= 0; break;
1081 case TOKue
: n
= n1
== n2
; break;
1082 case TOKug
: n
= n1
> n2
; break;
1083 case TOKuge
: n
= n1
>= n2
; break;
1084 case TOKul
: n
= n1
< n2
; break;
1085 case TOKule
: n
= n1
<= n2
; break;
1092 e
= new IntegerExp(loc
, n
, type
);
1096 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
1097 * to: type to cast to
1098 * type: type to paint the result
1101 Expression
*Cast(Type
*type
, Type
*to
, Expression
*e1
)
1102 { Expression
*e
= EXP_CANT_INTERPRET
;
1105 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars());
1106 //printf("\te1->type = %s\n", e1->type->toChars());
1107 if (e1
->type
->equals(type
) && type
->equals(to
))
1109 if (e1
->type
->implicitConvTo(to
) >= MATCHconst
||
1110 to
->implicitConvTo(e1
->type
) >= MATCHconst
)
1111 return expType(to
, e1
);
1113 if (e1
->isConst() != 1)
1114 return EXP_CANT_INTERPRET
;
1116 Type
*tb
= to
->toBasetype();
1117 if (tb
->ty
== Tbool
)
1118 e
= new IntegerExp(loc
, e1
->toInteger() != 0, type
);
1119 else if (type
->isintegral())
1121 if (e1
->type
->isfloating())
1124 Type
* rt
= e1
->type
;
1125 if (rt
->iscomplex())
1127 switch (rt
->toBasetype()->ty
)
1129 case Tcomplex32
: rt
= Type::tfloat32
; break;
1130 case Tcomplex64
: rt
= Type::tfloat64
; break;
1131 case Tcomplex80
: rt
= Type::tfloat80
; break;
1135 d_int64 r
= e1
->toReal().toInt(rt
, type
);
1137 real_t r
= e1
->toReal();
1140 switch (type
->toBasetype()->ty
)
1142 case Tint8
: result
= (d_int8
)r
; break;
1144 case Tuns8
: result
= (d_uns8
)r
; break;
1145 case Tint16
: result
= (d_int16
)r
; break;
1147 case Tuns16
: result
= (d_uns16
)r
; break;
1148 case Tint32
: result
= (d_int32
)r
; break;
1150 case Tuns32
: result
= (d_uns32
)r
; break;
1151 case Tint64
: result
= (d_int64
)r
; break;
1152 case Tuns64
: result
= (d_uns64
)r
; break;
1157 e
= new IntegerExp(loc
, result
, type
);
1159 else if (type
->isunsigned())
1160 e
= new IntegerExp(loc
, e1
->toUInteger(), type
);
1162 e
= new IntegerExp(loc
, e1
->toInteger(), type
);
1164 else if (tb
->isreal())
1165 { real_t value
= e1
->toReal();
1167 e
= new RealExp(loc
, value
, type
);
1169 else if (tb
->isimaginary())
1170 { real_t value
= e1
->toImaginary();
1172 e
= new RealExp(loc
, value
, type
);
1174 else if (tb
->iscomplex())
1175 { complex_t value
= e1
->toComplex();
1177 e
= new ComplexExp(loc
, value
, type
);
1179 else if (tb
->isscalar())
1180 e
= new IntegerExp(loc
, e1
->toInteger(), type
);
1181 else if (tb
->ty
== Tvoid
)
1182 e
= EXP_CANT_INTERPRET
;
1183 else if (tb
->ty
== Tstruct
&& e1
->op
== TOKint64
)
1185 StructDeclaration
*sd
= tb
->toDsymbol(NULL
)->isStructDeclaration();
1187 Expressions
*elements
= new Expressions
;
1188 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
1189 { Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
1190 VarDeclaration
*v
= s
->isVarDeclaration();
1193 Expression
*exp
= new IntegerExp(0);
1194 exp
= Cast(v
->type
, v
->type
, exp
);
1195 if (exp
== EXP_CANT_INTERPRET
)
1197 elements
->push(exp
);
1199 e
= new StructLiteralExp(loc
, sd
, elements
);
1204 error(loc
, "cannot cast %s to %s", e1
->type
->toChars(), type
->toChars());
1205 e
= new IntegerExp(loc
, 0, type
);
1211 Expression
*ArrayLength(Type
*type
, Expression
*e1
)
1215 if (e1
->op
== TOKstring
)
1216 { StringExp
*es1
= (StringExp
*)e1
;
1218 e
= new IntegerExp(loc
, es1
->len
, type
);
1220 else if (e1
->op
== TOKarrayliteral
)
1221 { ArrayLiteralExp
*ale
= (ArrayLiteralExp
*)e1
;
1224 dim
= ale
->elements
? ale
->elements
->dim
: 0;
1225 e
= new IntegerExp(loc
, dim
, type
);
1227 else if (e1
->op
== TOKassocarrayliteral
)
1228 { AssocArrayLiteralExp
*ale
= (AssocArrayLiteralExp
*)e1
;
1229 size_t dim
= ale
->keys
->dim
;
1231 e
= new IntegerExp(loc
, dim
, type
);
1234 e
= EXP_CANT_INTERPRET
;
1238 /* Also return EXP_CANT_INTERPRET if this fails
1240 Expression
*Index(Type
*type
, Expression
*e1
, Expression
*e2
)
1241 { Expression
*e
= EXP_CANT_INTERPRET
;
1244 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1246 if (e1
->op
== TOKstring
&& e2
->op
== TOKint64
)
1247 { StringExp
*es1
= (StringExp
*)e1
;
1248 uinteger_t i
= e2
->toInteger();
1251 e1
->error("string index %"PRIuMAX
" is out of bounds [0 .. %"PRIuSIZE
"]", i
, es1
->len
);
1253 { unsigned value
= es1
->charAt(i
);
1254 e
= new IntegerExp(loc
, value
, type
);
1257 else if (e1
->type
->toBasetype()->ty
== Tsarray
&& e2
->op
== TOKint64
)
1258 { TypeSArray
*tsa
= (TypeSArray
*)e1
->type
->toBasetype();
1259 uinteger_t length
= tsa
->dim
->toInteger();
1260 uinteger_t i
= e2
->toInteger();
1263 { e2
->error("array index %"PRIuMAX
" is out of bounds %s[0 .. %"PRIuMAX
"]", i
, e1
->toChars(), length
);
1265 else if (e1
->op
== TOKarrayliteral
&& !e1
->checkSideEffect(2))
1266 { ArrayLiteralExp
*ale
= (ArrayLiteralExp
*)e1
;
1267 e
= (Expression
*)ale
->elements
->data
[i
];
1271 else if (e1
->type
->toBasetype()->ty
== Tarray
&& e2
->op
== TOKint64
)
1273 uinteger_t i
= e2
->toInteger();
1275 if (e1
->op
== TOKarrayliteral
&& !e1
->checkSideEffect(2))
1276 { ArrayLiteralExp
*ale
= (ArrayLiteralExp
*)e1
;
1277 if (i
>= ale
->elements
->dim
)
1278 { e2
->error("array index %ju is out of bounds %s[0 .. %u]", i
, e1
->toChars(), ale
->elements
->dim
);
1281 { e
= (Expression
*)ale
->elements
->data
[i
];
1286 else if (e1
->op
== TOKassocarrayliteral
&& !e1
->checkSideEffect(2))
1288 AssocArrayLiteralExp
*ae
= (AssocArrayLiteralExp
*)e1
;
1289 /* Search the keys backwards, in case there are duplicate keys
1291 for (size_t i
= ae
->keys
->dim
; i
;)
1294 Expression
*ekey
= (Expression
*)ae
->keys
->data
[i
];
1295 Expression
*ex
= Equal(TOKequal
, Type::tbool
, ekey
, e2
);
1296 if (ex
== EXP_CANT_INTERPRET
)
1298 if (ex
->isBool(TRUE
))
1299 { e
= (Expression
*)ae
->values
->data
[i
];
1308 /* Also return EXP_CANT_INTERPRET if this fails
1310 Expression
*Slice(Type
*type
, Expression
*e1
, Expression
*lwr
, Expression
*upr
)
1311 { Expression
*e
= EXP_CANT_INTERPRET
;
1315 printf("Slice()\n");
1317 { printf("\te1 = %s\n", e1
->toChars());
1318 printf("\tlwr = %s\n", lwr
->toChars());
1319 printf("\tupr = %s\n", upr
->toChars());
1322 if (e1
->op
== TOKstring
&& lwr
->op
== TOKint64
&& upr
->op
== TOKint64
)
1323 { StringExp
*es1
= (StringExp
*)e1
;
1324 uinteger_t ilwr
= lwr
->toInteger();
1325 uinteger_t iupr
= upr
->toInteger();
1327 if (iupr
> es1
->len
|| ilwr
> iupr
)
1328 e1
->error("string slice [%"PRIuMAX
" .. %"PRIuMAX
"] is out of bounds", ilwr
, iupr
);
1332 size_t len
= iupr
- ilwr
;
1336 s
= mem
.malloc((len
+ 1) * sz
);
1337 memcpy((unsigned char *)s
, (unsigned char *)es1
->string
+ ilwr
* sz
, len
* sz
);
1338 memset((unsigned char *)s
+ len
* sz
, 0, sz
);
1340 es
= new StringExp(loc
, s
, len
, es1
->postfix
);
1347 else if (e1
->op
== TOKarrayliteral
&&
1348 lwr
->op
== TOKint64
&& upr
->op
== TOKint64
&&
1349 !e1
->checkSideEffect(2))
1350 { ArrayLiteralExp
*es1
= (ArrayLiteralExp
*)e1
;
1351 uinteger_t ilwr
= lwr
->toInteger();
1352 uinteger_t iupr
= upr
->toInteger();
1354 if (iupr
> es1
->elements
->dim
|| ilwr
> iupr
)
1355 e1
->error("array slice [%"PRIuMAX
" .. %"PRIuMAX
"] is out of bounds", ilwr
, iupr
);
1358 Expressions
*elements
= new Expressions();
1359 elements
->setDim(iupr
- ilwr
);
1360 memcpy(elements
->data
,
1361 es1
->elements
->data
+ ilwr
,
1362 (iupr
- ilwr
) * sizeof(es1
->elements
->data
[0]));
1363 e
= new ArrayLiteralExp(e1
->loc
, elements
);
1370 /* Also return EXP_CANT_INTERPRET if this fails
1372 Expression
*Cat(Type
*type
, Expression
*e1
, Expression
*e2
)
1373 { Expression
*e
= EXP_CANT_INTERPRET
;
1376 Type
*t1
= e1
->type
->toBasetype();
1377 Type
*t2
= e2
->type
->toBasetype();
1379 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1380 //printf("\tt1 = %s, t2 = %s\n", t1->toChars(), t2->toChars());
1382 if (e1
->op
== TOKnull
&& (e2
->op
== TOKint64
|| e2
->op
== TOKstructliteral
))
1386 else if ((e1
->op
== TOKint64
|| e1
->op
== TOKstructliteral
) && e2
->op
== TOKnull
)
1389 Type
*tn
= e
->type
->toBasetype();
1390 if (tn
->ty
== Tchar
|| tn
->ty
== Twchar
|| tn
->ty
== Tdchar
)
1392 // Create a StringExp
1396 int sz
= tn
->size();
1397 integer_t v
= e
->toInteger();
1399 s
= mem
.malloc((len
+ 1) * sz
);
1402 case 1: *(d_uns8
*)s
= v
; break;
1403 case 2: *(d_uns16
*)s
= v
; break;
1404 case 4: *(d_uns32
*)s
= v
; break;
1408 // Add terminating 0
1409 memset((unsigned char *)s
+ len
* sz
, 0, sz
);
1411 es
= new StringExp(loc
, s
, len
);
1417 { // Create an ArrayLiteralExp
1418 Expressions
*elements
= new Expressions();
1420 e
= new ArrayLiteralExp(e
->loc
, elements
);
1425 else if (e1
->op
== TOKstring
&& e2
->op
== TOKstring
)
1427 // Concatenate the strings
1429 StringExp
*es1
= (StringExp
*)e1
;
1430 StringExp
*es2
= (StringExp
*)e2
;
1433 size_t len
= es1
->len
+ es2
->len
;
1436 assert(sz
== es2
->sz
);
1437 s
= mem
.malloc((len
+ 1) * sz
);
1438 memcpy(s
, es1
->string
, es1
->len
* sz
);
1439 memcpy((unsigned char *)s
+ es1
->len
* sz
, es2
->string
, es2
->len
* sz
);
1441 // Add terminating 0
1442 memset((unsigned char *)s
+ len
* sz
, 0, sz
);
1444 es
= new StringExp(loc
, s
, len
);
1446 es
->committed
= es1
->committed
| es2
->committed
;
1454 else if (e1
->op
== TOKstring
&& e2
->op
== TOKint64
)
1456 // Concatenate the strings
1459 StringExp
*es1
= (StringExp
*)e1
;
1462 size_t len
= es1
->len
+ 1;
1464 integer_t v
= e2
->toInteger();
1466 s
= mem
.malloc((len
+ 1) * sz
);
1467 memcpy(s
, es1
->string
, es1
->len
* sz
);
1468 sch
= (unsigned char *)s
+ es1
->len
* sz
;
1471 case 1: *(d_uns8
*)sch
= v
; break;
1472 case 2: *(d_uns16
*)sch
= v
; break;
1473 case 4: *(d_uns32
*)sch
= v
; break;
1477 // Add terminating 0
1478 memset((unsigned char *)s
+ len
* sz
, 0, sz
);
1480 es
= new StringExp(loc
, s
, len
);
1482 es
->committed
= es1
->committed
;
1487 else if (e1
->op
== TOKint64
&& e2
->op
== TOKstring
)
1489 // Concatenate the strings
1491 StringExp
*es2
= (StringExp
*)e2
;
1494 size_t len
= 1 + es2
->len
;
1496 integer_t v
= e1
->toInteger();
1498 s
= mem
.malloc((len
+ 1) * sz
);
1501 case 1: *(d_uns8
*)s
= v
; break;
1502 case 2: *(d_uns16
*)s
= v
; break;
1503 case 4: *(d_uns32
*)s
= v
; break;
1506 memcpy((unsigned char *)s
+ sz
, es2
->string
, es2
->len
* sz
);
1508 // Add terminating 0
1509 memset((unsigned char *)s
+ len
* sz
, 0, sz
);
1511 es
= new StringExp(loc
, s
, len
);
1513 es
->committed
= es2
->committed
;
1518 else if (e1
->op
== TOKarrayliteral
&& e2
->op
== TOKarrayliteral
&&
1519 t1
->nextOf()->equals(t2
->nextOf()))
1521 // Concatenate the arrays
1522 ArrayLiteralExp
*es1
= (ArrayLiteralExp
*)e1
;
1523 ArrayLiteralExp
*es2
= (ArrayLiteralExp
*)e2
;
1525 es1
= new ArrayLiteralExp(es1
->loc
, (Expressions
*)es1
->elements
->copy());
1526 es1
->elements
->insert(es1
->elements
->dim
, es2
->elements
);
1529 if (type
->toBasetype()->ty
== Tsarray
)
1531 e
->type
= new TypeSArray(t1
->nextOf(), new IntegerExp(0, es1
->elements
->dim
, Type::tindex
));
1532 e
->type
= e
->type
->semantic(loc
, NULL
);
1537 else if (e1
->op
== TOKarrayliteral
&&
1538 e1
->type
->toBasetype()->nextOf()->equals(e2
->type
))
1540 ArrayLiteralExp
*es1
= (ArrayLiteralExp
*)e1
;
1542 es1
= new ArrayLiteralExp(es1
->loc
, (Expressions
*)es1
->elements
->copy());
1543 es1
->elements
->push(e2
);
1546 if (type
->toBasetype()->ty
== Tsarray
)
1548 e
->type
= new TypeSArray(e2
->type
, new IntegerExp(0, es1
->elements
->dim
, Type::tindex
));
1549 e
->type
= e
->type
->semantic(loc
, NULL
);
1554 else if (e2
->op
== TOKarrayliteral
&&
1555 e2
->type
->toBasetype()->nextOf()->equals(e1
->type
))
1557 ArrayLiteralExp
*es2
= (ArrayLiteralExp
*)e2
;
1559 es2
= new ArrayLiteralExp(es2
->loc
, (Expressions
*)es2
->elements
->copy());
1560 es2
->elements
->shift(e1
);
1563 if (type
->toBasetype()->ty
== Tsarray
)
1565 e
->type
= new TypeSArray(e1
->type
, new IntegerExp(0, es2
->elements
->dim
, Type::tindex
));
1566 e
->type
= e
->type
->semantic(loc
, NULL
);
1571 else if (e1
->op
== TOKnull
&& e2
->op
== TOKstring
)
1577 else if (e1
->op
== TOKstring
&& e2
->op
== TOKnull
)
1581 Type
*tb
= t
->toBasetype();
1582 if (tb
->ty
== Tarray
&& tb
->nextOf()->equals(e
->type
))
1583 { Expressions
*expressions
= new Expressions();
1584 expressions
->push(e
);
1585 e
= new ArrayLiteralExp(loc
, expressions
);
1588 if (!e
->type
->equals(type
))
1589 { StringExp
*se
= (StringExp
*)e
->copy();
1590 e
= se
->castTo(NULL
, type
);
1596 Expression
*Ptr(Type
*type
, Expression
*e1
)
1598 //printf("Ptr(e1 = %s)\n", e1->toChars());
1599 if (e1
->op
== TOKadd
)
1600 { AddExp
*ae
= (AddExp
*)e1
;
1601 if (ae
->e1
->op
== TOKaddress
&& ae
->e2
->op
== TOKint64
)
1602 { AddrExp
*ade
= (AddrExp
*)ae
->e1
;
1603 if (ade
->e1
->op
== TOKstructliteral
)
1604 { StructLiteralExp
*se
= (StructLiteralExp
*)ade
->e1
;
1605 unsigned offset
= ae
->e2
->toInteger();
1606 Expression
*e
= se
->getField(type
, offset
);
1608 e
= EXP_CANT_INTERPRET
;
1613 return EXP_CANT_INTERPRET
;