Mercurial > projects > ddmd
annotate dmd/BinExp.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 | fa9a71a9f5a8 |
children | cd48cb899aee |
rev | line source |
---|---|
0 | 1 module dmd.BinExp; |
2 | |
114 | 3 import dmd.common; |
63 | 4 import dmd.SliceExp; |
5 import dmd.IndexExp; | |
6 import dmd.StructDeclaration; | |
7 import dmd.expression.ArrayLength; | |
8 import dmd.expression.Equal; | |
9 import dmd.expression.Index; | |
10 import dmd.ArrayLiteralExp; | |
11 import dmd.AssocArrayLiteralExp; | |
12 import dmd.StringExp; | |
13 import dmd.TypeSArray; | |
14 import dmd.PtrExp; | |
15 import dmd.SymOffExp; | |
16 import dmd.Declaration; | |
17 import dmd.StructLiteralExp; | |
0 | 18 import dmd.Expression; |
63 | 19 import dmd.interpret.Util; |
20 import dmd.GlobalExpressions; | |
176 | 21 import dmd.Global; |
63 | 22 import dmd.Cast; |
23 import dmd.CastExp; | |
24 import dmd.VarDeclaration; | |
25 import dmd.DotVarExp; | |
0 | 26 import dmd.Loc; |
27 import dmd.ClassDeclaration; | |
28 import dmd.OutBuffer; | |
29 import dmd.HdrGenState; | |
30 import dmd.TOK; | |
31 import dmd.IRState; | |
32 import dmd.Scope; | |
33 import dmd.Type; | |
34 import dmd.InterState; | |
35 import dmd.InlineCostState; | |
36 import dmd.InlineScanState; | |
37 import dmd.InlineDoState; | |
38 import dmd.AggregateDeclaration; | |
39 import dmd.Identifier; | |
40 import dmd.MATCH; | |
41 import dmd.declaration.Match; | |
42 import dmd.ArrayTypes; | |
43 import dmd.TY; | |
44 import dmd.TypeClass; | |
45 import dmd.TypeStruct; | |
46 import dmd.Dsymbol; | |
47 import dmd.FuncDeclaration; | |
48 import dmd.TemplateDeclaration; | |
49 import dmd.DotIdExp; | |
50 import dmd.ErrorExp; | |
51 import dmd.WANT; | |
52 import dmd.IntegerExp; | |
53 import dmd.MulExp; | |
54 import dmd.Token; | |
55 import dmd.PREC; | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
56 import dmd.StringValue; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
57 import dmd.StringTable; |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
58 import dmd.Parameter; |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
59 import dmd.Statement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
60 import dmd.ForeachRangeStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
61 import dmd.ArrayLengthExp; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
62 import dmd.IdentifierExp; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
63 import dmd.ExpStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
64 import dmd.CompoundStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
65 import dmd.TypeFunction; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
66 import dmd.LINK; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
67 import dmd.Lexer; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
68 import dmd.ReturnStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
69 import dmd.Id; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
70 import dmd.STC; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
71 import dmd.PROT; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
72 import dmd.VarExp; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
73 import dmd.CallExp; |
0 | 74 |
75 import dmd.expression.Util; | |
76 | |
77 import dmd.backend.elem; | |
78 import dmd.backend.Util; | |
79 | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
80 import dmd.backend.iasm : binary; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
81 |
63 | 82 import std.exception : assumeUnique; |
83 import core.stdc.stdlib : calloc; | |
0 | 84 import std.stdio : writef; |
85 | |
86 /************************************** | |
87 * Combine types. | |
88 * Output: | |
89 * *pt merged type, if *pt is not null | |
90 * *pe1 rewritten e1 | |
91 * *pe2 rewritten e2 | |
92 * Returns: | |
93 * !=0 success | |
94 * 0 failed | |
95 */ | |
96 | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
97 /************************************** |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
98 * Hash table of array op functions already generated or known about. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
99 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
100 |
0 | 101 int typeMerge(Scope sc, Expression e, Type* pt, Expression* pe1, Expression* pe2) |
102 { | |
60 | 103 //printf("typeMerge() %.*s op %.*s\n", (*pe1).toChars(), (*pe2).toChars()); |
0 | 104 //dump(0); |
105 | |
106 Expression e1 = (*pe1).integralPromotions(sc); | |
107 Expression e2 = (*pe2).integralPromotions(sc); | |
108 | |
109 Type t1 = e1.type; | |
110 Type t2 = e2.type; | |
111 assert(t1); | |
112 Type t = t1; | |
113 | |
114 //if (t1) printf("\tt1 = %s\n", t1.toChars()); | |
115 //if (t2) printf("\tt2 = %s\n", t2.toChars()); | |
116 debug { | |
117 if (!t2) writef("\te2 = '%s'\n", e2.toChars()); | |
118 } | |
119 assert(t2); | |
120 | |
121 Type t1b = t1.toBasetype(); | |
122 Type t2b = t2.toBasetype(); | |
123 | |
124 TY ty = cast(TY)Type.impcnvResult[t1b.ty][t2b.ty]; | |
125 if (ty != TY.Terror) | |
126 { | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
127 auto ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty]; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
128 auto ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty]; |
0 | 129 |
130 if (t1b.ty == ty1) // if no promotions | |
131 { | |
132 if (t1 == t2) | |
133 { | |
134 t = t1; | |
135 goto Lret; | |
136 } | |
137 | |
138 if (t1b == t2b) | |
139 { | |
140 t = t1b; | |
141 goto Lret; | |
142 } | |
143 } | |
144 | |
145 t = Type.basic[ty]; | |
146 | |
147 t1 = Type.basic[ty1]; | |
148 t2 = Type.basic[ty2]; | |
149 | |
150 e1 = e1.castTo(sc, t1); | |
151 e2 = e2.castTo(sc, t2); | |
152 //printf("after typeCombine():\n"); | |
153 //dump(0); | |
154 //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2); | |
155 goto Lret; | |
156 } | |
157 | |
158 t1 = t1b; | |
159 t2 = t2b; | |
160 | |
161 Lagain: | |
162 if (t1 == t2) | |
163 { | |
164 } | |
165 else if (t1.ty == TY.Tpointer && t2.ty == TY.Tpointer) | |
166 { | |
167 // Bring pointers to compatible type | |
168 Type t1n = t1.nextOf(); | |
169 Type t2n = t2.nextOf(); | |
170 | |
171 if (t1n == t2n) { | |
172 ; | |
173 } else if (t1n.ty == TY.Tvoid) {// pointers to void are always compatible | |
174 t = t2; | |
175 } else if (t2n.ty == TY.Tvoid) { | |
176 ; | |
177 } else if (t1n.mod != t2n.mod) { | |
178 t1 = t1n.mutableOf().constOf().pointerTo(); | |
179 t2 = t2n.mutableOf().constOf().pointerTo(); | |
180 t = t1; | |
181 goto Lagain; | |
182 } else if (t1n.ty == TY.Tclass && t2n.ty == TY.Tclass) { | |
183 ClassDeclaration cd1 = t1n.isClassHandle(); | |
184 ClassDeclaration cd2 = t2n.isClassHandle(); | |
185 int offset; | |
186 | |
187 if (cd1.isBaseOf(cd2, &offset)) | |
188 { | |
189 if (offset) | |
190 e2 = e2.castTo(sc, t); | |
191 } | |
192 else if (cd2.isBaseOf(cd1, &offset)) | |
193 { | |
194 t = t2; | |
195 if (offset) | |
196 e1 = e1.castTo(sc, t); | |
197 } | |
198 else | |
199 goto Lincompatible; | |
200 } else { | |
201 goto Lincompatible; | |
202 } | |
203 } | |
204 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
205 (e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid || |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
206 e2.op == TOK.TOKarrayliteral && t2.ty == TY.Tsarray && t2.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t2).dim.toInteger() == 0) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
207 ) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
208 { /* (T[n] op void*) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
209 * (T[] op void*) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
210 * (T[n] op void[0]) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
211 * (T[] op void[0]) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
212 */ |
0 | 213 goto Lx1; |
214 } | |
215 else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) && | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
216 (e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid || |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
217 e1.op == TOK.TOKarrayliteral && t1.ty == TY.Tsarray && t1.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t1).dim.toInteger() == 0) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
218 ) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
219 { /* (void* op T[n]) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
220 * (void* op T[]) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
221 * (void[0] op T[n]) => T[] |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
222 * (void[0] op T[]) => T[] |
0 | 223 */ |
224 goto Lx2; | |
225 } | |
226 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && t1.implicitConvTo(t2)) | |
227 { | |
228 goto Lt2; | |
229 } | |
230 else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) && t2.implicitConvTo(t1)) | |
231 { | |
232 goto Lt1; | |
233 } | |
234 /* If one is mutable and the other invariant, then retry | |
235 * with both of them as const | |
236 */ | |
237 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray || t1.ty == TY.Tpointer) && | |
238 (t2.ty == TY.Tsarray || t2.ty == TY.Tarray || t2.ty == TY.Tpointer) && | |
239 t1.nextOf().mod != t2.nextOf().mod | |
240 ) | |
241 { | |
242 if (t1.ty == TY.Tpointer) | |
243 t1 = t1.nextOf().mutableOf().constOf().pointerTo(); | |
244 else | |
245 t1 = t1.nextOf().mutableOf().constOf().arrayOf(); | |
246 | |
247 if (t2.ty == TY.Tpointer) | |
248 t2 = t2.nextOf().mutableOf().constOf().pointerTo(); | |
249 else | |
250 t2 = t2.nextOf().mutableOf().constOf().arrayOf(); | |
251 t = t1; | |
252 goto Lagain; | |
253 } | |
254 else if (t1.ty == TY.Tclass || t2.ty == TY.Tclass) | |
255 { | |
256 while (1) | |
257 { | |
258 int i1 = e2.implicitConvTo(t1); | |
259 int i2 = e1.implicitConvTo(t2); | |
260 | |
261 if (i1 && i2) | |
262 { | |
263 // We have the case of class vs. void*, so pick class | |
264 if (t1.ty == TY.Tpointer) | |
265 i1 = 0; | |
266 else if (t2.ty == TY.Tpointer) | |
267 i2 = 0; | |
268 } | |
269 | |
270 if (i2) | |
271 { | |
272 goto Lt2; | |
273 } | |
274 else if (i1) | |
275 { | |
276 goto Lt1; | |
277 } | |
278 else if (t1.ty == TY.Tclass && t2.ty == TY.Tclass) | |
174 | 279 { |
0 | 280 TypeClass tc1 = cast(TypeClass)t1; |
281 TypeClass tc2 = cast(TypeClass)t2; | |
282 | |
283 /* Pick 'tightest' type | |
284 */ | |
285 ClassDeclaration cd1 = tc1.sym.baseClass; | |
286 ClassDeclaration cd2 = tc2.sym.baseClass; | |
287 | |
288 if (cd1 && cd2) | |
289 { t1 = cd1.type; | |
290 t2 = cd2.type; | |
291 } | |
292 else if (cd1) | |
293 t1 = cd1.type; | |
294 else if (cd2) | |
295 t2 = cd2.type; | |
296 else | |
297 goto Lincompatible; | |
298 } | |
299 else | |
300 goto Lincompatible; | |
301 } | |
302 } | |
303 else if (t1.ty == TY.Tstruct && t2.ty == TY.Tstruct) | |
304 { | |
305 if ((cast(TypeStruct)t1).sym != (cast(TypeStruct)t2).sym) | |
306 goto Lincompatible; | |
307 } | |
308 else if ((e1.op == TOK.TOKstring || e1.op == TOK.TOKnull) && e1.implicitConvTo(t2)) | |
309 { | |
310 goto Lt2; | |
311 } | |
312 else if ((e2.op == TOK.TOKstring || e2.op == TOK.TOKnull) && e2.implicitConvTo(t1)) | |
313 { | |
314 goto Lt1; | |
315 } | |
316 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && | |
317 e2.implicitConvTo(t1.nextOf().arrayOf())) | |
318 { | |
319 Lx1: | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
320 t = t1.nextOf().arrayOf(); // T[] |
0 | 321 e1 = e1.castTo(sc, t); |
322 e2 = e2.castTo(sc, t); | |
323 } | |
324 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && | |
325 e1.implicitConvTo(t2.nextOf().arrayOf())) | |
326 { | |
327 Lx2: | |
328 t = t2.nextOf().arrayOf(); | |
329 e1 = e1.castTo(sc, t); | |
330 e2 = e2.castTo(sc, t); | |
331 } | |
332 else if (t1.isintegral() && t2.isintegral()) | |
333 { | |
334 assert(0); | |
335 } | |
98 | 336 else if (e1.isArrayOperand() && t1.ty == TY.Tarray && |
0 | 337 e2.implicitConvTo(t1.nextOf())) |
338 { // T[] op T | |
339 e2 = e2.castTo(sc, t1.nextOf()); | |
340 t = t1.nextOf().arrayOf(); | |
341 } | |
98 | 342 else if (e2.isArrayOperand() && t2.ty == TY.Tarray && |
0 | 343 e1.implicitConvTo(t2.nextOf())) |
344 { // T op T[] | |
345 e1 = e1.castTo(sc, t2.nextOf()); | |
346 t = t2.nextOf().arrayOf(); | |
347 | |
348 //printf("test %s\n", e.toChars()); | |
349 e1 = e1.optimize(WANT.WANTvalue); | |
350 if (e && e.isCommutative() && e1.isConst()) | |
351 { /* Swap operands to minimize number of functions generated | |
352 */ | |
353 //printf("swap %s\n", e.toChars()); | |
354 Expression tmp = e1; | |
355 e1 = e2; | |
356 e2 = tmp; | |
357 } | |
358 } | |
359 else | |
360 { | |
361 Lincompatible: | |
362 return 0; | |
363 } | |
364 Lret: | |
365 if (!*pt) | |
366 *pt = t; | |
367 *pe1 = e1; | |
368 *pe2 = e2; | |
369 static if (false) { | |
370 printf("-typeMerge() %s op %s\n", e1.toChars(), e2.toChars()); | |
371 if (e1.type) printf("\tt1 = %s\n", e1.type.toChars()); | |
372 if (e2.type) printf("\tt2 = %s\n", e2.type.toChars()); | |
373 printf("\ttype = %s\n", t.toChars()); | |
374 } | |
375 //dump(0); | |
376 return 1; | |
377 | |
378 | |
379 Lt1: | |
380 e2 = e2.castTo(sc, t1); | |
381 t = t1; | |
382 goto Lret; | |
383 | |
384 Lt2: | |
385 e1 = e1.castTo(sc, t2); | |
386 t = t2; | |
387 goto Lret; | |
388 } | |
389 | |
390 class BinExp : Expression | |
391 { | |
392 Expression e1; | |
393 Expression e2; | |
394 | |
395 this(Loc loc, TOK op, int size, Expression e1, Expression e2) | |
396 { | |
178 | 397 register(); |
398 | |
0 | 399 super(loc, op, size); |
400 this.e1 = e1; | |
401 this.e2 = e2; | |
402 } | |
174 | 403 |
72 | 404 override Expression syntaxCopy() |
0 | 405 { |
406 BinExp e = cast(BinExp)copy(); | |
407 e.type = null; | |
408 e.e1 = e.e1.syntaxCopy(); | |
409 e.e2 = e.e2.syntaxCopy(); | |
410 | |
411 return e; | |
412 } | |
413 | |
72 | 414 override Expression semantic(Scope sc) |
0 | 415 { |
416 version (LOGSEMANTIC) { | |
60 | 417 printf("BinExp.semantic('%.*s')\n", toChars()); |
0 | 418 } |
419 e1 = e1.semantic(sc); | |
420 if (!e1.type && !(op == TOK.TOKassign && e1.op == TOK.TOKdottd)) // a.template = e2 | |
421 { | |
422 error("%s has no value", e1.toChars()); | |
423 e1.type = Type.terror; | |
424 } | |
425 e2 = e2.semantic(sc); | |
426 if (!e2.type) | |
427 { | |
428 error("%s has no value", e2.toChars()); | |
429 e2.type = Type.terror; | |
430 } | |
431 return this; | |
432 } | |
174 | 433 |
0 | 434 Expression semanticp(Scope sc) |
435 { | |
60 | 436 BinExp.semantic(sc); |
174 | 437 |
60 | 438 e1 = resolveProperties(sc, e1); |
439 e2 = resolveProperties(sc, e2); | |
0 | 440 return this; |
441 } | |
174 | 442 |
56 | 443 /*************************** |
444 * Common semantic routine for some xxxAssignExp's. | |
445 */ | |
0 | 446 Expression commonSemanticAssign(Scope sc) |
447 { | |
56 | 448 Expression e; |
449 | |
450 if (!type) | |
451 { | |
452 BinExp.semantic(sc); | |
453 e2 = resolveProperties(sc, e2); | |
454 | |
455 e = op_overload(sc); | |
456 if (e) | |
457 return e; | |
458 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
459 if (e1.op == TOK.TOKarraylength) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
460 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
461 e = ArrayLengthExp.rewriteOpAssign(this); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
462 e = e.semantic(sc); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
463 return e; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
464 } |
174 | 465 |
56 | 466 if (e1.op == TOKslice) |
174 | 467 { |
56 | 468 // T[] op= ... |
469 typeCombine(sc); | |
470 type = e1.type; | |
471 return arrayOp(sc); | |
472 } | |
473 | |
474 e1 = e1.modifiableLvalue(sc, e1); | |
475 e1.checkScalar(); | |
476 type = e1.type; | |
477 if (type.toBasetype().ty == Tbool) | |
478 { | |
479 error("operator not allowed on bool expression %s", toChars()); | |
480 } | |
481 typeCombine(sc); | |
482 e1.checkArithmetic(); | |
483 e2.checkArithmetic(); | |
484 | |
485 if (op == TOKmodass && e2.type.iscomplex()) | |
486 { error("cannot perform modulo complex arithmetic"); | |
487 return new ErrorExp(); | |
488 } | |
489 } | |
490 return this; | |
0 | 491 } |
492 | |
493 Expression commonSemanticAssignIntegral(Scope sc) | |
494 { | |
495 Expression e; | |
496 | |
497 if (!type) | |
498 { | |
499 BinExp.semantic(sc); | |
500 e2 = resolveProperties(sc, e2); | |
501 | |
502 e = op_overload(sc); | |
503 if (e) | |
504 return e; | |
505 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
506 if (e1.op == TOKarraylength) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
507 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
508 e = ArrayLengthExp.rewriteOpAssign(this); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
509 e = e.semantic(sc); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
510 return e; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
511 } |
174 | 512 |
0 | 513 if (e1.op == TOK.TOKslice) |
514 { // T[] op= ... | |
515 typeCombine(sc); | |
516 type = e1.type; | |
517 return arrayOp(sc); | |
518 } | |
519 | |
520 e1 = e1.modifiableLvalue(sc, e1); | |
521 e1.checkScalar(); | |
522 type = e1.type; | |
523 if (type.toBasetype().ty == TY.Tbool) | |
524 { | |
525 e2 = e2.implicitCastTo(sc, type); | |
526 } | |
527 | |
528 typeCombine(sc); | |
529 e1.checkIntegral(); | |
530 e2.checkIntegral(); | |
531 } | |
532 | |
533 return this; | |
534 } | |
174 | 535 |
72 | 536 override bool checkSideEffect(int flag) |
0 | 537 { |
538 switch (op) { | |
539 case TOK.TOKplusplus: | |
540 case TOK.TOKminusminus: | |
541 case TOK.TOKassign: | |
542 case TOK.TOKconstruct: | |
543 case TOK.TOKblit: | |
544 case TOK.TOKaddass: | |
545 case TOK.TOKminass: | |
546 case TOK.TOKcatass: | |
547 case TOK.TOKmulass: | |
548 case TOK.TOKdivass: | |
549 case TOK.TOKmodass: | |
550 case TOK.TOKshlass: | |
551 case TOK.TOKshrass: | |
552 case TOK.TOKushrass: | |
553 case TOK.TOKandass: | |
554 case TOK.TOKorass: | |
555 case TOK.TOKxorass: | |
135 | 556 case TOK.TOKpowass: |
0 | 557 case TOK.TOKin: |
558 case TOK.TOKremove: | |
559 return true; | |
560 | |
561 default: | |
562 return Expression.checkSideEffect(flag); | |
563 } | |
564 } | |
174 | 565 |
72 | 566 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 567 { |
568 expToCBuffer(buf, hgs, e1, precedence[op]); | |
569 buf.writeByte(' '); | |
570 buf.writestring(Token.toChars(op)); | |
571 buf.writeByte(' '); | |
572 expToCBuffer(buf, hgs, e2, cast(PREC)(precedence[op] + 1)); | |
573 } | |
574 | |
575 /**************************************** | |
576 * Scale addition/subtraction to/from pointer. | |
577 */ | |
578 Expression scaleFactor(Scope sc) | |
579 { | |
580 ulong stride; | |
581 Type t1b = e1.type.toBasetype(); | |
582 Type t2b = e2.type.toBasetype(); | |
583 | |
584 if (t1b.ty == Tpointer && t2b.isintegral()) | |
174 | 585 { |
0 | 586 // Need to adjust operator by the stride |
587 // Replace (ptr + int) with (ptr + (int * stride)) | |
588 Type t = Type.tptrdiff_t; | |
589 | |
590 stride = t1b.nextOf().size(loc); | |
591 if (!t.equals(t2b)) | |
592 e2 = e2.castTo(sc, t); | |
593 e2 = new MulExp(loc, e2, new IntegerExp(Loc(0), stride, t)); | |
594 e2.type = t; | |
595 type = e1.type; | |
596 } | |
597 else if (t2b.ty == Tpointer && t1b.isintegral()) | |
174 | 598 { |
0 | 599 // Need to adjust operator by the stride |
600 // Replace (int + ptr) with (ptr + (int * stride)) | |
601 Type t = Type.tptrdiff_t; | |
602 Expression e; | |
603 | |
604 stride = t2b.nextOf().size(loc); | |
605 if (!t.equals(t1b)) | |
606 e = e1.castTo(sc, t); | |
607 else | |
608 e = e1; | |
609 e = new MulExp(loc, e, new IntegerExp(Loc(0), stride, t)); | |
610 e.type = t; | |
611 type = e2.type; | |
612 e1 = e2; | |
613 e2 = e; | |
614 } | |
615 return this; | |
616 } | |
174 | 617 |
0 | 618 /************************************ |
619 * Bring leaves to common type. | |
620 */ | |
621 Expression typeCombine(Scope sc) | |
622 { | |
623 Type t1 = e1.type.toBasetype(); | |
624 Type t2 = e2.type.toBasetype(); | |
625 | |
626 if (op == TOK.TOKmin || op == TOK.TOKadd) | |
627 { | |
628 if (t1.ty == TY.Tstruct) | |
629 { | |
630 if (t2.ty == TY.Tstruct && (cast(TypeStruct)t1).sym is (cast(TypeStruct)t2).sym) | |
631 goto Lerror; | |
632 } | |
633 else if (t1.ty == TY.Tclass) | |
634 { | |
635 if (t2.ty == TY.Tclass) | |
636 goto Lerror; | |
637 } | |
638 } | |
639 | |
640 if (!typeMerge(sc, this, &type, &e1, &e2)) | |
641 goto Lerror; | |
642 return this; | |
643 | |
644 Lerror: | |
645 incompatibleTypes(); | |
646 type = Type.terror; | |
647 e1 = new ErrorExp(); | |
648 e2 = new ErrorExp(); | |
649 return this; | |
650 } | |
651 | |
72 | 652 override Expression optimize(int result) |
0 | 653 { |
654 //printf("BinExp.optimize(result = %d) %s\n", result, toChars()); | |
655 if (op != TOK.TOKconstruct && op != TOK.TOKblit) // don't replace const variable with its initializer | |
656 e1 = e1.optimize(result); | |
657 | |
658 e2 = e2.optimize(result); | |
659 if (op == TOK.TOKshlass || op == TOK.TOKshrass || op == TOK.TOKushrass) | |
660 { | |
661 if (e2.isConst() == 1) | |
662 { | |
663 long i2 = e2.toInteger(); | |
664 ulong sz = e1.type.size() * 8; | |
665 | |
666 if (i2 < 0 || i2 > sz) | |
174 | 667 { |
0 | 668 error("shift assign by %jd is outside the range 0..%zu", i2, sz); |
669 e2 = new IntegerExp(0); | |
670 } | |
671 } | |
672 } | |
673 | |
674 return this; | |
675 } | |
676 | |
677 bool isunsigned() | |
678 { | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
679 return e1.type.isunsigned() || e2.type.isunsigned(); |
0 | 680 } |
174 | 681 |
0 | 682 void incompatibleTypes() |
683 { | |
684 error("incompatible types for ((%s) %s (%s)): '%s' and '%s'", | |
685 e1.toChars(), Token.toChars(op), e2.toChars(), | |
686 e1.type.toChars(), e2.type.toChars()); | |
687 } | |
688 | |
72 | 689 override void dump(int indent) |
0 | 690 { |
691 assert(false); | |
692 } | |
693 | |
154
14feb7ae01a6
* changed the build system to build a release version if the debug one compiles
trass3r
parents:
135
diff
changeset
|
694 override void scanForNestedRef(Scope sc) |
0 | 695 { |
123 | 696 e1.scanForNestedRef(sc); |
697 e2.scanForNestedRef(sc); | |
0 | 698 } |
699 | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
700 Expression interpretCommon(InterState istate, Expression function(Type, Expression, Expression) fp) |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
701 { |
116 | 702 Expression e; |
703 Expression e1; | |
704 Expression e2; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
705 |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
706 version(LOG) |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
707 { |
116 | 708 writef("BinExp::interpretCommon() %s\n", toChars()); |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
709 } |
116 | 710 e1 = this.e1.interpret(istate); |
711 if (e1 is EXP_CANT_INTERPRET) | |
712 goto Lcant; | |
713 if (e1.isConst() != 1) | |
714 goto Lcant; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
715 |
116 | 716 e2 = this.e2.interpret(istate); |
717 if (e2 is EXP_CANT_INTERPRET) | |
718 goto Lcant; | |
719 if (e2.isConst() != 1) | |
720 goto Lcant; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
721 |
116 | 722 e = fp(type, e1, e2); |
723 return e; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
724 |
116 | 725 Lcant: |
726 return EXP_CANT_INTERPRET; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
727 } |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
728 |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
729 Expression interpretCommon2(InterState istate, Expression function(TOK, Type, Expression, Expression) fp) |
0 | 730 { |
116 | 731 Expression e; |
732 Expression e1; | |
733 Expression e2; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
734 |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
735 version(LOG) |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
736 { |
116 | 737 writef("BinExp::interpretCommon2() %s\n", toChars()); |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
738 } |
116 | 739 e1 = this.e1.interpret(istate); |
740 if (e1 is EXP_CANT_INTERPRET) | |
741 goto Lcant; | |
742 if (e1.isConst() != 1 && | |
743 e1.op != TOKnull && | |
744 e1.op != TOKstring && | |
745 e1.op != TOKarrayliteral && | |
746 e1.op != TOKstructliteral) | |
747 goto Lcant; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
748 |
116 | 749 e2 = this.e2.interpret(istate); |
750 if (e2 is EXP_CANT_INTERPRET) | |
751 goto Lcant; | |
752 if (e2.isConst() != 1 && | |
753 e2.op != TOKnull && | |
754 e2.op != TOKstring && | |
755 e2.op != TOKarrayliteral && | |
756 e2.op != TOKstructliteral) | |
757 goto Lcant; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
758 |
116 | 759 e = fp(op, type, e1, e2); |
760 return e; | |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
761 |
116 | 762 Lcant: |
763 return EXP_CANT_INTERPRET; | |
0 | 764 } |
174 | 765 |
116 | 766 Expression interpretAssignCommon(InterState istate, Expression function(Type, Expression, Expression) fp, int post = 0) |
0 | 767 { |
116 | 768 version (LOG) |
769 { | |
770 writef("BinExp.interpretAssignCommon() %.*s\n", toChars()); | |
63 | 771 } |
772 Expression e = EXP_CANT_INTERPRET; | |
773 Expression e1 = this.e1; | |
774 | |
775 if (fp) | |
776 { | |
777 if (e1.op == TOKcast) | |
174 | 778 { |
63 | 779 CastExp ce = cast(CastExp)e1; |
780 e1 = ce.e1; | |
781 } | |
782 } | |
783 if (e1 is EXP_CANT_INTERPRET) | |
784 return e1; | |
785 Expression e2 = this.e2.interpret(istate); | |
786 if (e2 is EXP_CANT_INTERPRET) | |
787 return e2; | |
174 | 788 |
63 | 789 // Chase down rebinding of out and ref. |
790 if (e1.op == TOKvar) | |
791 { | |
792 VarExp ve = cast(VarExp)e1; | |
793 VarDeclaration v = ve.var.isVarDeclaration(); | |
794 if (v && v.value && v.value.op == TOKvar) | |
795 { | |
796 VarExp ve2 = cast(VarExp)v.value; | |
797 if (ve2.var.isSymbolDeclaration()) | |
174 | 798 { |
63 | 799 // This can happen if v is a struct initialized to |
800 // 0 using an __initZ SymbolDeclaration from | |
801 // TypeStruct.defaultInit() | |
802 } | |
803 else | |
804 e1 = v.value; | |
805 } | |
806 else if (v && v.value && (v.value.op==TOKindex || v.value.op == TOKdotvar)) | |
807 { | |
135 | 808 // It is no longer a TOKvar, eg when a[4] is passed by ref. |
174 | 809 e1 = v.value; |
63 | 810 } |
811 } | |
812 | |
813 // To reduce code complexity of handling dotvar expressions, | |
814 // extract the aggregate now. | |
815 Expression aggregate; | |
816 if (e1.op == TOKdotvar) { | |
817 aggregate = (cast(DotVarExp)e1).e1; | |
818 // Get rid of 'this'. | |
819 if (aggregate.op == TOKthis && istate.localThis) | |
174 | 820 aggregate = istate.localThis; |
63 | 821 } |
174 | 822 |
63 | 823 /* Assignment to variable of the form: |
824 * v = e2 | |
825 */ | |
826 if (e1.op == TOKvar) | |
827 { | |
828 VarExp ve = cast(VarExp)e1; | |
829 VarDeclaration v = ve.var.isVarDeclaration(); | |
830 assert(v); | |
135 | 831 if (v && !v.isCTFE()) |
174 | 832 { |
63 | 833 // Can't modify global or static data |
834 error("%s cannot be modified at compile time", v.toChars()); | |
835 return EXP_CANT_INTERPRET; | |
836 } | |
135 | 837 if (v && v.isCTFE()) |
63 | 838 { |
839 Expression ev = v.value; | |
840 if (fp && !ev) | |
174 | 841 { |
63 | 842 error("variable %s is used before initialization", v.toChars()); |
843 return e; | |
844 } | |
845 if (fp) | |
846 e2 = (*fp)(v.type, ev, e2); | |
847 else | |
174 | 848 { |
63 | 849 /* Look for special case of struct being initialized with 0. |
850 */ | |
851 if (v.type.toBasetype().ty == Tstruct && e2.op == TOKint64) | |
852 { | |
135 | 853 e2 = v.type.defaultInitLiteral(Loc(0)); |
63 | 854 } |
855 e2 = Cast(v.type, v.type, e2); | |
856 } | |
857 if (e2 is EXP_CANT_INTERPRET) | |
858 return e2; | |
859 | |
860 addVarToInterstate(istate, v); | |
861 v.value = e2; | |
862 e = Cast(type, type, post ? ev : e2); | |
863 } | |
864 } | |
865 else if (e1.op == TOKdotvar && aggregate.op == TOKdotvar) | |
174 | 866 { |
63 | 867 // eg v.u.var = e2, v[3].u.var = e2, etc. |
868 error("Nested struct assignment %s is not yet supported in CTFE", toChars()); | |
869 } | |
870 /* Assignment to struct member of the form: | |
871 * v.var = e2 | |
872 */ | |
873 else if (e1.op == TOKdotvar && aggregate.op == TOKvar) | |
174 | 874 { |
63 | 875 VarDeclaration v = (cast(VarExp)aggregate).var.isVarDeclaration(); |
876 | |
135 | 877 if (!v.isCTFE()) |
174 | 878 { |
63 | 879 // Can't modify global or static data |
880 error("%s cannot be modified at compile time", v.toChars()); | |
881 return EXP_CANT_INTERPRET; | |
882 } else { | |
883 // Chase down rebinding of out and ref | |
884 if (v.value && v.value.op == TOKvar) | |
885 { | |
886 VarExp ve2 = cast(VarExp)v.value; | |
887 if (ve2.var.isSymbolDeclaration()) | |
174 | 888 { |
63 | 889 // This can happen if v is a struct initialized to |
890 // 0 using an __initZ SymbolDeclaration from | |
891 // TypeStruct.defaultInit() | |
892 } | |
893 else | |
894 v = ve2.var.isVarDeclaration(); | |
895 assert(v); | |
896 } | |
897 } | |
898 if (fp && !v.value) | |
174 | 899 { |
63 | 900 error("variable %s is used before initialization", v.toChars()); |
901 return e; | |
902 } | |
903 if (v.value is null && v.init.isVoidInitializer()) | |
174 | 904 { |
63 | 905 /* Since a void initializer initializes to undefined |
906 * values, it is valid here to use the default initializer. | |
907 * No attempt is made to determine if someone actually relies | |
908 * on the void value - to do that we'd need a VoidExp. | |
909 * That's probably a good enhancement idea. | |
910 */ | |
911 v.value = v.type.defaultInit(Loc(0)); | |
912 } | |
913 Expression vie = v.value; | |
914 if (vie.op == TOKvar) | |
915 { | |
916 Declaration d = (cast(VarExp)vie).var; | |
917 vie = getVarExp(e1.loc, istate, d); | |
918 } | |
919 if (vie.op != TOKstructliteral) | |
920 return EXP_CANT_INTERPRET; | |
921 StructLiteralExp se = cast(StructLiteralExp)vie; | |
922 VarDeclaration vf = (cast(DotVarExp)e1).var.isVarDeclaration(); | |
923 if (!vf) | |
924 return EXP_CANT_INTERPRET; | |
925 int fieldi = se.getFieldIndex(type, vf.offset); | |
926 if (fieldi == -1) | |
927 return EXP_CANT_INTERPRET; | |
928 Expression ev = se.getField(type, vf.offset); | |
929 if (fp) | |
930 e2 = (*fp)(type, ev, e2); | |
931 else | |
932 e2 = Cast(type, type, e2); | |
933 if (e2 is EXP_CANT_INTERPRET) | |
934 return e2; | |
935 | |
936 addVarToInterstate(istate, v); | |
937 | |
938 /* Create new struct literal reflecting updated fieldi | |
939 */ | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
940 auto expsx = changeOneElement(se.elements, fieldi, e2); |
63 | 941 v.value = new StructLiteralExp(se.loc, se.sd, expsx); |
942 v.value.type = se.type; | |
943 | |
944 e = Cast(type, type, post ? ev : e2); | |
945 } | |
946 /* Assignment to struct member of the form: | |
947 * *(symoffexp) = e2 | |
948 */ | |
949 else if (e1.op == TOKstar && (cast(PtrExp)e1).e1.op == TOKsymoff) | |
174 | 950 { |
63 | 951 SymOffExp soe = cast(SymOffExp)(cast(PtrExp)e1).e1; |
952 VarDeclaration v = soe.var.isVarDeclaration(); | |
953 | |
135 | 954 if (!v.isCTFE()) |
63 | 955 { |
956 error("%s cannot be modified at compile time", v.toChars()); | |
957 return EXP_CANT_INTERPRET; | |
958 } | |
959 if (fp && !v.value) | |
174 | 960 { |
63 | 961 error("variable %s is used before initialization", v.toChars()); |
962 return e; | |
963 } | |
964 Expression vie = v.value; | |
965 if (vie.op == TOKvar) | |
966 { | |
967 Declaration d = (cast(VarExp)vie).var; | |
968 vie = getVarExp(e1.loc, istate, d); | |
969 } | |
970 if (vie.op != TOKstructliteral) | |
971 return EXP_CANT_INTERPRET; | |
972 StructLiteralExp se = cast(StructLiteralExp)vie; | |
973 int fieldi = se.getFieldIndex(type, soe.offset); | |
974 if (fieldi == -1) | |
975 return EXP_CANT_INTERPRET; | |
976 Expression ev = se.getField(type, soe.offset); | |
977 if (fp) | |
978 e2 = (*fp)(type, ev, e2); | |
979 else | |
980 e2 = Cast(type, type, e2); | |
981 if (e2 is EXP_CANT_INTERPRET) | |
982 return e2; | |
983 | |
984 addVarToInterstate(istate, v); | |
985 | |
986 /* Create new struct literal reflecting updated fieldi | |
987 */ | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
988 auto expsx = changeOneElement(se.elements, fieldi, e2); |
63 | 989 v.value = new StructLiteralExp(se.loc, se.sd, expsx); |
990 v.value.type = se.type; | |
991 | |
992 e = Cast(type, type, post ? ev : e2); | |
993 } | |
994 /* Assignment to array element of the form: | |
995 * a[i] = e2 | |
996 */ | |
997 else if (e1.op == TOKindex && (cast(IndexExp)e1).e1.op == TOKvar) | |
174 | 998 { |
63 | 999 IndexExp ie = cast(IndexExp)e1; |
1000 VarExp ve = cast(VarExp)ie.e1; | |
1001 VarDeclaration v = ve.var.isVarDeclaration(); | |
135 | 1002 if (!v || !v.isCTFE()) |
63 | 1003 { |
1004 error("%s cannot be modified at compile time", v ? v.toChars(): "void"); | |
1005 return EXP_CANT_INTERPRET; | |
1006 } | |
1007 if (v.value && v.value.op == TOKvar) | |
1008 { | |
1009 VarExp ve2 = cast(VarExp)v.value; | |
1010 if (ve2.var.isSymbolDeclaration()) | |
174 | 1011 { |
63 | 1012 // This can happen if v is a struct initialized to |
1013 // 0 using an __initZ SymbolDeclaration from | |
1014 // TypeStruct.defaultInit() | |
1015 } | |
1016 else | |
1017 v = ve2.var.isVarDeclaration(); | |
1018 assert(v); | |
1019 } | |
1020 if (!v.value) | |
1021 { | |
1022 if (fp) | |
174 | 1023 { |
63 | 1024 error("variable %s is used before initialization", v.toChars()); |
1025 return e; | |
1026 } | |
1027 | |
1028 Type t = v.type.toBasetype(); | |
1029 if (t.ty == Tsarray) | |
1030 { | |
1031 /* This array was void initialized. Create a | |
1032 * default initializer for it. | |
1033 * What we should do is fill the array literal with | |
1034 * null data, so use-before-initialized can be detected. | |
1035 * But we're too lazy at the moment to do it, as that | |
1036 * involves redoing Index() and whoever calls it. | |
1037 */ | |
1038 | |
1039 size_t dim = cast(size_t)(cast(TypeSArray)t).dim.toInteger(); | |
1040 v.value = createBlockDuplicatedArrayLiteral(v.type, | |
1041 v.type.defaultInit(Loc(0)), dim); | |
1042 } | |
1043 else | |
1044 return EXP_CANT_INTERPRET; | |
1045 } | |
1046 | |
1047 ArrayLiteralExp ae = null; | |
1048 AssocArrayLiteralExp aae = null; | |
1049 StringExp se = null; | |
1050 if (v.value.op == TOKarrayliteral) | |
1051 ae = cast(ArrayLiteralExp)v.value; | |
1052 else if (v.value.op == TOKassocarrayliteral) | |
1053 aae = cast(AssocArrayLiteralExp)v.value; | |
1054 else if (v.value.op == TOKstring) | |
1055 se = cast(StringExp)v.value; | |
1056 else if (v.value.op == TOKnull) | |
1057 { | |
1058 // This would be a runtime segfault | |
1059 error("Cannot index null array %.*s", v.toChars()); | |
1060 return EXP_CANT_INTERPRET; | |
1061 } | |
1062 else | |
1063 return EXP_CANT_INTERPRET; | |
1064 | |
1065 /* Set the $ variable | |
1066 */ | |
1067 Expression ee = ArrayLength(Type.tsize_t, v.value); | |
1068 if (ee !is EXP_CANT_INTERPRET && ie.lengthVar) | |
1069 ie.lengthVar.value = ee; | |
1070 Expression index = ie.e2.interpret(istate); | |
1071 if (index is EXP_CANT_INTERPRET) | |
1072 return EXP_CANT_INTERPRET; | |
1073 Expression ev; | |
1074 if (fp || ae || se) // not for aae, because key might not be there | |
1075 { | |
1076 ev = Index(type, v.value, index); | |
1077 if (ev is EXP_CANT_INTERPRET) | |
1078 return EXP_CANT_INTERPRET; | |
1079 } | |
1080 | |
1081 if (fp) | |
1082 e2 = (*fp)(type, ev, e2); | |
1083 else | |
1084 e2 = Cast(type, type, e2); | |
1085 if (e2 is EXP_CANT_INTERPRET) | |
1086 return e2; | |
174 | 1087 |
63 | 1088 addVarToInterstate(istate, v); |
1089 if (ae) | |
1090 { | |
1091 /* Create new array literal reflecting updated elem | |
1092 */ | |
1093 int elemi = cast(int)index.toInteger(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1094 auto expsx = changeOneElement(ae.elements, elemi, e2); |
63 | 1095 v.value = new ArrayLiteralExp(ae.loc, expsx); |
1096 v.value.type = ae.type; | |
1097 } | |
1098 else if (aae) | |
1099 { | |
1100 /* Create new associative array literal reflecting updated key/value | |
1101 */ | |
1102 Expressions keysx = aae.keys; | |
1103 Expressions valuesx = new Expressions(); | |
1104 valuesx.setDim(aae.values.dim); | |
1105 int updated = 0; | |
1106 for (size_t j = valuesx.dim; j; ) | |
174 | 1107 { |
63 | 1108 j--; |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1109 Expression ekey = aae.keys[j]; |
63 | 1110 Expression ex = Equal(TOKequal, Type.tbool, ekey, index); |
1111 if (ex is EXP_CANT_INTERPRET) | |
1112 return EXP_CANT_INTERPRET; | |
1113 if (ex.isBool(true)) | |
174 | 1114 { |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1115 valuesx[j] = e2; |
63 | 1116 updated = 1; |
1117 } | |
1118 else | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1119 valuesx[j] = aae.values[j]; |
63 | 1120 } |
1121 if (!updated) | |
174 | 1122 { |
63 | 1123 // Append index/e2 to keysx[]/valuesx[] |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1124 valuesx.push(e2); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1125 keysx = keysx.copy(); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1126 keysx.push(index); |
63 | 1127 } |
1128 v.value = new AssocArrayLiteralExp(aae.loc, keysx, valuesx); | |
1129 v.value.type = aae.type; | |
1130 } | |
1131 else if (se) | |
1132 { | |
1133 /* Create new string literal reflecting updated elem | |
1134 */ | |
1135 int elemi = cast(int)index.toInteger(); | |
1136 char* s; | |
1137 s = cast(char*)calloc(se.len + 1, se.sz); | |
1138 memcpy(s, se.string_, se.len * se.sz); | |
1139 dchar value = cast(dchar)e2.toInteger(); | |
1140 switch (se.sz) | |
1141 { | |
1142 case 1: s[elemi] = cast(char)value; break; | |
1143 case 2: (cast(wchar*)s)[elemi] = cast(wchar)value; break; | |
1144 case 4: (cast(dchar*)s)[elemi] = value; break; | |
1145 default: | |
1146 assert(0); | |
1147 break; | |
1148 } | |
1149 StringExp se2 = new StringExp(se.loc, assumeUnique(s[0..se.len])); | |
1150 se2.committed = se.committed; | |
1151 se2.postfix = se.postfix; | |
1152 se2.type = se.type; | |
1153 v.value = se2; | |
1154 } | |
1155 else | |
1156 assert(0); | |
1157 | |
1158 e = Cast(type, type, post ? ev : e2); | |
1159 } | |
174 | 1160 |
63 | 1161 /* Assignment to struct element in array, of the form: |
1162 * a[i].var = e2 | |
1163 */ | |
1164 else if (e1.op == TOKdotvar && aggregate.op == TOKindex && | |
1165 (cast(IndexExp)aggregate).e1.op == TOKvar) | |
1166 { | |
1167 IndexExp ie = cast(IndexExp)aggregate; | |
1168 VarExp ve = cast(VarExp)(ie.e1); | |
1169 VarDeclaration v = ve.var.isVarDeclaration(); | |
135 | 1170 if (!v || !v.isCTFE()) |
63 | 1171 { |
1172 error("%s cannot be modified at compile time", v ? v.toChars(): "void"); | |
1173 return EXP_CANT_INTERPRET; | |
1174 } | |
1175 Type t = ve.type.toBasetype(); | |
1176 ArrayLiteralExp ae = cast(ArrayLiteralExp)v.value; | |
1177 if (!ae) | |
1178 { | |
1179 // assignment to one element in an uninitialized (static) array. | |
1180 // This is quite difficult, because defaultInit() for a struct is a VarExp, | |
1181 // not a StructLiteralExp. | |
1182 Type t2 = v.type.toBasetype(); | |
1183 if (t2.ty != Tsarray) | |
1184 { | |
1185 error("Cannot index an uninitialized variable"); | |
1186 return EXP_CANT_INTERPRET; | |
1187 } | |
1188 | |
1189 Type telem = (cast(TypeSArray)t2).nextOf().toBasetype(); | |
1190 if (telem.ty != Tstruct) { return EXP_CANT_INTERPRET; } | |
1191 | |
1192 // Create a default struct literal... | |
135 | 1193 Expression structinit = telem.defaultInitLiteral(v.loc); |
63 | 1194 |
1195 // ... and use to create a blank array literal | |
1196 size_t dim = cast(size_t)(cast(TypeSArray)t2).dim.toInteger(); | |
1197 ae = createBlockDuplicatedArrayLiteral(v.type, structinit, dim); | |
1198 v.value = ae; | |
1199 } | |
1200 if (cast(Expression)(ae.elements) is EXP_CANT_INTERPRET) | |
1201 { | |
1202 // Note that this would be a runtime segfault | |
1203 error("Cannot index null array %s", v.toChars()); | |
1204 return EXP_CANT_INTERPRET; | |
1205 } | |
1206 // Set the $ variable | |
1207 Expression ee = ArrayLength(Type.tsize_t, v.value); | |
1208 if (ee !is EXP_CANT_INTERPRET && ie.lengthVar) | |
1209 ie.lengthVar.value = ee; | |
1210 // Determine the index, and check that it's OK. | |
1211 Expression index = ie.e2.interpret(istate); | |
1212 if (index is EXP_CANT_INTERPRET) | |
1213 return EXP_CANT_INTERPRET; | |
1214 | |
1215 int elemi = cast(int)index.toInteger(); | |
1216 if (elemi >= ae.elements.dim) | |
1217 { | |
174 | 1218 error("array index %d is out of bounds %s[0..%d]", elemi, |
63 | 1219 v.toChars(), ae.elements.dim); |
1220 return EXP_CANT_INTERPRET; | |
1221 } | |
1222 // Get old element | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
1223 auto vie = ae.elements[elemi]; |
63 | 1224 if (vie.op != TOKstructliteral) |
1225 return EXP_CANT_INTERPRET; | |
1226 | |
1227 // Work out which field needs to be changed | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
1228 auto se = cast(StructLiteralExp)vie; |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
1229 auto vf = (cast(DotVarExp)e1).var.isVarDeclaration(); |
63 | 1230 if (!vf) |
1231 return EXP_CANT_INTERPRET; | |
1232 | |
1233 int fieldi = se.getFieldIndex(type, vf.offset); | |
1234 if (fieldi == -1) | |
1235 return EXP_CANT_INTERPRET; | |
174 | 1236 |
63 | 1237 Expression ev = se.getField(type, vf.offset); |
1238 if (fp) | |
1239 e2 = (*fp)(type, ev, e2); | |
1240 else | |
1241 e2 = Cast(type, type, e2); | |
1242 if (e2 == EXP_CANT_INTERPRET) | |
1243 return e2; | |
1244 | |
1245 // Create new struct literal reflecting updated field | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1246 auto expsx = changeOneElement(se.elements, fieldi, e2); |
63 | 1247 Expression newstruct = new StructLiteralExp(se.loc, se.sd, expsx); |
1248 | |
1249 // Create new array literal reflecting updated struct elem | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1250 ae.elements = changeOneElement(ae.elements, elemi, newstruct); |
63 | 1251 return ae; |
1252 } | |
1253 /* Slice assignment, initialization of static arrays | |
1254 * a[] = e | |
1255 */ | |
1256 else if (e1.op == TOKslice && (cast(SliceExp)e1).e1.op == TOKvar) | |
1257 { | |
1258 SliceExp sexp = cast(SliceExp)e1; | |
1259 VarExp ve = cast(VarExp)(sexp.e1); | |
1260 VarDeclaration v = ve.var.isVarDeclaration(); | |
135 | 1261 if (!v || !v.isCTFE()) |
63 | 1262 { |
1263 error("%s cannot be modified at compile time", v.toChars()); | |
1264 return EXP_CANT_INTERPRET; | |
1265 } | |
1266 // Chase down rebinding of out and ref | |
1267 if (v.value && v.value.op == TOKvar) | |
1268 { | |
1269 VarExp ve2 = cast(VarExp)v.value; | |
1270 if (ve2.var.isSymbolDeclaration()) | |
174 | 1271 { |
63 | 1272 // This can happen if v is a struct initialized to |
1273 // 0 using an __initZ SymbolDeclaration from | |
1274 // TypeStruct.defaultInit() | |
1275 } | |
1276 else | |
1277 v = ve2.var.isVarDeclaration(); | |
1278 assert(v); | |
1279 } | |
1280 /* Set the $ variable | |
1281 */ | |
1282 Expression ee = v.value ? ArrayLength(Type.tsize_t, v.value) | |
1283 : EXP_CANT_INTERPRET; | |
1284 if (ee !is EXP_CANT_INTERPRET && sexp.lengthVar) | |
1285 sexp.lengthVar.value = ee; | |
1286 Expression upper = null; | |
1287 Expression lower = null; | |
1288 if (sexp.upr) | |
1289 { | |
1290 upper = sexp.upr.interpret(istate); | |
1291 if (upper is EXP_CANT_INTERPRET) | |
1292 return EXP_CANT_INTERPRET; | |
1293 } | |
1294 if (sexp.lwr) | |
1295 { | |
1296 lower = sexp.lwr.interpret(istate); | |
1297 if (lower is EXP_CANT_INTERPRET) | |
1298 return EXP_CANT_INTERPRET; | |
1299 } | |
1300 Type t = v.type.toBasetype(); | |
1301 size_t dim; | |
174 | 1302 if (t.ty == Tsarray) |
63 | 1303 dim = cast(size_t)(cast(TypeSArray)t).dim.toInteger(); |
1304 else if (t.ty == Tarray) | |
1305 { | |
1306 if (!v.value || v.value.op == TOKnull) | |
1307 { | |
1308 error("cannot assign to null array %s", v.toChars()); | |
1309 return EXP_CANT_INTERPRET; | |
1310 } | |
1311 if (v.value.op == TOKarrayliteral) | |
1312 dim = (cast(ArrayLiteralExp)v.value).elements.dim; | |
1313 else if (v.value.op ==TOKstring) | |
1314 { | |
1315 error("String slice assignment is not yet supported in CTFE"); | |
1316 return EXP_CANT_INTERPRET; | |
1317 } | |
1318 } | |
1319 else | |
1320 { | |
1321 error("%s cannot be evaluated at compile time", toChars()); | |
1322 return EXP_CANT_INTERPRET; | |
1323 } | |
1324 int upperbound = upper ? cast(int)upper.toInteger() : dim; | |
1325 int lowerbound = lower ? cast(int)lower.toInteger() : 0; | |
1326 | |
1327 ArrayLiteralExp existing; | |
1328 if ((cast(int)lowerbound < 0) || (upperbound > dim)) | |
1329 { | |
1330 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound); | |
1331 return EXP_CANT_INTERPRET; | |
1332 } | |
1333 if (upperbound-lowerbound != dim) | |
1334 { | |
1335 // Only modifying part of the array. Must create a new array literal. | |
1336 // If the existing array is uninitialized (this can only happen | |
1337 // with static arrays), create it. | |
1338 if (v.value && v.value.op == TOKarrayliteral) | |
1339 existing = cast(ArrayLiteralExp)v.value; | |
1340 else | |
1341 { | |
1342 // this can only happen with static arrays | |
1343 existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim); | |
1344 } | |
1345 } | |
1346 | |
1347 if (e2.op == TOKarrayliteral) | |
1348 { | |
1349 // Static array assignment from literal | |
174 | 1350 ArrayLiteralExp ae = cast(ArrayLiteralExp)e2; |
63 | 1351 if (ae.elements.dim != (upperbound - lowerbound)) |
1352 { | |
1353 error("Array length mismatch assigning [0..%d] to [%d..%d]", ae.elements.dim, lowerbound, upperbound); | |
1354 return e; | |
1355 } | |
1356 if (upperbound - lowerbound == dim) | |
1357 v.value = ae; | |
1358 else | |
1359 { | |
1360 // value[] = value[0..lower] ~ ae ~ value[upper..$] | |
1361 existing.elements = spliceElements(existing.elements, ae.elements, lowerbound); | |
1362 v.value = existing; | |
1363 } | |
1364 return e2; | |
1365 } | |
1366 else if (t.nextOf().ty == e2.type.ty) | |
1367 { | |
1368 // Static array block assignment | |
1369 if (upperbound-lowerbound ==dim) | |
1370 v.value = createBlockDuplicatedArrayLiteral(v.type, e2, dim); | |
1371 else | |
1372 { | |
1373 // value[] = value[0..lower] ~ ae ~ value[upper..$] | |
1374 existing.elements = spliceElements(existing.elements, createBlockDuplicatedArrayLiteral(v.type, e2, upperbound-lowerbound).elements, lowerbound); | |
1375 v.value = existing; | |
174 | 1376 } |
63 | 1377 return e2; |
1378 } | |
1379 else if (e2.op == TOKstring) | |
1380 { | |
1381 StringExp se = cast(StringExp)e2; | |
1382 // This is problematic. char[8] should be storing | |
1383 // values as a string literal, not | |
1384 // as an array literal. Then, for static arrays, we | |
1385 // could do modifications | |
1386 // in-place, with a dramatic memory and speed improvement. | |
1387 error("String slice assignment is not yet supported in CTFE"); | |
1388 return e2; | |
1389 } | |
1390 else | |
1391 { | |
1392 error("Slice operation %s cannot be evaluated at compile time", toChars()); | |
1393 return e; | |
1394 } | |
1395 } | |
1396 else | |
1397 { | |
1398 error("%s cannot be evaluated at compile time", toChars()); | |
1399 version (DEBUG) { | |
1400 dump(0); | |
1401 } | |
1402 } | |
1403 return e; | |
0 | 1404 } |
115
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
1405 |
6caaf0256da1
+ interpretation of (non-assign) binary expressions
Trass3r
parents:
114
diff
changeset
|
1406 version(DMDV2) |
72 | 1407 override bool canThrow() |
0 | 1408 { |
1409 return e1.canThrow() || e2.canThrow(); | |
1410 } | |
174 | 1411 |
73 | 1412 // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary |
1413 void checkComplexMulAssign() | |
1414 { | |
1415 // Any multiplication by an imaginary or complex number yields a complex result. | |
1416 // r *= c, i*=c, r*=i, i*=i are all forbidden operations. | |
1417 string opstr = Token.toChars(op); | |
1418 if ( e1.type.isreal() && e2.type.iscomplex()) | |
1419 { | |
1420 error("%s %s %s is undefined. Did you mean %s %s %s.re ?", | |
174 | 1421 e1.type.toChars(), opstr, e2.type.toChars(), |
73 | 1422 e1.type.toChars(), opstr, e2.type.toChars()); |
1423 } | |
1424 else if (e1.type.isimaginary() && e2.type.iscomplex()) | |
1425 { | |
1426 error("%s %s %s is undefined. Did you mean %s %s %s.im ?", | |
1427 e1.type.toChars(), opstr, e2.type.toChars(), | |
1428 e1.type.toChars(), opstr, e2.type.toChars()); | |
1429 } | |
1430 else if ((e1.type.isreal() || e1.type.isimaginary()) && e2.type.isimaginary()) | |
1431 { | |
1432 error("%s %s %s is an undefined operation", e1.type.toChars(), | |
1433 opstr, e2.type.toChars()); | |
1434 } | |
1435 } | |
1436 | |
1437 // generate an error if this is a nonsensical += or -=, eg real += imaginary | |
1438 void checkComplexAddAssign() | |
1439 { | |
1440 // Addition or subtraction of a real and an imaginary is a complex result. | |
1441 // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations. | |
1442 if ( (e1.type.isreal() && (e2.type.isimaginary() || e2.type.iscomplex())) || | |
174 | 1443 (e1.type.isimaginary() && (e2.type.isreal() || e2.type.iscomplex())) |
73 | 1444 ) |
1445 { | |
1446 error("%s %s %s is undefined (result is complex)", | |
1447 e1.type.toChars(), Token.toChars(op), e2.type.toChars()); | |
1448 } | |
1449 } | |
1450 | |
0 | 1451 |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1452 /*********************************** |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1453 * Construct the array operation expression. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1454 */ |
0 | 1455 Expression arrayOp(Scope sc) |
1456 { | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1457 //printf("BinExp.arrayOp() %s\n", toChars()); |
174 | 1458 |
73 | 1459 if (type.toBasetype().nextOf().toBasetype().ty == Tvoid) |
1460 { | |
1461 error("Cannot perform array operations on void[] arrays"); | |
1462 return new ErrorExp(); | |
1463 } | |
174 | 1464 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
1465 auto arguments = new Expressions(); |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1466 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1467 /* The expression to generate an array operation for is mangled |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1468 * into a name to use as the array operation function name. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1469 * Mangle in the operands and operators in RPN order, and type. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1470 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1471 scope OutBuffer buf = new OutBuffer(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1472 buf.writestring("_array"); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1473 buildArrayIdent(buf, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1474 buf.writeByte('_'); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1475 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1476 /* Append deco of array element type |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1477 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1478 version (DMDV2) { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1479 buf.writestring(type.toBasetype().nextOf().toBasetype().mutableOf().deco); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1480 } else { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1481 buf.writestring(type.toBasetype().nextOf().toBasetype().deco); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1482 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1483 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1484 size_t namelen = buf.offset; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1485 buf.writeByte(0); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1486 immutable(char)* name = cast(immutable(char)*)buf.extractData(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1487 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1488 /* Look up name in hash table |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1489 */ |
178 | 1490 auto s = name[0..namelen]; |
1491 Object* sv = global.arrayfuncs.update(s); | |
1492 FuncDeclaration fd = cast(FuncDeclaration)*sv; | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1493 if (!fd) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1494 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1495 /* Some of the array op functions are written as library functions, |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1496 * presumably to optimize them with special CPU vector instructions. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1497 * List those library functions here, in alpha order. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1498 */ |
175 | 1499 enum const(char)*[] libArrayopFuncs = |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1500 [ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1501 "_arrayExpSliceAddass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1502 "_arrayExpSliceAddass_d", // T[]+=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1503 "_arrayExpSliceAddass_f", // T[]+=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1504 "_arrayExpSliceAddass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1505 "_arrayExpSliceAddass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1506 "_arrayExpSliceAddass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1507 "_arrayExpSliceAddass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1508 "_arrayExpSliceAddass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1509 "_arrayExpSliceAddass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1510 "_arrayExpSliceAddass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1511 "_arrayExpSliceAddass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1512 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1513 "_arrayExpSliceDivass_d", // T[]/=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1514 "_arrayExpSliceDivass_f", // T[]/=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1515 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1516 "_arrayExpSliceMinSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1517 "_arrayExpSliceMinSliceAssign_d", // T[]=T-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1518 "_arrayExpSliceMinSliceAssign_f", // T[]=T-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1519 "_arrayExpSliceMinSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1520 "_arrayExpSliceMinSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1521 "_arrayExpSliceMinSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1522 "_arrayExpSliceMinSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1523 "_arrayExpSliceMinSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1524 "_arrayExpSliceMinSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1525 "_arrayExpSliceMinSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1526 "_arrayExpSliceMinSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1527 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1528 "_arrayExpSliceMinass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1529 "_arrayExpSliceMinass_d", // T[]-=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1530 "_arrayExpSliceMinass_f", // T[]-=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1531 "_arrayExpSliceMinass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1532 "_arrayExpSliceMinass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1533 "_arrayExpSliceMinass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1534 "_arrayExpSliceMinass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1535 "_arrayExpSliceMinass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1536 "_arrayExpSliceMinass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1537 "_arrayExpSliceMinass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1538 "_arrayExpSliceMinass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1539 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1540 "_arrayExpSliceMulass_d", // T[]*=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1541 "_arrayExpSliceMulass_f", // T[]*=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1542 "_arrayExpSliceMulass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1543 "_arrayExpSliceMulass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1544 "_arrayExpSliceMulass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1545 "_arrayExpSliceMulass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1546 "_arrayExpSliceMulass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1547 "_arrayExpSliceMulass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1548 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1549 "_arraySliceExpAddSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1550 "_arraySliceExpAddSliceAssign_d", // T[]=T[]+T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1551 "_arraySliceExpAddSliceAssign_f", // T[]=T[]+T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1552 "_arraySliceExpAddSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1553 "_arraySliceExpAddSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1554 "_arraySliceExpAddSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1555 "_arraySliceExpAddSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1556 "_arraySliceExpAddSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1557 "_arraySliceExpAddSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1558 "_arraySliceExpAddSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1559 "_arraySliceExpAddSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1560 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1561 "_arraySliceExpDivSliceAssign_d", // T[]=T[]/T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1562 "_arraySliceExpDivSliceAssign_f", // T[]=T[]/T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1563 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1564 "_arraySliceExpMinSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1565 "_arraySliceExpMinSliceAssign_d", // T[]=T[]-T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1566 "_arraySliceExpMinSliceAssign_f", // T[]=T[]-T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1567 "_arraySliceExpMinSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1568 "_arraySliceExpMinSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1569 "_arraySliceExpMinSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1570 "_arraySliceExpMinSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1571 "_arraySliceExpMinSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1572 "_arraySliceExpMinSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1573 "_arraySliceExpMinSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1574 "_arraySliceExpMinSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1575 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1576 "_arraySliceExpMulSliceAddass_d", // T[] += T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1577 "_arraySliceExpMulSliceAddass_f", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1578 "_arraySliceExpMulSliceAddass_r", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1579 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1580 "_arraySliceExpMulSliceAssign_d", // T[]=T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1581 "_arraySliceExpMulSliceAssign_f", // T[]=T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1582 "_arraySliceExpMulSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1583 "_arraySliceExpMulSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1584 "_arraySliceExpMulSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1585 "_arraySliceExpMulSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1586 "_arraySliceExpMulSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1587 "_arraySliceExpMulSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1588 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1589 "_arraySliceExpMulSliceMinass_d", // T[] -= T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1590 "_arraySliceExpMulSliceMinass_f", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1591 "_arraySliceExpMulSliceMinass_r", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1592 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1593 "_arraySliceSliceAddSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1594 "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1595 "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1596 "_arraySliceSliceAddSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1597 "_arraySliceSliceAddSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1598 "_arraySliceSliceAddSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1599 "_arraySliceSliceAddSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1600 "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1601 "_arraySliceSliceAddSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1602 "_arraySliceSliceAddSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1603 "_arraySliceSliceAddSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1604 "_arraySliceSliceAddSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1605 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1606 "_arraySliceSliceAddass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1607 "_arraySliceSliceAddass_d", // T[]+=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1608 "_arraySliceSliceAddass_f", // T[]+=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1609 "_arraySliceSliceAddass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1610 "_arraySliceSliceAddass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1611 "_arraySliceSliceAddass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1612 "_arraySliceSliceAddass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1613 "_arraySliceSliceAddass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1614 "_arraySliceSliceAddass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1615 "_arraySliceSliceAddass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1616 "_arraySliceSliceAddass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1617 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1618 "_arraySliceSliceMinSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1619 "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1620 "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1621 "_arraySliceSliceMinSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1622 "_arraySliceSliceMinSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1623 "_arraySliceSliceMinSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1624 "_arraySliceSliceMinSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1625 "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1626 "_arraySliceSliceMinSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1627 "_arraySliceSliceMinSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1628 "_arraySliceSliceMinSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1629 "_arraySliceSliceMinSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1630 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1631 "_arraySliceSliceMinass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1632 "_arraySliceSliceMinass_d", // T[]-=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1633 "_arraySliceSliceMinass_f", // T[]-=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1634 "_arraySliceSliceMinass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1635 "_arraySliceSliceMinass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1636 "_arraySliceSliceMinass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1637 "_arraySliceSliceMinass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1638 "_arraySliceSliceMinass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1639 "_arraySliceSliceMinass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1640 "_arraySliceSliceMinass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1641 "_arraySliceSliceMinass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1642 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1643 "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1644 "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1645 "_arraySliceSliceMulSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1646 "_arraySliceSliceMulSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1647 "_arraySliceSliceMulSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1648 "_arraySliceSliceMulSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1649 "_arraySliceSliceMulSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1650 "_arraySliceSliceMulSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1651 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1652 "_arraySliceSliceMulass_d", // T[]*=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1653 "_arraySliceSliceMulass_f", // T[]*=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1654 "_arraySliceSliceMulass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1655 "_arraySliceSliceMulass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1656 "_arraySliceSliceMulass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1657 "_arraySliceSliceMulass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1658 "_arraySliceSliceMulass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1659 "_arraySliceSliceMulass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1660 ]; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1661 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1662 int i = binary(name, libArrayopFuncs.ptr, libArrayopFuncs.length); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1663 if (i == -1) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1664 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1665 debug { // Make sure our array is alphabetized |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1666 for (i = 0; i < libArrayopFuncs.length; i++) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1667 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1668 if (strcmp(name, libArrayopFuncs[i]) == 0) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1669 assert(false); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1670 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1671 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1672 /* Not in library, so generate it. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1673 * Construct the function body: |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1674 * foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1675 * loopbody; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1676 * return p; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1677 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1678 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
1679 auto fparams = new Parameters(); |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1680 Expression loopbody = buildArrayLoop(fparams); |
126
1765f3ef917d
ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
1681 auto p = fparams[0 /*fparams.dim - 1*/]; |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1682 version (DMDV1) { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1683 // for (size_t i = 0; i < p.length; i++) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1684 Initializer init = new ExpInitializer(0, new IntegerExp(0, 0, Type.tsize_t)); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1685 Dsymbol d = new VarDeclaration(0, Type.tsize_t, Id.p, init); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1686 Statement s1 = new ForStatement(0, |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1687 new DeclarationStatement(0, d), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1688 new CmpExp(TOKlt, 0, new IdentifierExp(0, Id.p), new ArrayLengthExp(0, new IdentifierExp(0, p.ident))), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1689 new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id.p)), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1690 new ExpStatement(0, loopbody)); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1691 } else { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1692 // foreach (i; 0 .. p.length) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1693 Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach, |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
1694 new Parameter(STC.STCundefined, null, Id.p, null), |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1695 new IntegerExp(Loc(0), 0, Type.tint32), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1696 new ArrayLengthExp(Loc(0), new IdentifierExp(Loc(0), p.ident)), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1697 new ExpStatement(Loc(0), loopbody)); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1698 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1699 Statement s2 = new ReturnStatement(Loc(0), new IdentifierExp(Loc(0), p.ident)); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1700 //printf("s2: %s\n", s2.toChars()); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1701 Statement fbody = new CompoundStatement(Loc(0), s1, s2); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1702 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1703 /* Construct the function |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1704 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1705 TypeFunction ftype = new TypeFunction(fparams, type, 0, LINKc); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1706 //printf("ftype: %s\n", ftype.toChars()); |
178 | 1707 fd = new FuncDeclaration(Loc(0), Loc(0), Lexer.idPool(s), STCundefined, ftype); |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1708 fd.fbody = fbody; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1709 fd.protection = PROT.PROTpublic; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1710 fd.linkage = LINKc; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1711 |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
1712 sc.module_.importedFrom.members.push(fd); |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1713 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1714 sc = sc.push(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1715 sc.parent = sc.module_.importedFrom; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1716 sc.stc = STCundefined; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1717 sc.linkage = LINKc; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1718 fd.semantic(sc); |
79 | 1719 fd.semantic2(sc); |
1720 fd.semantic3(sc); | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1721 sc.pop(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1722 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1723 else |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1724 { /* In library, refer to it. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1725 */ |
178 | 1726 fd = FuncDeclaration.genCfunc(type, s); |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1727 } |
178 | 1728 *sv = fd; // cache symbol in hash table |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1729 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1730 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1731 /* Call the function fd(arguments) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1732 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1733 Expression ec = new VarExp(Loc(0), fd); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1734 Expression e = new CallExp(loc, ec, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1735 e.type = type; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1736 return e; |
0 | 1737 } |
1738 | |
72 | 1739 override int inlineCost(InlineCostState* ics) |
0 | 1740 { |
1741 return 1 + e1.inlineCost(ics) + e2.inlineCost(ics); | |
1742 } | |
174 | 1743 |
72 | 1744 override Expression doInline(InlineDoState ids) |
0 | 1745 { |
1746 BinExp be = cast(BinExp)copy(); | |
1747 | |
1748 be.e1 = e1.doInline(ids); | |
1749 be.e2 = e2.doInline(ids); | |
1750 return be; | |
1751 } | |
174 | 1752 |
72 | 1753 override Expression inlineScan(InlineScanState* iss) |
0 | 1754 { |
1755 e1 = e1.inlineScan(iss); | |
1756 e2 = e2.inlineScan(iss); | |
1757 return this; | |
1758 } | |
1759 | |
1760 Expression op_overload(Scope sc) | |
1761 { | |
1762 //printf("BinExp.op_overload() (%s)\n", toChars()); | |
1763 | |
1764 AggregateDeclaration ad; | |
1765 Type t1 = e1.type.toBasetype(); | |
1766 Type t2 = e2.type.toBasetype(); | |
1767 Identifier id = opId(); | |
1768 Identifier id_r = opId_r(); | |
1769 | |
1770 Match m; | |
1771 scope Expressions args1 = new Expressions(); | |
1772 scope Expressions args2 = new Expressions(); | |
1773 int argsset = 0; | |
1774 | |
1775 AggregateDeclaration ad1; | |
1776 if (t1.ty == TY.Tclass) | |
1777 ad1 = (cast(TypeClass)t1).sym; | |
1778 else if (t1.ty == TY.Tstruct) | |
1779 ad1 = (cast(TypeStruct)t1).sym; | |
1780 else | |
1781 ad1 = null; | |
1782 | |
1783 AggregateDeclaration ad2; | |
1784 if (t2.ty == TY.Tclass) | |
1785 ad2 = (cast(TypeClass)t2).sym; | |
1786 else if (t2.ty == TY.Tstruct) | |
1787 ad2 = (cast(TypeStruct)t2).sym; | |
1788 else | |
1789 ad2 = null; | |
1790 | |
1791 Dsymbol s = null; | |
1792 Dsymbol s_r = null; | |
1793 FuncDeclaration fd = null; | |
1794 TemplateDeclaration td = null; | |
1795 if (ad1 && id) | |
1796 { | |
1797 s = search_function(ad1, id); | |
1798 } | |
1799 if (ad2 && id_r) | |
1800 { | |
1801 s_r = search_function(ad2, id_r); | |
1802 } | |
1803 | |
1804 if (s || s_r) | |
1805 { | |
1806 /* Try: | |
1807 * a.opfunc(b) | |
1808 * b.opfunc_r(a) | |
1809 * and see which is better. | |
1810 */ | |
1811 Expression e; | |
1812 FuncDeclaration lastf; | |
1813 | |
1814 args1.setDim(1); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1815 args1[0] = e1; |
0 | 1816 args2.setDim(1); |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1817 args2[0] = e2; |
0 | 1818 argsset = 1; |
1819 | |
1820 ///memset(&m, 0, sizeof(m)); | |
1821 m.last = MATCH.MATCHnomatch; | |
1822 | |
1823 if (s) | |
1824 { | |
1825 fd = s.isFuncDeclaration(); | |
1826 if (fd) | |
1827 { | |
1828 overloadResolveX(&m, fd, null, args2); | |
1829 } | |
1830 else | |
174 | 1831 { |
0 | 1832 td = s.isTemplateDeclaration(); |
1833 templateResolve(&m, td, sc, loc, null, null, args2); | |
1834 } | |
1835 } | |
174 | 1836 |
0 | 1837 lastf = m.lastf; |
1838 | |
1839 if (s_r) | |
1840 { | |
1841 fd = s_r.isFuncDeclaration(); | |
1842 if (fd) | |
1843 { | |
1844 overloadResolveX(&m, fd, null, args1); | |
1845 } | |
1846 else | |
174 | 1847 { |
0 | 1848 td = s_r.isTemplateDeclaration(); |
1849 templateResolve(&m, td, sc, loc, null, null, args1); | |
1850 } | |
1851 } | |
1852 | |
1853 if (m.count > 1) | |
1854 { | |
1855 // Error, ambiguous | |
1856 error("overloads %s and %s both match argument list for %s", | |
1857 m.lastf.type.toChars(), | |
1858 m.nextf.type.toChars(), | |
1859 m.lastf.toChars()); | |
1860 } | |
1861 else if (m.last == MATCH.MATCHnomatch) | |
1862 { | |
1863 m.lastf = m.anyf; | |
1864 } | |
1865 | |
1866 if (op == TOK.TOKplusplus || op == TOK.TOKminusminus) | |
1867 // Kludge because operator overloading regards e++ and e-- | |
1868 // as unary, but it's implemented as a binary. | |
1869 // Rewrite (e1 ++ e2) as e1.postinc() | |
1870 // Rewrite (e1 -- e2) as e1.postdec() | |
1871 e = build_overload(loc, sc, e1, null, id); | |
1872 else if (lastf && m.lastf == lastf || m.last == MATCH.MATCHnomatch) | |
1873 // Rewrite (e1 op e2) as e1.opfunc(e2) | |
1874 e = build_overload(loc, sc, e1, e2, id); | |
1875 else | |
1876 // Rewrite (e1 op e2) as e2.opfunc_r(e1) | |
1877 e = build_overload(loc, sc, e2, e1, id_r); | |
1878 return e; | |
1879 } | |
1880 | |
1881 if (isCommutative()) | |
1882 { | |
1883 s = null; | |
1884 s_r = null; | |
1885 if (ad1 && id_r) | |
1886 { | |
1887 s_r = search_function(ad1, id_r); | |
1888 } | |
1889 if (ad2 && id) | |
1890 { | |
1891 s = search_function(ad2, id); | |
1892 } | |
1893 | |
1894 if (s || s_r) | |
1895 { | |
1896 /* Try: | |
1897 * a.opfunc_r(b) | |
1898 * b.opfunc(a) | |
1899 * and see which is better. | |
1900 */ | |
1901 | |
1902 if (!argsset) | |
174 | 1903 { |
0 | 1904 args1.setDim(1); |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1905 args1[0] = e1; |
0 | 1906 args2.setDim(1); |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1907 args2[0] = e2; |
0 | 1908 } |
1909 | |
1910 ///memset(&m, 0, sizeof(m)); | |
1911 m.last = MATCH.MATCHnomatch; | |
1912 | |
1913 if (s_r) | |
1914 { | |
1915 fd = s_r.isFuncDeclaration(); | |
1916 if (fd) | |
1917 { | |
1918 overloadResolveX(&m, fd, null, args2); | |
1919 } | |
1920 else | |
1921 { td = s_r.isTemplateDeclaration(); | |
1922 templateResolve(&m, td, sc, loc, null, null, args2); | |
1923 } | |
1924 } | |
1925 FuncDeclaration lastf = m.lastf; | |
1926 | |
1927 if (s) | |
1928 { | |
1929 fd = s.isFuncDeclaration(); | |
1930 if (fd) | |
1931 { | |
1932 overloadResolveX(&m, fd, null, args1); | |
1933 } | |
1934 else | |
1935 { td = s.isTemplateDeclaration(); | |
1936 templateResolve(&m, td, sc, loc, null, null, args1); | |
1937 } | |
1938 } | |
1939 | |
1940 if (m.count > 1) | |
1941 { | |
1942 // Error, ambiguous | |
1943 error("overloads %s and %s both match argument list for %s", | |
1944 m.lastf.type.toChars(), | |
1945 m.nextf.type.toChars(), | |
1946 m.lastf.toChars()); | |
1947 } | |
1948 else if (m.last == MATCH.MATCHnomatch) | |
1949 { | |
1950 m.lastf = m.anyf; | |
1951 } | |
1952 | |
1953 Expression e; | |
1954 if (lastf && m.lastf == lastf || id_r && m.last == MATCH.MATCHnomatch) | |
1955 // Rewrite (e1 op e2) as e1.opfunc_r(e2) | |
1956 e = build_overload(loc, sc, e1, e2, id_r); | |
1957 else | |
1958 // Rewrite (e1 op e2) as e2.opfunc(e1) | |
1959 e = build_overload(loc, sc, e2, e1, id); | |
1960 | |
1961 // When reversing operands of comparison operators, | |
1962 // need to reverse the sense of the op | |
1963 switch (op) | |
1964 { | |
1965 case TOK.TOKlt: op = TOK.TOKgt; break; | |
1966 case TOK.TOKgt: op = TOK.TOKlt; break; | |
1967 case TOK.TOKle: op = TOK.TOKge; break; | |
1968 case TOK.TOKge: op = TOK.TOKle; break; | |
1969 | |
1970 // Floating point compares | |
1971 case TOK.TOKule: op = TOK.TOKuge; break; | |
1972 case TOK.TOKul: op = TOK.TOKug; break; | |
1973 case TOK.TOKuge: op = TOK.TOKule; break; | |
1974 case TOK.TOKug: op = TOK.TOKul; break; | |
1975 | |
1976 // These are symmetric | |
1977 case TOK.TOKunord: | |
1978 case TOK.TOKlg: | |
1979 case TOK.TOKleg: | |
1980 case TOK.TOKue: | |
1981 break; | |
123 | 1982 default: |
1983 break; /// | |
0 | 1984 } |
1985 | |
1986 return e; | |
1987 } | |
1988 } | |
1989 | |
1990 version (DMDV2) { | |
1991 // Try alias this on first operand | |
1992 if (ad1 && ad1.aliasthis) | |
1993 { | |
1994 /* Rewrite (e1 op e2) as: | |
1995 * (e1.aliasthis op e2) | |
1996 */ | |
1997 Expression e1 = new DotIdExp(loc, this.e1, ad1.aliasthis.ident); | |
1998 Expression e = copy(); | |
1999 (cast(BinExp)e).e1 = e1; | |
2000 e = e.semantic(sc); | |
2001 return e; | |
2002 } | |
2003 | |
2004 // Try alias this on second operand | |
2005 if (ad2 && ad2.aliasthis) | |
2006 { | |
2007 /* Rewrite (e1 op e2) as: | |
2008 * (e1 op e2.aliasthis) | |
2009 */ | |
2010 Expression e2 = new DotIdExp(loc, this.e2, ad2.aliasthis.ident); | |
2011 Expression e = copy(); | |
2012 (cast(BinExp)e).e2 = e2; | |
2013 e = e.semantic(sc); | |
2014 return e; | |
2015 } | |
2016 } | |
2017 return null; | |
2018 } | |
2019 | |
2020 elem* toElemBin(IRState* irs, int op) | |
2021 { | |
2022 //printf("toElemBin() '%s'\n", toChars()); | |
2023 | |
2024 tym_t tym = type.totym(); | |
2025 | |
2026 elem* el = e1.toElem(irs); | |
2027 elem* er = e2.toElem(irs); | |
2028 elem* e = el_bin(op,tym,el,er); | |
2029 el_setLoc(e,loc); | |
2030 | |
2031 return e; | |
2032 } | |
123 | 2033 final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) |
174 | 2034 { |
2035 /* Evaluate assign expressions right to left | |
2036 */ | |
2037 e2.buildArrayIdent(buf, arguments); | |
2038 e1.buildArrayIdent(buf, arguments); | |
2039 buf.writestring(Str); | |
2040 buf.writestring("ass"); | |
123 | 2041 } |
174 | 2042 |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
2043 final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) |
174 | 2044 { |
2045 /* Evaluate assign expressions left to right | |
2046 */ | |
2047 e1.buildArrayIdent(buf, arguments); | |
2048 e2.buildArrayIdent(buf, arguments); | |
2049 buf.writestring(Str); | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
2050 } |
174 | 2051 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
2052 final Expression AssignExp_buildArrayLoop(AssignExpType)(Parameters fparams)// if (is (AssignExpType : AssignExp)) |
123 | 2053 { |
2054 /* Evaluate assign expressions right to left | |
2055 */ | |
2056 Expression ex2 = e2.buildArrayLoop(fparams); | |
2057 Expression ex1 = e1.buildArrayLoop(fparams); | |
126
1765f3ef917d
ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
2058 auto param = fparams[0]; |
123 | 2059 param.storageClass = STCundefined; |
2060 Expression e = new AssignExpType(Loc(0), ex1, ex2); | |
2061 return e; | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
2062 } |
174 | 2063 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
2064 final Expression Exp_buildArrayLoop(ExpType)(Parameters fparams) if (is (ExpType : BinExp)) |
123 | 2065 { |
2066 /* Evaluate assign expressions left to right | |
2067 */ | |
2068 Expression ex1 = e1.buildArrayLoop(fparams); | |
2069 Expression ex2 = e2.buildArrayLoop(fparams); | |
2070 Expression e = new ExpType(Loc(0), ex1, ex2); | |
2071 return e; | |
2072 } | |
174 | 2073 } |