Mercurial > projects > ddmd
annotate dmd/CatExp.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | e8a741997ccf |
children | b0d41ff5e0df |
rev | line source |
---|---|
72 | 1 module dmd.CatExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.Identifier; | |
6 import dmd.InterState; | |
7 import dmd.Loc; | |
8 import dmd.Scope; | |
9 import dmd.IRState; | |
10 import dmd.BinExp; | |
0 | 11 import dmd.TOK; |
12 import dmd.Type; | |
13 import dmd.TY; | |
14 import dmd.MATCH; | |
15 import dmd.ArrayLiteralExp; | |
16 import dmd.StringExp; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
17 import dmd.ErrorExp; |
0 | 18 import dmd.WANT; |
19 import dmd.Id; | |
72 | 20 import dmd.GlobalExpressions; |
21 | |
0 | 22 import dmd.backend.elem; |
23 import dmd.backend.Util; | |
24 import dmd.backend.TYM; | |
25 import dmd.backend.OPER; | |
26 import dmd.backend.RTLSYM; | |
27 import dmd.codegen.Util; | |
72 | 28 import dmd.expression.Cat; |
29 | |
0 | 30 class CatExp : BinExp |
31 { | |
32 this(Loc loc, Expression e1, Expression e2) | |
33 { | |
178 | 34 register(); |
35 | |
0 | 36 super(loc, TOK.TOKcat, CatExp.sizeof, e1, e2); |
37 } | |
38 | |
72 | 39 override Expression semantic(Scope sc) |
0 | 40 { |
41 Expression e; | |
42 | |
43 //printf("CatExp.semantic() %s\n", toChars()); | |
44 if (!type) | |
45 { | |
46 BinExp.semanticp(sc); | |
47 e = op_overload(sc); | |
48 if (e) | |
49 return e; | |
50 | |
51 Type tb1 = e1.type.toBasetype(); | |
52 Type tb2 = e2.type.toBasetype(); | |
53 | |
54 | |
55 /* BUG: Should handle things like: | |
56 * char c; | |
57 * c ~ ' ' | |
58 * ' ' ~ c; | |
59 */ | |
60 | |
61 static if (false) { | |
62 e1.type.print(); | |
63 e2.type.print(); | |
64 } | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
65 Type tb1next = tb1.nextOf(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
66 Type tb2next = tb2.nextOf(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
67 |
0 | 68 if ((tb1.ty == Tsarray || tb1.ty == Tarray) && |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
69 e2.implicitConvTo(tb1next) >= MATCHconvert) |
0 | 70 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
71 e2 = e2.implicitCastTo(sc, tb1next); |
133
e8a741997ccf
Fix update bugs
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
130
diff
changeset
|
72 type = tb1next.arrayOf(); |
0 | 73 if (tb2.ty == Tarray) |
74 { | |
75 // Make e2 into [e2] | |
76 e2 = new ArrayLiteralExp(e2.loc, e2); | |
77 e2.type = type; | |
78 } | |
79 return this; | |
80 } | |
81 else if ((tb2.ty == Tsarray || tb2.ty == Tarray) && | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
82 e1.implicitConvTo(tb2next) >= MATCHconvert) |
0 | 83 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
84 e1 = e1.implicitCastTo(sc, tb2next); |
133
e8a741997ccf
Fix update bugs
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
130
diff
changeset
|
85 type = tb2next.arrayOf(); |
0 | 86 if (tb1.ty == Tarray) |
87 { | |
88 // Make e1 into [e1] | |
89 e1 = new ArrayLiteralExp(e1.loc, e1); | |
90 e1.type = type; | |
91 } | |
92 return this; | |
93 } | |
94 | |
95 if ((tb1.ty == Tsarray || tb1.ty == Tarray) && | |
96 (tb2.ty == Tsarray || tb2.ty == Tarray) && | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
97 (tb1next.mod || tb2next.mod) && |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
98 (tb1next.mod != tb2next.mod) |
0 | 99 ) |
100 { | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
101 Type t1 = tb1next.mutableOf().constOf().arrayOf(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
102 Type t2 = tb2next.mutableOf().constOf().arrayOf(); |
0 | 103 if (e1.op == TOKstring && !(cast(StringExp)e1).committed) |
104 e1.type = t1; | |
105 else | |
106 e1 = e1.castTo(sc, t1); | |
107 if (e2.op == TOKstring && !(cast(StringExp)e2).committed) | |
108 e2.type = t2; | |
109 else | |
110 e2 = e2.castTo(sc, t2); | |
111 } | |
112 | |
113 typeCombine(sc); | |
114 type = type.toHeadMutable(); | |
115 | |
116 Type tb = type.toBasetype(); | |
117 if (tb.ty == Tsarray) | |
118 type = tb.nextOf().arrayOf(); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
119 if (type.ty == Tarray && tb1next && tb2next && |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
120 tb1next.mod != tb2next.mod) |
0 | 121 { |
122 type = type.nextOf().toHeadMutable().arrayOf(); | |
123 } | |
124 static if (false) { | |
125 e1.type.print(); | |
126 e2.type.print(); | |
127 type.print(); | |
128 print(); | |
129 } | |
130 Type t1 = e1.type.toBasetype(); | |
131 Type t2 = e2.type.toBasetype(); | |
132 if (e1.op == TOKstring && e2.op == TOKstring) | |
133 e = optimize(WANTvalue); | |
134 else if ((t1.ty == Tarray || t1.ty == Tsarray) && | |
135 (t2.ty == Tarray || t2.ty == Tsarray)) | |
136 { | |
137 e = this; | |
138 } | |
139 else | |
140 { | |
141 //printf("(%s) ~ (%s)\n", e1.toChars(), e2.toChars()); | |
142 error("Can only concatenate arrays, not (%s ~ %s)", | |
143 e1.type.toChars(), e2.type.toChars()); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
144 return new ErrorExp(); |
0 | 145 } |
146 e.type = e.type.semantic(loc, sc); | |
147 return e; | |
148 } | |
149 return this; | |
150 } | |
151 | |
72 | 152 override Expression optimize(int result) |
0 | 153 { |
154 //printf("CatExp::optimize(%d) %s\n", result, toChars()); | |
155 e1 = e1.optimize(result); | |
156 e2 = e2.optimize(result); | |
157 Expression e = Cat(type, e1, e2); | |
158 if (e is EXP_CANT_INTERPRET) | |
159 e = this; | |
160 | |
161 return e; | |
162 } | |
163 | |
72 | 164 override Expression interpret(InterState istate) |
0 | 165 { |
72 | 166 Expression e; |
167 Expression e1; | |
168 Expression e2; | |
169 | |
170 version (LOG) { | |
171 printf("CatExp.interpret() %.*s\n", toChars()); | |
172 } | |
173 e1 = this.e1.interpret(istate); | |
174 if (e1 is EXP_CANT_INTERPRET) | |
175 { | |
176 goto Lcant; | |
177 } | |
178 e2 = this.e2.interpret(istate); | |
179 if (e2 is EXP_CANT_INTERPRET) | |
180 goto Lcant; | |
181 return Cat(type, e1, e2); | |
182 | |
183 Lcant: | |
184 version (LOG) { | |
185 printf("CatExp.interpret() %.*s CANT\n", toChars()); | |
186 } | |
63 | 187 return EXP_CANT_INTERPRET; |
0 | 188 } |
189 | |
72 | 190 override Identifier opId() |
0 | 191 { |
192 return Id.cat; | |
193 } | |
194 | |
72 | 195 override Identifier opId_r() |
0 | 196 { |
197 return Id.cat_r; | |
198 } | |
199 | |
72 | 200 override elem* toElem(IRState* irs) |
0 | 201 { |
202 elem *e; | |
203 | |
204 static if (false) { | |
205 printf("CatExp::toElem()\n"); | |
206 print(); | |
207 } | |
208 | |
209 Type tb1 = e1.type.toBasetype(); | |
210 Type tb2 = e2.type.toBasetype(); | |
211 Type tn; | |
212 | |
213 ///static if (false) { | |
214 /// if ((tb1.ty == Tarray || tb1.ty == Tsarray) && | |
215 /// (tb2.ty == Tarray || tb2.ty == Tsarray) | |
216 /// ) | |
217 ///} | |
218 | |
219 Type ta = tb1.nextOf() ? e1.type : e2.type; | |
220 tn = tb1.nextOf() ? tb1.nextOf() : tb2.nextOf(); | |
221 { | |
222 if (e1.op == TOKcat) | |
223 { | |
224 elem* ep; | |
225 CatExp ce = this; | |
226 int n = 2; | |
227 | |
228 ep = eval_Darray(irs, ce.e2); | |
229 do | |
230 { | |
231 n++; | |
232 ce = cast(CatExp)ce.e1; | |
233 ep = el_param(ep, eval_Darray(irs, ce.e2)); | |
234 } while (ce.e1.op == TOKcat); | |
235 | |
236 ep = el_param(ep, eval_Darray(irs, ce.e1)); | |
237 static if (true) { | |
238 ep = el_params( | |
239 ep, | |
240 el_long(TYint, n), | |
241 ta.getTypeInfo(null).toElem(irs), | |
242 null); | |
243 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep); | |
244 } else { | |
245 ep = el_params( | |
246 ep, | |
247 el_long(TYint, n), | |
248 el_long(TYint, tn.size()), | |
249 null); | |
250 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); | |
251 } | |
252 } | |
253 else | |
254 { | |
255 elem *e1; | |
256 elem *e2; | |
257 elem *ep; | |
258 | |
259 e1 = eval_Darray(irs, this.e1); | |
260 e2 = eval_Darray(irs, this.e2); | |
261 static if (true) { | |
262 ep = el_params(e2, e1, ta.getTypeInfo(null).toElem(irs), null); | |
263 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATT]), ep); | |
264 } else { | |
265 ep = el_params(el_long(TYint, tn.size()), e2, e1, null); | |
266 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCAT]), ep); | |
267 } | |
268 } | |
269 el_setLoc(e,loc); | |
270 } | |
271 /// static if (false) { | |
272 /// else if ((tb1.ty == Tarray || tb1.ty == Tsarray) && | |
273 /// e2.type.equals(tb1.next)) | |
274 /// { | |
275 /// error("array cat with element not implemented"); | |
276 /// e = el_long(TYint, 0); | |
277 /// } | |
278 /// else | |
279 /// assert(0); | |
280 /// } | |
281 return e; | |
282 } | |
283 } | |
284 |