Mercurial > projects > ddmd
comparison dmd/BinExp.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | 1765f3ef917d |
children | af1bebfd96a4 |
comparison
equal
deleted
inserted
replaced
129:010eb8f0e18d | 130:60bb0fe4563e |
---|---|
52 import dmd.MulExp; | 52 import dmd.MulExp; |
53 import dmd.Token; | 53 import dmd.Token; |
54 import dmd.PREC; | 54 import dmd.PREC; |
55 import dmd.StringValue; | 55 import dmd.StringValue; |
56 import dmd.StringTable; | 56 import dmd.StringTable; |
57 import dmd.Argument; | 57 import dmd.Parameter; |
58 import dmd.Statement; | 58 import dmd.Statement; |
59 import dmd.ForeachRangeStatement; | 59 import dmd.ForeachRangeStatement; |
60 import dmd.ArrayLengthExp; | 60 import dmd.ArrayLengthExp; |
61 import dmd.IdentifierExp; | 61 import dmd.IdentifierExp; |
62 import dmd.ExpStatement; | 62 import dmd.ExpStatement; |
123 Type t2b = t2.toBasetype(); | 123 Type t2b = t2.toBasetype(); |
124 | 124 |
125 TY ty = cast(TY)Type.impcnvResult[t1b.ty][t2b.ty]; | 125 TY ty = cast(TY)Type.impcnvResult[t1b.ty][t2b.ty]; |
126 if (ty != TY.Terror) | 126 if (ty != TY.Terror) |
127 { | 127 { |
128 TY ty1; | 128 auto ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty]; |
129 TY ty2; | 129 auto ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty]; |
130 | |
131 ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty]; | |
132 ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty]; | |
133 | 130 |
134 if (t1b.ty == ty1) // if no promotions | 131 if (t1b.ty == ty1) // if no promotions |
135 { | 132 { |
136 if (t1 == t2) | 133 if (t1 == t2) |
137 { | 134 { |
204 } else { | 201 } else { |
205 goto Lincompatible; | 202 goto Lincompatible; |
206 } | 203 } |
207 } | 204 } |
208 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && | 205 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && |
209 e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid) | 206 (e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid || |
210 { /* (T[n] op void*) | 207 e2.op == TOK.TOKarrayliteral && t2.ty == TY.Tsarray && t2.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t2).dim.toInteger() == 0) |
211 * (T[] op void*) | 208 ) |
212 */ | 209 { /* (T[n] op void*) => T[] |
210 * (T[] op void*) => T[] | |
211 * (T[n] op void[0]) => T[] | |
212 * (T[] op void[0]) => T[] | |
213 */ | |
213 goto Lx1; | 214 goto Lx1; |
214 } | 215 } |
215 else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) && | 216 else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) && |
216 e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid) | 217 (e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid || |
217 { /* (void* op T[n]) | 218 e1.op == TOK.TOKarrayliteral && t1.ty == TY.Tsarray && t1.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t1).dim.toInteger() == 0) |
218 * (void* op T[]) | 219 ) |
220 { /* (void* op T[n]) => T[] | |
221 * (void* op T[]) => T[] | |
222 * (void[0] op T[n]) => T[] | |
223 * (void[0] op T[]) => T[] | |
219 */ | 224 */ |
220 goto Lx2; | 225 goto Lx2; |
221 } | 226 } |
222 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && t1.implicitConvTo(t2)) | 227 else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) && t1.implicitConvTo(t2)) |
223 { | 228 { |
311 } | 316 } |
312 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && | 317 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && |
313 e2.implicitConvTo(t1.nextOf().arrayOf())) | 318 e2.implicitConvTo(t1.nextOf().arrayOf())) |
314 { | 319 { |
315 Lx1: | 320 Lx1: |
316 t = t1.nextOf().arrayOf(); | 321 t = t1.nextOf().arrayOf(); // T[] |
317 e1 = e1.castTo(sc, t); | 322 e1 = e1.castTo(sc, t); |
318 e2 = e2.castTo(sc, t); | 323 e2 = e2.castTo(sc, t); |
319 } | 324 } |
320 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && | 325 else if (t1.ty == TY.Tsarray && t2.ty == TY.Tsarray && |
321 e1.implicitConvTo(t2.nextOf().arrayOf())) | 326 e1.implicitConvTo(t2.nextOf().arrayOf())) |
448 | 453 |
449 e = op_overload(sc); | 454 e = op_overload(sc); |
450 if (e) | 455 if (e) |
451 return e; | 456 return e; |
452 | 457 |
458 if (e1.op == TOK.TOKarraylength) | |
459 { | |
460 e = ArrayLengthExp.rewriteOpAssign(this); | |
461 e = e.semantic(sc); | |
462 return e; | |
463 } | |
464 | |
453 if (e1.op == TOKslice) | 465 if (e1.op == TOKslice) |
454 { | 466 { |
455 // T[] op= ... | 467 // T[] op= ... |
456 typeCombine(sc); | 468 typeCombine(sc); |
457 type = e1.type; | 469 type = e1.type; |
488 | 500 |
489 e = op_overload(sc); | 501 e = op_overload(sc); |
490 if (e) | 502 if (e) |
491 return e; | 503 return e; |
492 | 504 |
505 if (e1.op == TOKarraylength) | |
506 { | |
507 e = ArrayLengthExp.rewriteOpAssign(this); | |
508 e = e.semantic(sc); | |
509 return e; | |
510 } | |
511 | |
493 if (e1.op == TOK.TOKslice) | 512 if (e1.op == TOK.TOKslice) |
494 { // T[] op= ... | 513 { // T[] op= ... |
495 typeCombine(sc); | 514 typeCombine(sc); |
496 type = e1.type; | 515 type = e1.type; |
497 return arrayOp(sc); | 516 return arrayOp(sc); |
1440 { | 1459 { |
1441 error("Cannot perform array operations on void[] arrays"); | 1460 error("Cannot perform array operations on void[] arrays"); |
1442 return new ErrorExp(); | 1461 return new ErrorExp(); |
1443 } | 1462 } |
1444 | 1463 |
1445 Expressions arguments = new Expressions(); | 1464 auto arguments = new Expressions(); |
1446 | 1465 |
1447 /* The expression to generate an array operation for is mangled | 1466 /* The expression to generate an array operation for is mangled |
1448 * into a name to use as the array operation function name. | 1467 * into a name to use as the array operation function name. |
1449 * Mangle in the operands and operators in RPN order, and type. | 1468 * Mangle in the operands and operators in RPN order, and type. |
1450 */ | 1469 */ |
1655 * foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++) | 1674 * foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++) |
1656 * loopbody; | 1675 * loopbody; |
1657 * return p; | 1676 * return p; |
1658 */ | 1677 */ |
1659 | 1678 |
1660 Arguments fparams = new Arguments(); | 1679 auto fparams = new Parameters(); |
1661 Expression loopbody = buildArrayLoop(fparams); | 1680 Expression loopbody = buildArrayLoop(fparams); |
1662 auto p = fparams[0 /*fparams.dim - 1*/]; | 1681 auto p = fparams[0 /*fparams.dim - 1*/]; |
1663 version (DMDV1) { | 1682 version (DMDV1) { |
1664 // for (size_t i = 0; i < p.length; i++) | 1683 // for (size_t i = 0; i < p.length; i++) |
1665 Initializer init = new ExpInitializer(0, new IntegerExp(0, 0, Type.tsize_t)); | 1684 Initializer init = new ExpInitializer(0, new IntegerExp(0, 0, Type.tsize_t)); |
1670 new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id.p)), | 1689 new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id.p)), |
1671 new ExpStatement(0, loopbody)); | 1690 new ExpStatement(0, loopbody)); |
1672 } else { | 1691 } else { |
1673 // foreach (i; 0 .. p.length) | 1692 // foreach (i; 0 .. p.length) |
1674 Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach, | 1693 Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach, |
1675 new Argument(STC.STCundefined, null, Id.p, null), | 1694 new Parameter(STC.STCundefined, null, Id.p, null), |
1676 new IntegerExp(Loc(0), 0, Type.tint32), | 1695 new IntegerExp(Loc(0), 0, Type.tint32), |
1677 new ArrayLengthExp(Loc(0), new IdentifierExp(Loc(0), p.ident)), | 1696 new ArrayLengthExp(Loc(0), new IdentifierExp(Loc(0), p.ident)), |
1678 new ExpStatement(Loc(0), loopbody)); | 1697 new ExpStatement(Loc(0), loopbody)); |
1679 } | 1698 } |
1680 Statement s2 = new ReturnStatement(Loc(0), new IdentifierExp(Loc(0), p.ident)); | 1699 Statement s2 = new ReturnStatement(Loc(0), new IdentifierExp(Loc(0), p.ident)); |
2028 e1.buildArrayIdent(buf, arguments); | 2047 e1.buildArrayIdent(buf, arguments); |
2029 e2.buildArrayIdent(buf, arguments); | 2048 e2.buildArrayIdent(buf, arguments); |
2030 buf.writestring(Str); | 2049 buf.writestring(Str); |
2031 } | 2050 } |
2032 | 2051 |
2033 final Expression AssignExp_buildArrayLoop(AssignExpType)(Arguments fparams)// if (is (AssignExpType : AssignExp)) | 2052 final Expression AssignExp_buildArrayLoop(AssignExpType)(Parameters fparams)// if (is (AssignExpType : AssignExp)) |
2034 { | 2053 { |
2035 /* Evaluate assign expressions right to left | 2054 /* Evaluate assign expressions right to left |
2036 */ | 2055 */ |
2037 Expression ex2 = e2.buildArrayLoop(fparams); | 2056 Expression ex2 = e2.buildArrayLoop(fparams); |
2038 Expression ex1 = e1.buildArrayLoop(fparams); | 2057 Expression ex1 = e1.buildArrayLoop(fparams); |
2040 param.storageClass = STCundefined; | 2059 param.storageClass = STCundefined; |
2041 Expression e = new AssignExpType(Loc(0), ex1, ex2); | 2060 Expression e = new AssignExpType(Loc(0), ex1, ex2); |
2042 return e; | 2061 return e; |
2043 } | 2062 } |
2044 | 2063 |
2045 final Expression Exp_buildArrayLoop(ExpType)(Arguments fparams) if (is (ExpType : BinExp)) | 2064 final Expression Exp_buildArrayLoop(ExpType)(Parameters fparams) if (is (ExpType : BinExp)) |
2046 { | 2065 { |
2047 /* Evaluate assign expressions left to right | 2066 /* Evaluate assign expressions left to right |
2048 */ | 2067 */ |
2049 Expression ex1 = e1.buildArrayLoop(fparams); | 2068 Expression ex1 = e1.buildArrayLoop(fparams); |
2050 Expression ex2 = e2.buildArrayLoop(fparams); | 2069 Expression ex2 = e2.buildArrayLoop(fparams); |