Mercurial > projects > ddmd
annotate dmd/ArrayLiteralExp.d @ 192:eb38fdcb3e62 default tip
updated to compile with dmd2.062
author | korDen |
---|---|
date | Sat, 02 Mar 2013 01:25:52 -0800 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
72 | 1 module dmd.ArrayLiteralExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.backend.elem; | |
6 import dmd.InterState; | |
7 import dmd.MATCH; | |
8 import dmd.Type; | |
9 import dmd.OutBuffer; | |
10 import dmd.Loc; | |
0 | 11 import dmd.WANT; |
72 | 12 import dmd.Scope; |
13 import dmd.InlineCostState; | |
14 import dmd.IRState; | |
15 import dmd.InlineDoState; | |
16 import dmd.HdrGenState; | |
17 import dmd.backend.dt_t; | |
18 import dmd.InlineScanState; | |
123 | 19 import dmd.GlobalExpressions; |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
20 import dmd.Array; |
72 | 21 import dmd.ArrayTypes; |
0 | 22 import dmd.TOK; |
23 import dmd.IntegerExp; | |
24 import dmd.TypeSArray; | |
25 import dmd.TY; | |
26 import dmd.StringExp; | |
27 | |
28 import dmd.expression.Util; | |
29 import dmd.backend.Util; | |
30 import dmd.backend.RTLSYM; | |
72 | 31 import dmd.backend.OPER; |
68
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
63
diff
changeset
|
32 import dmd.backend.Symbol; |
0 | 33 import dmd.backend.TYM; |
72 | 34 import dmd.backend.mTY; |
35 import dmd.codegen.Util; | |
36 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
37 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
38 |
0 | 39 class ArrayLiteralExp : Expression |
40 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
41 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
42 |
0 | 43 Expressions elements; |
44 | |
45 this(Loc loc, Expressions elements) | |
72 | 46 { |
178 | 47 register(); |
0 | 48 super(loc, TOK.TOKarrayliteral, ArrayLiteralExp.sizeof); |
49 this.elements = elements; | |
50 } | |
51 | |
52 this(Loc loc, Expression e) | |
53 { | |
178 | 54 register(); |
0 | 55 super(loc, TOK.TOKarrayliteral, ArrayLiteralExp.sizeof); |
56 elements = new Expressions(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
57 elements.push(e); |
0 | 58 } |
59 | |
72 | 60 override Expression syntaxCopy() |
0 | 61 { |
62 return new ArrayLiteralExp(loc, arraySyntaxCopy(elements)); | |
63 } | |
64 | |
72 | 65 override Expression semantic(Scope sc) |
0 | 66 { |
67 version (LOGSEMANTIC) { | |
68 printf("ArrayLiteralExp.semantic('%s')\n", toChars()); | |
69 } | |
70 if (type) | |
71 return this; | |
72 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
73 arrayExpressionSemantic(elements, sc); // run semantic() on each element |
0 | 74 |
75 expandTuples(elements); | |
76 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
77 Type t0; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
78 elements = arrayExpressionToCommonType(sc, elements, &t0); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
79 |
0 | 80 type = new TypeSArray(t0, new IntegerExp(elements.dim)); |
81 type = type.semantic(loc, sc); | |
82 return this; | |
83 } | |
84 | |
72 | 85 override bool isBool(bool result) |
0 | 86 { |
87 size_t dim = elements ? elements.dim : 0; | |
88 return result ? (dim != 0) : (dim == 0); | |
89 } | |
90 | |
72 | 91 override elem* toElem(IRState* irs) |
0 | 92 { |
93 elem* e; | |
94 size_t dim; | |
95 | |
96 //printf("ArrayLiteralExp.toElem() %s\n", toChars()); | |
97 if (elements) | |
98 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
99 scope args = new Array(); // ddmd was Expressions |
0 | 100 dim = elements.dim; |
101 args.setDim(dim + 1); // +1 for number of args parameter | |
102 e = el_long(TYint, dim); | |
103 args.data[dim] = cast(void*)e; | |
104 for (size_t i = 0; i < dim; i++) | |
105 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
106 auto el = elements[i]; |
0 | 107 elem* ep = el.toElem(irs); |
108 | |
109 if (tybasic(ep.Ety) == TYstruct || tybasic(ep.Ety) == TYarray) | |
110 { | |
111 ep = el_una(OPstrpar, TYstruct, ep); | |
112 ep.Enumbytes = cast(uint)el.type.size(); | |
113 } | |
114 args.data[dim - (i + 1)] = cast(void *)ep; | |
115 } | |
116 | |
117 /* Because the number of parameters can get very large, produce | |
118 * a balanced binary tree so we don't blow up the stack in | |
119 * the subsequent tree walking code. | |
120 */ | |
121 e = el_params(args.data, dim + 1); | |
122 } | |
123 else | |
124 { | |
125 dim = 0; | |
126 e = el_long(TYint, 0); | |
127 } | |
128 Type tb = type.toBasetype(); | |
129 static if (true) { | |
130 e = el_param(e, type.getTypeInfo(null).toElem(irs)); | |
131 | |
132 // call _d_arrayliteralT(ti, dim, ...) | |
133 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); | |
134 } else { | |
135 e = el_param(e, el_long(TYint, tb.next.size())); | |
136 | |
137 // call _d_arrayliteral(size, dim, ...) | |
138 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); | |
139 } | |
140 if (tb.ty == Tarray) | |
141 { | |
142 e = el_pair(TYullong, el_long(TYint, dim), e); | |
143 } | |
144 else if (tb.ty == Tpointer) | |
145 { | |
146 } | |
147 else | |
148 { | |
149 e = el_una(OPind,TYstruct,e); | |
150 e.Enumbytes = cast(uint)type.size(); | |
151 } | |
152 | |
153 el_setLoc(e,loc); | |
154 return e; | |
155 } | |
156 | |
72 | 157 override bool checkSideEffect(int flag) |
0 | 158 { |
159 bool f = false; | |
160 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
161 foreach (e; elements) |
0 | 162 { |
163 f |= e.checkSideEffect(2); | |
164 } | |
165 if (flag == 0 && f == false) | |
166 Expression.checkSideEffect(0); | |
167 | |
168 return f; | |
169 } | |
170 | |
72 | 171 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 172 { |
173 buf.writeByte('['); | |
174 argsToCBuffer(buf, elements, hgs); | |
175 buf.writeByte(']'); | |
176 } | |
177 | |
72 | 178 override void toMangleBuffer(OutBuffer buf) |
0 | 179 { |
180 size_t dim = elements ? elements.dim : 0; | |
162 | 181 buf.printf("A%d", dim); /// |
0 | 182 for (size_t i = 0; i < dim; i++) |
183 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
184 auto e = elements[i]; |
0 | 185 e.toMangleBuffer(buf); |
186 } | |
187 } | |
188 | |
72 | 189 override void scanForNestedRef(Scope sc) |
0 | 190 { |
191 assert(false); | |
192 } | |
193 | |
72 | 194 override Expression optimize(int result) |
0 | 195 { |
196 if (elements) | |
197 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
198 foreach (ref Expression e; elements) |
0 | 199 { |
200 e = e.optimize(WANTvalue | (result & WANTinterpret)); | |
201 } | |
202 } | |
203 | |
204 return this; | |
205 } | |
206 | |
72 | 207 override Expression interpret(InterState istate) |
0 | 208 { |
123 | 209 Expressions expsx = null; |
210 | |
211 version (LOG) { | |
212 printf("ArrayLiteralExp.interpret() %.*s\n", toChars()); | |
213 } | |
214 if (elements) | |
215 { | |
216 foreach (size_t i, Expression e; elements) | |
217 { | |
218 Expression ex; | |
219 | |
220 ex = e.interpret(istate); | |
221 if (ex is EXP_CANT_INTERPRET) | |
135 | 222 goto Lerror; |
123 | 223 |
224 /* If any changes, do Copy On Write | |
225 */ | |
226 if (ex != e) | |
227 { | |
228 if (!expsx) | |
229 { | |
230 expsx = new Expressions(); | |
231 expsx.setDim(elements.dim); | |
232 for (size_t j = 0; j < elements.dim; j++) | |
233 { | |
234 expsx[j] = elements[j]; | |
235 } | |
236 } | |
237 expsx[i] = ex; | |
238 } | |
239 } | |
240 } | |
241 if (elements && expsx) | |
242 { | |
243 expandTuples(expsx); | |
244 if (expsx.dim != elements.dim) | |
135 | 245 goto Lerror; |
123 | 246 |
247 ArrayLiteralExp ae = new ArrayLiteralExp(loc, expsx); | |
248 ae.type = type; | |
249 | |
250 return ae; | |
251 } | |
252 return this; | |
135 | 253 |
254 Lerror: | |
255 if (expsx) | |
256 delete expsx; | |
257 error("cannot interpret array literal"); | |
258 return EXP_CANT_INTERPRET; | |
0 | 259 } |
260 | |
72 | 261 override MATCH implicitConvTo(Type t) |
0 | 262 { |
263 MATCH result = MATCHexact; | |
264 | |
265 static if (false) { | |
266 printf("ArrayLiteralExp.implicitConvTo(this=%s, type=%s, t=%s)\n", | |
267 toChars(), type.toChars(), t.toChars()); | |
268 } | |
269 Type typeb = type.toBasetype(); | |
270 Type tb = t.toBasetype(); | |
271 if ((tb.ty == Tarray || tb.ty == Tsarray) && | |
272 (typeb.ty == Tarray || typeb.ty == Tsarray)) | |
273 { | |
274 if (tb.ty == Tsarray) | |
275 { | |
276 TypeSArray tsa = cast(TypeSArray)tb; | |
277 if (elements.dim != tsa.dim.toInteger()) | |
278 result = MATCHnomatch; | |
279 } | |
280 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
281 foreach (e; elements) |
0 | 282 { |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
283 auto m = cast(MATCH)e.implicitConvTo(tb.nextOf()); |
0 | 284 if (m < result) |
285 result = m; // remember worst match | |
286 if (result == MATCHnomatch) | |
287 break; // no need to check for worse | |
288 } | |
289 return result; | |
290 } | |
291 else | |
292 return Expression.implicitConvTo(t); | |
293 } | |
294 | |
72 | 295 override Expression castTo(Scope sc, Type t) |
0 | 296 { |
297 static if (false) { | |
298 printf("ArrayLiteralExp.castTo(this=%s, type=%s, => %s)\n", | |
299 toChars(), type.toChars(), t.toChars()); | |
300 } | |
301 if (type == t) | |
302 return this; | |
303 ArrayLiteralExp e = this; | |
304 Type typeb = type.toBasetype(); | |
305 Type tb = t.toBasetype(); | |
306 if ((tb.ty == Tarray || tb.ty == Tsarray) && | |
307 (typeb.ty == Tarray || typeb.ty == Tsarray) && | |
308 // Not trying to convert non-void[] to void[] | |
309 !(tb.nextOf().toBasetype().ty == Tvoid && typeb.nextOf().toBasetype().ty != Tvoid)) | |
310 { | |
311 if (tb.ty == Tsarray) | |
312 { | |
313 TypeSArray tsa = cast(TypeSArray)tb; | |
314 if (elements.dim != tsa.dim.toInteger()) | |
315 goto L1; | |
316 } | |
317 | |
318 e = cast(ArrayLiteralExp)copy(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
319 e.elements = elements.copy(); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
320 foreach (size_t i, Expression ex; elements) |
0 | 321 { |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
322 e.elements[i] = ex.castTo(sc, tb.nextOf()); |
0 | 323 } |
324 e.type = t; | |
325 return e; | |
326 } | |
327 if (tb.ty == Tpointer && typeb.ty == Tsarray) | |
328 { | |
329 Type tp = typeb.nextOf().pointerTo(); | |
330 if (!tp.equals(e.type)) | |
331 { | |
332 e = cast(ArrayLiteralExp)copy(); | |
333 e.type = tp; | |
334 } | |
335 } | |
336 L1: | |
337 return e.Expression.castTo(sc, t); | |
338 } | |
339 | |
72 | 340 override dt_t** toDt(dt_t** pdt) |
0 | 341 { |
72 | 342 //printf("ArrayLiteralExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); |
343 | |
344 dt_t *d; | |
345 dt_t **pdtend; | |
346 | |
347 d = null; | |
348 pdtend = &d; | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
349 foreach (e; elements) |
72 | 350 { |
351 pdtend = e.toDt(pdtend); | |
352 } | |
353 Type t = type.toBasetype(); | |
354 | |
355 switch (t.ty) | |
356 { | |
357 case Tsarray: | |
358 pdt = dtcat(pdt, d); | |
359 break; | |
360 | |
361 case Tpointer: | |
362 case Tarray: | |
363 if (t.ty == Tarray) | |
364 dtdword(pdt, elements.dim); | |
365 if (d) | |
366 { | |
367 // Create symbol, and then refer to it | |
368 Symbol* s; | |
369 s = static_sym(); | |
370 s.Sdt = d; | |
371 outdata(s); | |
372 | |
373 dtxoff(pdt, s, 0, TYnptr); | |
374 } | |
375 else | |
376 dtdword(pdt, 0); | |
377 | |
378 break; | |
379 | |
380 default: | |
381 assert(0); | |
382 } | |
68
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
63
diff
changeset
|
383 return pdt; |
0 | 384 } |
385 | |
386 version (DMDV2) { | |
72 | 387 override bool canThrow() |
0 | 388 { |
389 return 1; // because it can fail allocating memory | |
390 } | |
391 } | |
72 | 392 override int inlineCost(InlineCostState* ics) |
0 | 393 { |
394 return 1 + arrayInlineCost(ics, elements); | |
395 } | |
396 | |
72 | 397 override Expression doInline(InlineDoState ids) |
0 | 398 { |
399 ArrayLiteralExp ce = cast(ArrayLiteralExp)copy(); | |
400 ce.elements = arrayExpressiondoInline(elements, ids); | |
401 return ce; | |
402 } | |
403 | |
72 | 404 override Expression inlineScan(InlineScanState* iss) |
0 | 405 { |
406 Expression e = this; | |
407 | |
408 //printf("ArrayLiteralExp.inlineScan()\n"); | |
409 arrayInlineScan(iss, elements); | |
410 | |
411 return e; | |
412 } | |
413 } | |
414 |