Mercurial > projects > ddmd
annotate dmd/BinExp.d @ 56:51605de93870
TupleExp.optimize
UnrolledLoopStatement.ctor
UnrolledLoopStatement.semantic
UnrolledLoopStatement.blockExit
OrOrExp.checkSideEffect
FuncExp.syntaxCopy
FuncLiteralDeclaration.syntaxCopy
WhileStatement.hasBreak
StructInitializer.toExpression
StructLiteralExp.ctor
StructLiteralExp.optimize
BinExp.commonSemanticAssign
ModAssignExp.opId
Argument.isLazyArray
CommaExp.implicitConvTo
CommaExp.castTo
TypeClass.isBaseOf
createTypeInfoArray
TypeTuple.getTypeInfoDeclaration
TypeInfoTupleDeclaration.ctor
TypeNext.constConv
XorExp.implicitConvTo
TemplateParameter.isTemplateValueParameter
author | korDen |
---|---|
date | Sat, 21 Aug 2010 14:16:53 +0400 |
parents | 832f71e6f96c |
children | a8740d0dbea4 |
rev | line source |
---|---|
0 | 1 module dmd.BinExp; |
2 | |
3 import dmd.Expression; | |
4 import dmd.Loc; | |
5 import dmd.ClassDeclaration; | |
6 import dmd.OutBuffer; | |
7 import dmd.HdrGenState; | |
8 import dmd.TOK; | |
9 import dmd.IRState; | |
10 import dmd.Scope; | |
11 import dmd.Type; | |
12 import dmd.InterState; | |
13 import dmd.InlineCostState; | |
14 import dmd.InlineScanState; | |
15 import dmd.InlineDoState; | |
16 import dmd.AggregateDeclaration; | |
17 import dmd.Identifier; | |
18 import dmd.MATCH; | |
19 import dmd.declaration.Match; | |
20 import dmd.ArrayTypes; | |
21 import dmd.TY; | |
22 import dmd.TypeClass; | |
23 import dmd.TypeStruct; | |
24 import dmd.Dsymbol; | |
25 import dmd.FuncDeclaration; | |
26 import dmd.TemplateDeclaration; | |
27 import dmd.DotIdExp; | |
28 import dmd.ErrorExp; | |
29 import dmd.WANT; | |
30 import dmd.IntegerExp; | |
31 import dmd.MulExp; | |
32 import dmd.Token; | |
33 import dmd.PREC; | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
34 import dmd.StringValue; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
35 import dmd.StringTable; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
36 import dmd.Argument; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
37 import dmd.Statement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
38 import dmd.ForeachRangeStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
39 import dmd.ArrayLengthExp; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
40 import dmd.IdentifierExp; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
41 import dmd.ExpStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
42 import dmd.CompoundStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
43 import dmd.TypeFunction; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
44 import dmd.LINK; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
45 import dmd.Lexer; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
46 import dmd.ReturnStatement; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
47 import dmd.Id; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
48 import dmd.STC; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
49 import dmd.PROT; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
50 import dmd.VarExp; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
51 import dmd.CallExp; |
0 | 52 |
53 import dmd.expression.Util; | |
54 | |
55 import dmd.backend.elem; | |
56 import dmd.backend.Util; | |
57 | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
58 import dmd.backend.iasm : binary; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
59 |
0 | 60 import std.stdio : writef; |
61 | |
62 /************************************** | |
63 * Combine types. | |
64 * Output: | |
65 * *pt merged type, if *pt is not null | |
66 * *pe1 rewritten e1 | |
67 * *pe2 rewritten e2 | |
68 * Returns: | |
69 * !=0 success | |
70 * 0 failed | |
71 */ | |
72 | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
73 /************************************** |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
74 * 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
|
75 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
76 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
77 __gshared StringTable arrayfuncs; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
78 |
0 | 79 int typeMerge(Scope sc, Expression e, Type* pt, Expression* pe1, Expression* pe2) |
80 { | |
81 //printf("typeMerge() %s op %s\n", (*pe1).toChars(), (*pe2).toChars()); | |
82 //dump(0); | |
83 | |
84 Expression e1 = (*pe1).integralPromotions(sc); | |
85 Expression e2 = (*pe2).integralPromotions(sc); | |
86 | |
87 Type t1 = e1.type; | |
88 Type t2 = e2.type; | |
89 assert(t1); | |
90 Type t = t1; | |
91 | |
92 //if (t1) printf("\tt1 = %s\n", t1.toChars()); | |
93 //if (t2) printf("\tt2 = %s\n", t2.toChars()); | |
94 debug { | |
95 if (!t2) writef("\te2 = '%s'\n", e2.toChars()); | |
96 } | |
97 assert(t2); | |
98 | |
99 Type t1b = t1.toBasetype(); | |
100 Type t2b = t2.toBasetype(); | |
101 | |
102 TY ty = cast(TY)Type.impcnvResult[t1b.ty][t2b.ty]; | |
103 if (ty != TY.Terror) | |
104 { | |
105 TY ty1; | |
106 TY ty2; | |
107 | |
108 ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty]; | |
109 ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty]; | |
110 | |
111 if (t1b.ty == ty1) // if no promotions | |
112 { | |
113 if (t1 == t2) | |
114 { | |
115 t = t1; | |
116 goto Lret; | |
117 } | |
118 | |
119 if (t1b == t2b) | |
120 { | |
121 t = t1b; | |
122 goto Lret; | |
123 } | |
124 } | |
125 | |
126 t = Type.basic[ty]; | |
127 | |
128 t1 = Type.basic[ty1]; | |
129 t2 = Type.basic[ty2]; | |
130 | |
131 e1 = e1.castTo(sc, t1); | |
132 e2 = e2.castTo(sc, t2); | |
133 //printf("after typeCombine():\n"); | |
134 //dump(0); | |
135 //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2); | |
136 goto Lret; | |
137 } | |
138 | |
139 t1 = t1b; | |
140 t2 = t2b; | |
141 | |
142 Lagain: | |
143 if (t1 == t2) | |
144 { | |
145 } | |
146 else if (t1.ty == TY.Tpointer && t2.ty == TY.Tpointer) | |
147 { | |
148 // Bring pointers to compatible type | |
149 Type t1n = t1.nextOf(); | |
150 Type t2n = t2.nextOf(); | |
151 | |
152 if (t1n == t2n) { | |
153 ; | |
154 } else if (t1n.ty == TY.Tvoid) {// pointers to void are always compatible | |
155 t = t2; | |
156 } else if (t2n.ty == TY.Tvoid) { | |
157 ; | |
158 } else if (t1n.mod != t2n.mod) { | |
159 t1 = t1n.mutableOf().constOf().pointerTo(); | |
160 t2 = t2n.mutableOf().constOf().pointerTo(); | |
161 t = t1; | |
162 goto Lagain; | |
163 } else if (t1n.ty == TY.Tclass && t2n.ty == TY.Tclass) { | |
164 ClassDeclaration cd1 = t1n.isClassHandle(); | |
165 ClassDeclaration cd2 = t2n.isClassHandle(); | |
166 int offset; | |
167 | |
168 if (cd1.isBaseOf(cd2, &offset)) | |
169 { | |
170 if (offset) | |
171 e2 = e2.castTo(sc, t); | |
172 } | |
173 else if (cd2.isBaseOf(cd1, &offset)) | |
174 { | |
175 t = t2; | |
176 if (offset) | |
177 e1 = e1.castTo(sc, t); | |
178 } | |
179 else | |
180 goto Lincompatible; | |
181 } else { | |
182 goto Lincompatible; | |
183 } | |
184 } | |
185 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && | |
186 e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid) | |
187 { /* (T[n] op void*) | |
188 * (T[] op void*) | |
189 */ | |
190 goto Lx1; | |
191 } | |
192 else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) && | |
193 e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid) | |
194 { /* (void* op T[n]) | |
195 * (void* op T[]) | |
196 */ | |
197 goto Lx2; | |
198 } | |
199 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && t1.implicitConvTo(t2)) | |
200 { | |
201 goto Lt2; | |
202 } | |
203 else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) && t2.implicitConvTo(t1)) | |
204 { | |
205 goto Lt1; | |
206 } | |
207 /* If one is mutable and the other invariant, then retry | |
208 * with both of them as const | |
209 */ | |
210 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray || t1.ty == TY.Tpointer) && | |
211 (t2.ty == TY.Tsarray || t2.ty == TY.Tarray || t2.ty == TY.Tpointer) && | |
212 t1.nextOf().mod != t2.nextOf().mod | |
213 ) | |
214 { | |
215 if (t1.ty == TY.Tpointer) | |
216 t1 = t1.nextOf().mutableOf().constOf().pointerTo(); | |
217 else | |
218 t1 = t1.nextOf().mutableOf().constOf().arrayOf(); | |
219 | |
220 if (t2.ty == TY.Tpointer) | |
221 t2 = t2.nextOf().mutableOf().constOf().pointerTo(); | |
222 else | |
223 t2 = t2.nextOf().mutableOf().constOf().arrayOf(); | |
224 t = t1; | |
225 goto Lagain; | |
226 } | |
227 else if (t1.ty == TY.Tclass || t2.ty == TY.Tclass) | |
228 { | |
229 while (1) | |
230 { | |
231 int i1 = e2.implicitConvTo(t1); | |
232 int i2 = e1.implicitConvTo(t2); | |
233 | |
234 if (i1 && i2) | |
235 { | |
236 // We have the case of class vs. void*, so pick class | |
237 if (t1.ty == TY.Tpointer) | |
238 i1 = 0; | |
239 else if (t2.ty == TY.Tpointer) | |
240 i2 = 0; | |
241 } | |
242 | |
243 if (i2) | |
244 { | |
245 goto Lt2; | |
246 } | |
247 else if (i1) | |
248 { | |
249 goto Lt1; | |
250 } | |
251 else if (t1.ty == TY.Tclass && t2.ty == TY.Tclass) | |
252 { | |
253 TypeClass tc1 = cast(TypeClass)t1; | |
254 TypeClass tc2 = cast(TypeClass)t2; | |
255 | |
256 /* Pick 'tightest' type | |
257 */ | |
258 ClassDeclaration cd1 = tc1.sym.baseClass; | |
259 ClassDeclaration cd2 = tc2.sym.baseClass; | |
260 | |
261 if (cd1 && cd2) | |
262 { t1 = cd1.type; | |
263 t2 = cd2.type; | |
264 } | |
265 else if (cd1) | |
266 t1 = cd1.type; | |
267 else if (cd2) | |
268 t2 = cd2.type; | |
269 else | |
270 goto Lincompatible; | |
271 } | |
272 else | |
273 goto Lincompatible; | |
274 } | |
275 } | |
276 else if (t1.ty == TY.Tstruct && t2.ty == TY.Tstruct) | |
277 { | |
278 if ((cast(TypeStruct)t1).sym != (cast(TypeStruct)t2).sym) | |
279 goto Lincompatible; | |
280 } | |
281 else if ((e1.op == TOK.TOKstring || e1.op == TOK.TOKnull) && e1.implicitConvTo(t2)) | |
282 { | |
283 goto Lt2; | |
284 } | |
285 else if ((e2.op == TOK.TOKstring || e2.op == TOK.TOKnull) && e2.implicitConvTo(t1)) | |
286 { | |
287 goto Lt1; | |
288 } | |
289 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && | |
290 e2.implicitConvTo(t1.nextOf().arrayOf())) | |
291 { | |
292 Lx1: | |
293 t = t1.nextOf().arrayOf(); | |
294 e1 = e1.castTo(sc, t); | |
295 e2 = e2.castTo(sc, t); | |
296 } | |
297 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && | |
298 e1.implicitConvTo(t2.nextOf().arrayOf())) | |
299 { | |
300 Lx2: | |
301 t = t2.nextOf().arrayOf(); | |
302 e1 = e1.castTo(sc, t); | |
303 e2 = e2.castTo(sc, t); | |
304 } | |
305 else if (t1.isintegral() && t2.isintegral()) | |
306 { | |
307 assert(0); | |
308 } | |
309 else if (e1.op == TOK.TOKslice && t1.ty == TY.Tarray && | |
310 e2.implicitConvTo(t1.nextOf())) | |
311 { // T[] op T | |
312 e2 = e2.castTo(sc, t1.nextOf()); | |
313 t = t1.nextOf().arrayOf(); | |
314 } | |
315 else if (e2.op == TOK.TOKslice && t2.ty == TY.Tarray && | |
316 e1.implicitConvTo(t2.nextOf())) | |
317 { // T op T[] | |
318 e1 = e1.castTo(sc, t2.nextOf()); | |
319 t = t2.nextOf().arrayOf(); | |
320 | |
321 //printf("test %s\n", e.toChars()); | |
322 e1 = e1.optimize(WANT.WANTvalue); | |
323 if (e && e.isCommutative() && e1.isConst()) | |
324 { /* Swap operands to minimize number of functions generated | |
325 */ | |
326 //printf("swap %s\n", e.toChars()); | |
327 Expression tmp = e1; | |
328 e1 = e2; | |
329 e2 = tmp; | |
330 } | |
331 } | |
332 else | |
333 { | |
334 Lincompatible: | |
335 return 0; | |
336 } | |
337 Lret: | |
338 if (!*pt) | |
339 *pt = t; | |
340 *pe1 = e1; | |
341 *pe2 = e2; | |
342 static if (false) { | |
343 printf("-typeMerge() %s op %s\n", e1.toChars(), e2.toChars()); | |
344 if (e1.type) printf("\tt1 = %s\n", e1.type.toChars()); | |
345 if (e2.type) printf("\tt2 = %s\n", e2.type.toChars()); | |
346 printf("\ttype = %s\n", t.toChars()); | |
347 } | |
348 //dump(0); | |
349 return 1; | |
350 | |
351 | |
352 Lt1: | |
353 e2 = e2.castTo(sc, t1); | |
354 t = t1; | |
355 goto Lret; | |
356 | |
357 Lt2: | |
358 e1 = e1.castTo(sc, t2); | |
359 t = t2; | |
360 goto Lret; | |
361 } | |
362 | |
363 class BinExp : Expression | |
364 { | |
365 Expression e1; | |
366 Expression e2; | |
367 | |
368 this(Loc loc, TOK op, int size, Expression e1, Expression e2) | |
369 { | |
370 super(loc, op, size); | |
371 this.e1 = e1; | |
372 this.e2 = e2; | |
373 } | |
374 | |
375 Expression syntaxCopy() | |
376 { | |
377 BinExp e = cast(BinExp)copy(); | |
378 e.type = null; | |
379 e.e1 = e.e1.syntaxCopy(); | |
380 e.e2 = e.e2.syntaxCopy(); | |
381 | |
382 return e; | |
383 } | |
384 | |
385 Expression semantic(Scope sc) | |
386 { | |
387 version (LOGSEMANTIC) { | |
388 printf("BinExp.semantic('%s')\n", toChars()); | |
389 } | |
390 e1 = e1.semantic(sc); | |
391 if (!e1.type && !(op == TOK.TOKassign && e1.op == TOK.TOKdottd)) // a.template = e2 | |
392 { | |
393 error("%s has no value", e1.toChars()); | |
394 e1.type = Type.terror; | |
395 } | |
396 e2 = e2.semantic(sc); | |
397 if (!e2.type) | |
398 { | |
399 error("%s has no value", e2.toChars()); | |
400 e2.type = Type.terror; | |
401 } | |
402 return this; | |
403 } | |
404 | |
405 Expression semanticp(Scope sc) | |
406 { | |
407 version (LOGSEMANTIC) { | |
408 printf("BinExp.semantic('%s')\n", toChars()); | |
409 } | |
410 e1 = e1.semantic(sc); | |
411 if (!e1.type && | |
412 !(op == TOK.TOKassign && e1.op == TOK.TOKdottd)) // a.template = e2 | |
413 { | |
414 error("%s has no value", e1.toChars()); | |
415 e1.type = Type.terror; | |
416 } | |
417 e2 = e2.semantic(sc); | |
418 if (!e2.type) | |
419 { | |
420 error("%s has no value", e2.toChars()); | |
421 e2.type = Type.terror; | |
422 } | |
423 return this; | |
424 } | |
425 | |
56 | 426 /*************************** |
427 * Common semantic routine for some xxxAssignExp's. | |
428 */ | |
0 | 429 Expression commonSemanticAssign(Scope sc) |
430 { | |
56 | 431 Expression e; |
432 | |
433 if (!type) | |
434 { | |
435 BinExp.semantic(sc); | |
436 e2 = resolveProperties(sc, e2); | |
437 | |
438 e = op_overload(sc); | |
439 if (e) | |
440 return e; | |
441 | |
442 if (e1.op == TOKslice) | |
443 { | |
444 // T[] op= ... | |
445 typeCombine(sc); | |
446 type = e1.type; | |
447 return arrayOp(sc); | |
448 } | |
449 | |
450 e1 = e1.modifiableLvalue(sc, e1); | |
451 e1.checkScalar(); | |
452 type = e1.type; | |
453 if (type.toBasetype().ty == Tbool) | |
454 { | |
455 error("operator not allowed on bool expression %s", toChars()); | |
456 } | |
457 typeCombine(sc); | |
458 e1.checkArithmetic(); | |
459 e2.checkArithmetic(); | |
460 | |
461 if (op == TOKmodass && e2.type.iscomplex()) | |
462 { error("cannot perform modulo complex arithmetic"); | |
463 return new ErrorExp(); | |
464 } | |
465 } | |
466 return this; | |
0 | 467 } |
468 | |
469 Expression commonSemanticAssignIntegral(Scope sc) | |
470 { | |
471 Expression e; | |
472 | |
473 if (!type) | |
474 { | |
475 BinExp.semantic(sc); | |
476 e2 = resolveProperties(sc, e2); | |
477 | |
478 e = op_overload(sc); | |
479 if (e) | |
480 return e; | |
481 | |
482 if (e1.op == TOK.TOKslice) | |
483 { // T[] op= ... | |
484 typeCombine(sc); | |
485 type = e1.type; | |
486 return arrayOp(sc); | |
487 } | |
488 | |
489 e1 = e1.modifiableLvalue(sc, e1); | |
490 e1.checkScalar(); | |
491 type = e1.type; | |
492 if (type.toBasetype().ty == TY.Tbool) | |
493 { | |
494 e2 = e2.implicitCastTo(sc, type); | |
495 } | |
496 | |
497 typeCombine(sc); | |
498 e1.checkIntegral(); | |
499 e2.checkIntegral(); | |
500 } | |
501 | |
502 return this; | |
503 } | |
504 | |
505 bool checkSideEffect(int flag) | |
506 { | |
507 switch (op) { | |
508 case TOK.TOKplusplus: | |
509 case TOK.TOKminusminus: | |
510 case TOK.TOKassign: | |
511 case TOK.TOKconstruct: | |
512 case TOK.TOKblit: | |
513 case TOK.TOKaddass: | |
514 case TOK.TOKminass: | |
515 case TOK.TOKcatass: | |
516 case TOK.TOKmulass: | |
517 case TOK.TOKdivass: | |
518 case TOK.TOKmodass: | |
519 case TOK.TOKshlass: | |
520 case TOK.TOKshrass: | |
521 case TOK.TOKushrass: | |
522 case TOK.TOKandass: | |
523 case TOK.TOKorass: | |
524 case TOK.TOKxorass: | |
525 case TOK.TOKin: | |
526 case TOK.TOKremove: | |
527 return true; | |
528 | |
529 default: | |
530 return Expression.checkSideEffect(flag); | |
531 } | |
532 } | |
533 | |
534 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
535 { | |
536 expToCBuffer(buf, hgs, e1, precedence[op]); | |
537 buf.writeByte(' '); | |
538 buf.writestring(Token.toChars(op)); | |
539 buf.writeByte(' '); | |
540 expToCBuffer(buf, hgs, e2, cast(PREC)(precedence[op] + 1)); | |
541 } | |
542 | |
543 /**************************************** | |
544 * Scale addition/subtraction to/from pointer. | |
545 */ | |
546 Expression scaleFactor(Scope sc) | |
547 { | |
548 ulong stride; | |
549 Type t1b = e1.type.toBasetype(); | |
550 Type t2b = e2.type.toBasetype(); | |
551 | |
552 if (t1b.ty == Tpointer && t2b.isintegral()) | |
553 { | |
554 // Need to adjust operator by the stride | |
555 // Replace (ptr + int) with (ptr + (int * stride)) | |
556 Type t = Type.tptrdiff_t; | |
557 | |
558 stride = t1b.nextOf().size(loc); | |
559 if (!t.equals(t2b)) | |
560 e2 = e2.castTo(sc, t); | |
561 e2 = new MulExp(loc, e2, new IntegerExp(Loc(0), stride, t)); | |
562 e2.type = t; | |
563 type = e1.type; | |
564 } | |
565 else if (t2b.ty == Tpointer && t1b.isintegral()) | |
566 { | |
567 // Need to adjust operator by the stride | |
568 // Replace (int + ptr) with (ptr + (int * stride)) | |
569 Type t = Type.tptrdiff_t; | |
570 Expression e; | |
571 | |
572 stride = t2b.nextOf().size(loc); | |
573 if (!t.equals(t1b)) | |
574 e = e1.castTo(sc, t); | |
575 else | |
576 e = e1; | |
577 e = new MulExp(loc, e, new IntegerExp(Loc(0), stride, t)); | |
578 e.type = t; | |
579 type = e2.type; | |
580 e1 = e2; | |
581 e2 = e; | |
582 } | |
583 return this; | |
584 } | |
585 | |
586 /************************************ | |
587 * Bring leaves to common type. | |
588 */ | |
589 Expression typeCombine(Scope sc) | |
590 { | |
591 Type t1 = e1.type.toBasetype(); | |
592 Type t2 = e2.type.toBasetype(); | |
593 | |
594 if (op == TOK.TOKmin || op == TOK.TOKadd) | |
595 { | |
596 if (t1.ty == TY.Tstruct) | |
597 { | |
598 if (t2.ty == TY.Tstruct && (cast(TypeStruct)t1).sym is (cast(TypeStruct)t2).sym) | |
599 goto Lerror; | |
600 } | |
601 else if (t1.ty == TY.Tclass) | |
602 { | |
603 if (t2.ty == TY.Tclass) | |
604 goto Lerror; | |
605 } | |
606 } | |
607 | |
608 if (!typeMerge(sc, this, &type, &e1, &e2)) | |
609 goto Lerror; | |
610 return this; | |
611 | |
612 Lerror: | |
613 incompatibleTypes(); | |
614 type = Type.terror; | |
615 e1 = new ErrorExp(); | |
616 e2 = new ErrorExp(); | |
617 return this; | |
618 } | |
619 | |
620 Expression optimize(int result) | |
621 { | |
622 //printf("BinExp.optimize(result = %d) %s\n", result, toChars()); | |
623 if (op != TOK.TOKconstruct && op != TOK.TOKblit) // don't replace const variable with its initializer | |
624 e1 = e1.optimize(result); | |
625 | |
626 e2 = e2.optimize(result); | |
627 if (op == TOK.TOKshlass || op == TOK.TOKshrass || op == TOK.TOKushrass) | |
628 { | |
629 if (e2.isConst() == 1) | |
630 { | |
631 long i2 = e2.toInteger(); | |
632 ulong sz = e1.type.size() * 8; | |
633 | |
634 if (i2 < 0 || i2 > sz) | |
635 { | |
636 error("shift assign by %jd is outside the range 0..%zu", i2, sz); | |
637 e2 = new IntegerExp(0); | |
638 } | |
639 } | |
640 } | |
641 | |
642 return this; | |
643 } | |
644 | |
645 bool isunsigned() | |
646 { | |
647 assert(false); | |
648 } | |
649 | |
650 void incompatibleTypes() | |
651 { | |
652 error("incompatible types for ((%s) %s (%s)): '%s' and '%s'", | |
653 e1.toChars(), Token.toChars(op), e2.toChars(), | |
654 e1.type.toChars(), e2.type.toChars()); | |
655 } | |
656 | |
657 void dump(int indent) | |
658 { | |
659 assert(false); | |
660 } | |
661 | |
662 void scanForNestedRef(Scope *sc) | |
663 { | |
664 assert(false); | |
665 } | |
666 | |
667 Expression interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *, Expression *)) | |
668 { | |
669 assert(false); | |
670 } | |
671 | |
672 Expression interpretCommon2(InterState *istate, Expression *(*fp)(TOK, Type *, Expression *, Expression *)) | |
673 { | |
674 assert(false); | |
675 } | |
676 | |
677 Expression interpretAssignCommon(InterState *istate, Expression *(*fp)(Type *, Expression *, Expression *), int post = 0) | |
678 { | |
679 assert(false); | |
680 } | |
681 | |
682 bool canThrow() | |
683 { | |
684 return e1.canThrow() || e2.canThrow(); | |
685 } | |
686 | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
687 /*********************************** |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
688 * Construct the array operation expression. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
689 */ |
0 | 690 Expression arrayOp(Scope sc) |
691 { | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
692 //printf("BinExp.arrayOp() %s\n", toChars()); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
693 Expressions arguments = new Expressions(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
694 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
695 /* 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
|
696 * 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
|
697 * 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
|
698 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
699 scope OutBuffer buf = new OutBuffer(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
700 buf.writestring("_array"); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
701 buildArrayIdent(buf, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
702 buf.writeByte('_'); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
703 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
704 /* Append deco of array element type |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
705 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
706 version (DMDV2) { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
707 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
|
708 } else { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
709 buf.writestring(type.toBasetype().nextOf().toBasetype().deco); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
710 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
711 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
712 size_t namelen = buf.offset; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
713 buf.writeByte(0); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
714 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
|
715 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
716 /* Look up name in hash table |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
717 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
718 if (arrayfuncs is null) arrayfuncs = new StringTable(); /// HACK! |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
719 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
720 StringValue* sv = arrayfuncs.update(name[0..namelen]); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
721 FuncDeclaration fd = cast(FuncDeclaration)sv.ptrvalue; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
722 if (!fd) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
723 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
724 /* 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
|
725 * 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
|
726 * 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
|
727 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
728 static const(char)*[] libArrayopFuncs = |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
729 [ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
730 "_arrayExpSliceAddass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
731 "_arrayExpSliceAddass_d", // T[]+=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
732 "_arrayExpSliceAddass_f", // T[]+=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
733 "_arrayExpSliceAddass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
734 "_arrayExpSliceAddass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
735 "_arrayExpSliceAddass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
736 "_arrayExpSliceAddass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
737 "_arrayExpSliceAddass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
738 "_arrayExpSliceAddass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
739 "_arrayExpSliceAddass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
740 "_arrayExpSliceAddass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
741 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
742 "_arrayExpSliceDivass_d", // T[]/=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
743 "_arrayExpSliceDivass_f", // T[]/=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
744 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
745 "_arrayExpSliceMinSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
746 "_arrayExpSliceMinSliceAssign_d", // T[]=T-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
747 "_arrayExpSliceMinSliceAssign_f", // T[]=T-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
748 "_arrayExpSliceMinSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
749 "_arrayExpSliceMinSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
750 "_arrayExpSliceMinSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
751 "_arrayExpSliceMinSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
752 "_arrayExpSliceMinSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
753 "_arrayExpSliceMinSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
754 "_arrayExpSliceMinSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
755 "_arrayExpSliceMinSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
756 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
757 "_arrayExpSliceMinass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
758 "_arrayExpSliceMinass_d", // T[]-=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
759 "_arrayExpSliceMinass_f", // T[]-=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
760 "_arrayExpSliceMinass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
761 "_arrayExpSliceMinass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
762 "_arrayExpSliceMinass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
763 "_arrayExpSliceMinass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
764 "_arrayExpSliceMinass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
765 "_arrayExpSliceMinass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
766 "_arrayExpSliceMinass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
767 "_arrayExpSliceMinass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
768 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
769 "_arrayExpSliceMulass_d", // T[]*=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
770 "_arrayExpSliceMulass_f", // T[]*=T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
771 "_arrayExpSliceMulass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
772 "_arrayExpSliceMulass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
773 "_arrayExpSliceMulass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
774 "_arrayExpSliceMulass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
775 "_arrayExpSliceMulass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
776 "_arrayExpSliceMulass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
777 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
778 "_arraySliceExpAddSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
779 "_arraySliceExpAddSliceAssign_d", // T[]=T[]+T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
780 "_arraySliceExpAddSliceAssign_f", // T[]=T[]+T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
781 "_arraySliceExpAddSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
782 "_arraySliceExpAddSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
783 "_arraySliceExpAddSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
784 "_arraySliceExpAddSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
785 "_arraySliceExpAddSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
786 "_arraySliceExpAddSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
787 "_arraySliceExpAddSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
788 "_arraySliceExpAddSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
789 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
790 "_arraySliceExpDivSliceAssign_d", // T[]=T[]/T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
791 "_arraySliceExpDivSliceAssign_f", // T[]=T[]/T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
792 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
793 "_arraySliceExpMinSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
794 "_arraySliceExpMinSliceAssign_d", // T[]=T[]-T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
795 "_arraySliceExpMinSliceAssign_f", // T[]=T[]-T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
796 "_arraySliceExpMinSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
797 "_arraySliceExpMinSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
798 "_arraySliceExpMinSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
799 "_arraySliceExpMinSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
800 "_arraySliceExpMinSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
801 "_arraySliceExpMinSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
802 "_arraySliceExpMinSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
803 "_arraySliceExpMinSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
804 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
805 "_arraySliceExpMulSliceAddass_d", // T[] += T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
806 "_arraySliceExpMulSliceAddass_f", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
807 "_arraySliceExpMulSliceAddass_r", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
808 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
809 "_arraySliceExpMulSliceAssign_d", // T[]=T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
810 "_arraySliceExpMulSliceAssign_f", // T[]=T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
811 "_arraySliceExpMulSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
812 "_arraySliceExpMulSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
813 "_arraySliceExpMulSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
814 "_arraySliceExpMulSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
815 "_arraySliceExpMulSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
816 "_arraySliceExpMulSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
817 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
818 "_arraySliceExpMulSliceMinass_d", // T[] -= T[]*T |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
819 "_arraySliceExpMulSliceMinass_f", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
820 "_arraySliceExpMulSliceMinass_r", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
821 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
822 "_arraySliceSliceAddSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
823 "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
824 "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
825 "_arraySliceSliceAddSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
826 "_arraySliceSliceAddSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
827 "_arraySliceSliceAddSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
828 "_arraySliceSliceAddSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
829 "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
830 "_arraySliceSliceAddSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
831 "_arraySliceSliceAddSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
832 "_arraySliceSliceAddSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
833 "_arraySliceSliceAddSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
834 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
835 "_arraySliceSliceAddass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
836 "_arraySliceSliceAddass_d", // T[]+=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
837 "_arraySliceSliceAddass_f", // T[]+=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
838 "_arraySliceSliceAddass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
839 "_arraySliceSliceAddass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
840 "_arraySliceSliceAddass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
841 "_arraySliceSliceAddass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
842 "_arraySliceSliceAddass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
843 "_arraySliceSliceAddass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
844 "_arraySliceSliceAddass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
845 "_arraySliceSliceAddass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
846 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
847 "_arraySliceSliceMinSliceAssign_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
848 "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
849 "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
850 "_arraySliceSliceMinSliceAssign_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
851 "_arraySliceSliceMinSliceAssign_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
852 "_arraySliceSliceMinSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
853 "_arraySliceSliceMinSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
854 "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
855 "_arraySliceSliceMinSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
856 "_arraySliceSliceMinSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
857 "_arraySliceSliceMinSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
858 "_arraySliceSliceMinSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
859 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
860 "_arraySliceSliceMinass_a", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
861 "_arraySliceSliceMinass_d", // T[]-=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
862 "_arraySliceSliceMinass_f", // T[]-=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
863 "_arraySliceSliceMinass_g", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
864 "_arraySliceSliceMinass_h", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
865 "_arraySliceSliceMinass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
866 "_arraySliceSliceMinass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
867 "_arraySliceSliceMinass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
868 "_arraySliceSliceMinass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
869 "_arraySliceSliceMinass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
870 "_arraySliceSliceMinass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
871 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
872 "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
873 "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
874 "_arraySliceSliceMulSliceAssign_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
875 "_arraySliceSliceMulSliceAssign_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
876 "_arraySliceSliceMulSliceAssign_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
877 "_arraySliceSliceMulSliceAssign_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
878 "_arraySliceSliceMulSliceAssign_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
879 "_arraySliceSliceMulSliceAssign_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
880 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
881 "_arraySliceSliceMulass_d", // T[]*=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
882 "_arraySliceSliceMulass_f", // T[]*=T[] |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
883 "_arraySliceSliceMulass_i", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
884 "_arraySliceSliceMulass_k", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
885 "_arraySliceSliceMulass_s", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
886 "_arraySliceSliceMulass_t", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
887 "_arraySliceSliceMulass_u", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
888 "_arraySliceSliceMulass_w", |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
889 ]; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
890 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
891 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
|
892 if (i == -1) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
893 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
894 debug { // Make sure our array is alphabetized |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
895 for (i = 0; i < libArrayopFuncs.length; i++) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
896 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
897 if (strcmp(name, libArrayopFuncs[i]) == 0) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
898 assert(false); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
899 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
900 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
901 /* Not in library, so generate it. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
902 * Construct the function body: |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
903 * 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
|
904 * loopbody; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
905 * return p; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
906 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
907 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
908 Arguments fparams = new Arguments(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
909 Expression loopbody = buildArrayLoop(fparams); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
910 Argument p = cast(Argument)fparams.data[0 /*fparams.dim - 1*/]; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
911 version (DMDV1) { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
912 // 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
|
913 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
|
914 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
|
915 Statement s1 = new ForStatement(0, |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
916 new DeclarationStatement(0, d), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
917 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
|
918 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
|
919 new ExpStatement(0, loopbody)); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
920 } else { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
921 // foreach (i; 0 .. p.length) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
922 Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach, |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
923 new Argument(STC.STCundefined, null, Id.p, null), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
924 new IntegerExp(Loc(0), 0, Type.tint32), |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
925 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
|
926 new ExpStatement(Loc(0), loopbody)); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
927 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
928 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
|
929 //printf("s2: %s\n", s2.toChars()); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
930 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
|
931 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
932 /* Construct the function |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
933 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
934 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
|
935 //printf("ftype: %s\n", ftype.toChars()); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
936 fd = new FuncDeclaration(Loc(0), Loc(0), Lexer.idPool(name[0..namelen]), STCundefined, ftype); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
937 fd.fbody = fbody; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
938 fd.protection = PROT.PROTpublic; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
939 fd.linkage = LINKc; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
940 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
941 sc.module_.importedFrom.members.push(cast(void*)fd); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
942 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
943 sc = sc.push(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
944 sc.parent = sc.module_.importedFrom; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
945 sc.stc = STCundefined; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
946 sc.linkage = LINKc; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
947 fd.semantic(sc); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
948 sc.pop(); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
949 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
950 else |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
951 { /* In library, refer to it. |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
952 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
953 fd = FuncDeclaration.genCfunc(type, name[0..namelen]); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
954 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
955 sv.ptrvalue = cast(void*)fd; // cache symbol in hash table |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
956 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
957 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
958 /* Call the function fd(arguments) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
959 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
960 Expression ec = new VarExp(Loc(0), fd); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
961 Expression e = new CallExp(loc, ec, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
962 e.type = type; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
963 return e; |
0 | 964 } |
965 | |
966 int inlineCost(InlineCostState* ics) | |
967 { | |
968 return 1 + e1.inlineCost(ics) + e2.inlineCost(ics); | |
969 } | |
970 | |
971 Expression doInline(InlineDoState ids) | |
972 { | |
973 BinExp be = cast(BinExp)copy(); | |
974 | |
975 be.e1 = e1.doInline(ids); | |
976 be.e2 = e2.doInline(ids); | |
977 return be; | |
978 } | |
979 | |
980 Expression inlineScan(InlineScanState* iss) | |
981 { | |
982 e1 = e1.inlineScan(iss); | |
983 e2 = e2.inlineScan(iss); | |
984 return this; | |
985 } | |
986 | |
987 Expression op_overload(Scope sc) | |
988 { | |
989 //printf("BinExp.op_overload() (%s)\n", toChars()); | |
990 | |
991 AggregateDeclaration ad; | |
992 Type t1 = e1.type.toBasetype(); | |
993 Type t2 = e2.type.toBasetype(); | |
994 Identifier id = opId(); | |
995 Identifier id_r = opId_r(); | |
996 | |
997 Match m; | |
998 scope Expressions args1 = new Expressions(); | |
999 scope Expressions args2 = new Expressions(); | |
1000 int argsset = 0; | |
1001 | |
1002 AggregateDeclaration ad1; | |
1003 if (t1.ty == TY.Tclass) | |
1004 ad1 = (cast(TypeClass)t1).sym; | |
1005 else if (t1.ty == TY.Tstruct) | |
1006 ad1 = (cast(TypeStruct)t1).sym; | |
1007 else | |
1008 ad1 = null; | |
1009 | |
1010 AggregateDeclaration ad2; | |
1011 if (t2.ty == TY.Tclass) | |
1012 ad2 = (cast(TypeClass)t2).sym; | |
1013 else if (t2.ty == TY.Tstruct) | |
1014 ad2 = (cast(TypeStruct)t2).sym; | |
1015 else | |
1016 ad2 = null; | |
1017 | |
1018 Dsymbol s = null; | |
1019 Dsymbol s_r = null; | |
1020 FuncDeclaration fd = null; | |
1021 TemplateDeclaration td = null; | |
1022 if (ad1 && id) | |
1023 { | |
1024 s = search_function(ad1, id); | |
1025 } | |
1026 if (ad2 && id_r) | |
1027 { | |
1028 s_r = search_function(ad2, id_r); | |
1029 } | |
1030 | |
1031 if (s || s_r) | |
1032 { | |
1033 /* Try: | |
1034 * a.opfunc(b) | |
1035 * b.opfunc_r(a) | |
1036 * and see which is better. | |
1037 */ | |
1038 Expression e; | |
1039 FuncDeclaration lastf; | |
1040 | |
1041 args1.setDim(1); | |
1042 args1.data[0] = cast(void*) e1; | |
1043 args2.setDim(1); | |
1044 args2.data[0] = cast(void*) e2; | |
1045 argsset = 1; | |
1046 | |
1047 ///memset(&m, 0, sizeof(m)); | |
1048 m.last = MATCH.MATCHnomatch; | |
1049 | |
1050 if (s) | |
1051 { | |
1052 fd = s.isFuncDeclaration(); | |
1053 if (fd) | |
1054 { | |
1055 overloadResolveX(&m, fd, null, args2); | |
1056 } | |
1057 else | |
1058 { | |
1059 td = s.isTemplateDeclaration(); | |
1060 templateResolve(&m, td, sc, loc, null, null, args2); | |
1061 } | |
1062 } | |
1063 | |
1064 lastf = m.lastf; | |
1065 | |
1066 if (s_r) | |
1067 { | |
1068 fd = s_r.isFuncDeclaration(); | |
1069 if (fd) | |
1070 { | |
1071 overloadResolveX(&m, fd, null, args1); | |
1072 } | |
1073 else | |
1074 { | |
1075 td = s_r.isTemplateDeclaration(); | |
1076 templateResolve(&m, td, sc, loc, null, null, args1); | |
1077 } | |
1078 } | |
1079 | |
1080 if (m.count > 1) | |
1081 { | |
1082 // Error, ambiguous | |
1083 error("overloads %s and %s both match argument list for %s", | |
1084 m.lastf.type.toChars(), | |
1085 m.nextf.type.toChars(), | |
1086 m.lastf.toChars()); | |
1087 } | |
1088 else if (m.last == MATCH.MATCHnomatch) | |
1089 { | |
1090 m.lastf = m.anyf; | |
1091 } | |
1092 | |
1093 if (op == TOK.TOKplusplus || op == TOK.TOKminusminus) | |
1094 // Kludge because operator overloading regards e++ and e-- | |
1095 // as unary, but it's implemented as a binary. | |
1096 // Rewrite (e1 ++ e2) as e1.postinc() | |
1097 // Rewrite (e1 -- e2) as e1.postdec() | |
1098 e = build_overload(loc, sc, e1, null, id); | |
1099 else if (lastf && m.lastf == lastf || m.last == MATCH.MATCHnomatch) | |
1100 // Rewrite (e1 op e2) as e1.opfunc(e2) | |
1101 e = build_overload(loc, sc, e1, e2, id); | |
1102 else | |
1103 // Rewrite (e1 op e2) as e2.opfunc_r(e1) | |
1104 e = build_overload(loc, sc, e2, e1, id_r); | |
1105 return e; | |
1106 } | |
1107 | |
1108 if (isCommutative()) | |
1109 { | |
1110 s = null; | |
1111 s_r = null; | |
1112 if (ad1 && id_r) | |
1113 { | |
1114 s_r = search_function(ad1, id_r); | |
1115 } | |
1116 if (ad2 && id) | |
1117 { | |
1118 s = search_function(ad2, id); | |
1119 } | |
1120 | |
1121 if (s || s_r) | |
1122 { | |
1123 /* Try: | |
1124 * a.opfunc_r(b) | |
1125 * b.opfunc(a) | |
1126 * and see which is better. | |
1127 */ | |
1128 | |
1129 if (!argsset) | |
1130 { | |
1131 args1.setDim(1); | |
1132 args1.data[0] = cast(void*) e1; | |
1133 args2.setDim(1); | |
1134 args2.data[0] = cast(void*) e2; | |
1135 } | |
1136 | |
1137 ///memset(&m, 0, sizeof(m)); | |
1138 m.last = MATCH.MATCHnomatch; | |
1139 | |
1140 if (s_r) | |
1141 { | |
1142 fd = s_r.isFuncDeclaration(); | |
1143 if (fd) | |
1144 { | |
1145 overloadResolveX(&m, fd, null, args2); | |
1146 } | |
1147 else | |
1148 { td = s_r.isTemplateDeclaration(); | |
1149 templateResolve(&m, td, sc, loc, null, null, args2); | |
1150 } | |
1151 } | |
1152 FuncDeclaration lastf = m.lastf; | |
1153 | |
1154 if (s) | |
1155 { | |
1156 fd = s.isFuncDeclaration(); | |
1157 if (fd) | |
1158 { | |
1159 overloadResolveX(&m, fd, null, args1); | |
1160 } | |
1161 else | |
1162 { td = s.isTemplateDeclaration(); | |
1163 templateResolve(&m, td, sc, loc, null, null, args1); | |
1164 } | |
1165 } | |
1166 | |
1167 if (m.count > 1) | |
1168 { | |
1169 // Error, ambiguous | |
1170 error("overloads %s and %s both match argument list for %s", | |
1171 m.lastf.type.toChars(), | |
1172 m.nextf.type.toChars(), | |
1173 m.lastf.toChars()); | |
1174 } | |
1175 else if (m.last == MATCH.MATCHnomatch) | |
1176 { | |
1177 m.lastf = m.anyf; | |
1178 } | |
1179 | |
1180 Expression e; | |
1181 if (lastf && m.lastf == lastf || id_r && m.last == MATCH.MATCHnomatch) | |
1182 // Rewrite (e1 op e2) as e1.opfunc_r(e2) | |
1183 e = build_overload(loc, sc, e1, e2, id_r); | |
1184 else | |
1185 // Rewrite (e1 op e2) as e2.opfunc(e1) | |
1186 e = build_overload(loc, sc, e2, e1, id); | |
1187 | |
1188 // When reversing operands of comparison operators, | |
1189 // need to reverse the sense of the op | |
1190 switch (op) | |
1191 { | |
1192 case TOK.TOKlt: op = TOK.TOKgt; break; | |
1193 case TOK.TOKgt: op = TOK.TOKlt; break; | |
1194 case TOK.TOKle: op = TOK.TOKge; break; | |
1195 case TOK.TOKge: op = TOK.TOKle; break; | |
1196 | |
1197 // Floating point compares | |
1198 case TOK.TOKule: op = TOK.TOKuge; break; | |
1199 case TOK.TOKul: op = TOK.TOKug; break; | |
1200 case TOK.TOKuge: op = TOK.TOKule; break; | |
1201 case TOK.TOKug: op = TOK.TOKul; break; | |
1202 | |
1203 // These are symmetric | |
1204 case TOK.TOKunord: | |
1205 case TOK.TOKlg: | |
1206 case TOK.TOKleg: | |
1207 case TOK.TOKue: | |
1208 break; | |
1209 } | |
1210 | |
1211 return e; | |
1212 } | |
1213 } | |
1214 | |
1215 version (DMDV2) { | |
1216 // Try alias this on first operand | |
1217 if (ad1 && ad1.aliasthis) | |
1218 { | |
1219 /* Rewrite (e1 op e2) as: | |
1220 * (e1.aliasthis op e2) | |
1221 */ | |
1222 Expression e1 = new DotIdExp(loc, this.e1, ad1.aliasthis.ident); | |
1223 Expression e = copy(); | |
1224 (cast(BinExp)e).e1 = e1; | |
1225 e = e.semantic(sc); | |
1226 return e; | |
1227 } | |
1228 | |
1229 // Try alias this on second operand | |
1230 if (ad2 && ad2.aliasthis) | |
1231 { | |
1232 /* Rewrite (e1 op e2) as: | |
1233 * (e1 op e2.aliasthis) | |
1234 */ | |
1235 Expression e2 = new DotIdExp(loc, this.e2, ad2.aliasthis.ident); | |
1236 Expression e = copy(); | |
1237 (cast(BinExp)e).e2 = e2; | |
1238 e = e.semantic(sc); | |
1239 return e; | |
1240 } | |
1241 } | |
1242 return null; | |
1243 } | |
1244 | |
1245 elem* toElemBin(IRState* irs, int op) | |
1246 { | |
1247 //printf("toElemBin() '%s'\n", toChars()); | |
1248 | |
1249 tym_t tym = type.totym(); | |
1250 | |
1251 elem* el = e1.toElem(irs); | |
1252 elem* er = e2.toElem(irs); | |
1253 elem* e = el_bin(op,tym,el,er); | |
1254 el_setLoc(e,loc); | |
1255 | |
1256 return e; | |
1257 } | |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1258 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1259 final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1260 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1261 /* Evaluate assign expressions left to right |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1262 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1263 e1.buildArrayIdent(buf, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1264 e2.buildArrayIdent(buf, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1265 buf.writestring(Str); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1266 } |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1267 |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1268 final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1269 { |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1270 /* Evaluate assign expressions right to left |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1271 */ |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1272 e2.buildArrayIdent(buf, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1273 e1.buildArrayIdent(buf, arguments); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1274 buf.writestring(Str); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1275 buf.writestring("ass"); |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
1276 } |
0 | 1277 } |