comparison dmd/MinExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 832f71e6f96c
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.MinExp;
2
3 import dmd.Expression;
4 import dmd.TY;
5 import dmd.ErrorExp;
6 import dmd.Identifier;
7 import dmd.IntegerExp;
8 import dmd.DivExp;
9 import dmd.Type;
10 import dmd.InterState;
11 import dmd.OutBuffer;
12 import dmd.Loc;
13 import dmd.Scope;
14 import dmd.IRState;
15 import dmd.ArrayTypes;
16 import dmd.BinExp;
17 import dmd.TOK;
18 import dmd.Id;
19 import dmd.expression.Min;
20
21 import dmd.backend.elem;
22 import dmd.backend.Util;
23 import dmd.backend.OPER;
24
25 class MinExp : BinExp
26 {
27 this(Loc loc, Expression e1, Expression e2)
28 {
29 super(loc, TOK.TOKmin, MinExp.sizeof, e1, e2);
30 }
31
32 Expression semantic(Scope sc)
33 {
34 Expression e;
35 Type t1;
36 Type t2;
37
38 version (LOGSEMANTIC) {
39 printf("MinExp.semantic('%s')\n", toChars());
40 }
41 if (type)
42 return this;
43
44 super.semanticp(sc);
45
46 e = op_overload(sc);
47 if (e)
48 return e;
49
50 e = this;
51 t1 = e1.type.toBasetype();
52 t2 = e2.type.toBasetype();
53 if (t1.ty == TY.Tpointer)
54 {
55 if (t2.ty == TY.Tpointer)
56 { // Need to divide the result by the stride
57 // Replace (ptr - ptr) with (ptr - ptr) / stride
58 long stride;
59 Expression ee;
60
61 typeCombine(sc); // make sure pointer types are compatible
62 type = Type.tptrdiff_t;
63 stride = t2.nextOf().size();
64 if (stride == 0)
65 {
66 ee = new IntegerExp(loc, 0, Type.tptrdiff_t);
67 }
68 else
69 {
70 ee = new DivExp(loc, this, new IntegerExp(Loc(0), stride, Type.tptrdiff_t));
71 ee.type = Type.tptrdiff_t;
72 }
73 return ee;
74 }
75 else if (t2.isintegral())
76 e = scaleFactor(sc);
77 else
78 {
79 error("incompatible types for minus");
80 return new ErrorExp();
81 }
82 }
83 else if (t2.ty == TY.Tpointer)
84 {
85 type = e2.type;
86 error("can't subtract pointer from %s", e1.type.toChars());
87 return new ErrorExp();
88 }
89 else
90 {
91 typeCombine(sc);
92 t1 = e1.type.toBasetype();
93 t2 = e2.type.toBasetype();
94 if ((t1.isreal() && t2.isimaginary()) ||
95 (t1.isimaginary() && t2.isreal()))
96 {
97 switch (type.ty)
98 {
99 case TY.Tfloat32:
100 case TY.Timaginary32:
101 type = Type.tcomplex32;
102 break;
103
104 case TY.Tfloat64:
105 case TY.Timaginary64:
106 type = Type.tcomplex64;
107 break;
108
109 case TY.Tfloat80:
110 case TY.Timaginary80:
111 type = Type.tcomplex80;
112 break;
113
114 default:
115 assert(0);
116 }
117 }
118 }
119 return e;
120 }
121
122 Expression optimize(int result)
123 {
124 Expression e;
125
126 e1 = e1.optimize(result);
127 e2 = e2.optimize(result);
128 if (e1.isConst() && e2.isConst())
129 {
130 if (e2.op == TOK.TOKsymoff)
131 return this;
132 e = Min(type, e1, e2);
133 }
134 else
135 e = this;
136
137 return e;
138 }
139
140 Expression interpret(InterState* istate)
141 {
142 assert(false);
143 }
144
145 void buildArrayIdent(OutBuffer buf, Expressions arguments)
146 {
147 assert(false);
148 }
149
150 Expression buildArrayLoop(Arguments fparams)
151 {
152 assert(false);
153 }
154
155 Identifier opId()
156 {
157 return Id.sub;
158 }
159
160 Identifier opId_r()
161 {
162 return Id.sub_r;
163 }
164
165 elem* toElem(IRState* irs)
166 {
167 Type tb1 = e1.type.toBasetype();
168 Type tb2 = e2.type.toBasetype();
169
170 if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray))
171 {
172 error("Array operation %s not implemented", toChars());
173 return el_long(type.totym(), 0); // error recovery
174 }
175
176 return toElemBin(irs, OPER.OPmin);
177 }
178 }
179