comparison dmd/PowExp.d @ 179:cd48cb899aee

Updated to dmd2.040
author korDen
date Sun, 17 Oct 2010 20:56:07 +0400
parents e3afd1303184
children b0d41ff5e0df
comparison
equal deleted inserted replaced
178:e3afd1303184 179:cd48cb899aee
16 import dmd.AndExp; 16 import dmd.AndExp;
17 import dmd.CondExp; 17 import dmd.CondExp;
18 import dmd.Global; 18 import dmd.Global;
19 import dmd.IntegerExp; 19 import dmd.IntegerExp;
20 import dmd.Type; 20 import dmd.Type;
21 import dmd.STC;
21 import dmd.Lexer; 22 import dmd.Lexer;
22 import dmd.VarDeclaration; 23 import dmd.VarDeclaration;
23 import dmd.ExpInitializer; 24 import dmd.ExpInitializer;
24 import dmd.VarExp; 25 import dmd.VarExp;
25 import dmd.DeclarationExp; 26 import dmd.DeclarationExp;
84 { 85 {
85 error("cannot raise %s to a negative integer power. Did you mean (cast(real)%s)^^%s ?", 86 error("cannot raise %s to a negative integer power. Did you mean (cast(real)%s)^^%s ?",
86 e1.type.toBasetype().toChars(), e1.toChars(), e2.toChars()); 87 e1.type.toBasetype().toChars(), e1.toChars(), e2.toChars());
87 return new ErrorExp(); 88 return new ErrorExp();
88 } 89 }
90
91 // Determine if we're raising to an integer power.
92 long intpow = 0;
93 if (e2.op == TOKint64 && (cast(long)e2.toInteger() == 2 || cast(long)e2.toInteger() == 3))
94 intpow = e2.toInteger();
95 else if (e2.op == TOKfloat64 && (e2.toReal() == cast(long)(e2.toReal())))
96 intpow = cast(long)(e2.toReal());
89 97
90 // Deal with x^^2, x^^3 immediately, since they are of practical importance. 98 // Deal with x^^2, x^^3 immediately, since they are of practical importance.
91 // Don't bother if x is a literal, since it will be constant-folded anyway. 99 if (intpow == 2 || intpow == 3)
92 if ( ( (e2.op == TOK.TOKint64 && (e2.toInteger() == 2 || e2.toInteger() == 3))
93 || (e2.op == TOK.TOKfloat64 && (e2.toReal() == 2.0 || e2.toReal() == 3.0))
94 ) && (e1.op == TOK.TOKint64 || e1.op == TOK.TOKfloat64)
95 )
96 { 100 {
97 typeCombine(sc); 101 typeCombine(sc);
98 // Replace x^^2 with (tmp = x, tmp*tmp) 102 // Replace x^^2 with (tmp = x, tmp*tmp)
99 // Replace x^^3 with (tmp = x, tmp*tmp*tmp) 103 // Replace x^^3 with (tmp = x, tmp*tmp*tmp)
100 Identifier idtmp = Lexer.uniqueId("__tmp"); 104 Identifier idtmp = Lexer.uniqueId("__tmp");
101 VarDeclaration tmp = new VarDeclaration(loc, e1.type.toBasetype(), idtmp, new ExpInitializer(Loc(0), e1)); 105 VarDeclaration tmp = new VarDeclaration(loc, e1.type.toBasetype(), idtmp, new ExpInitializer(Loc(0), e1));
102 VarExp ve = new VarExp(loc, tmp); 106 tmp.storage_class = STC.STCctfe;
107 Expression ve = new VarExp(loc, tmp);
103 Expression ae = new DeclarationExp(loc, tmp); 108 Expression ae = new DeclarationExp(loc, tmp);
109 /* Note that we're reusing ve. This should be ok.
110 */
104 Expression me = new MulExp(loc, ve, ve); 111 Expression me = new MulExp(loc, ve, ve);
105 if ( (e2.op == TOK.TOKint64 && e2.toInteger() == 3) 112 if (intpow == 3)
106 || (e2.op == TOK.TOKfloat64 && e2.toReal() == 3.0)) 113 me = new MulExp(loc, me, ve);
107 me = new MulExp(loc, me, ve);
108 e = new CommaExp(loc, ae, me); 114 e = new CommaExp(loc, ae, me);
109 e = e.semantic(sc); 115 e = e.semantic(sc);
110 return e; 116 return e;
111 } 117 }
112 118
141 // Replace e1 ^^ e2 with .std.math.pow(e1, e2) 147 // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
142 // We don't combine the types if raising to an integer power (because 148 // We don't combine the types if raising to an integer power (because
143 // integer powers are treated specially by std.math.pow). 149 // integer powers are treated specially by std.math.pow).
144 if (!e2.type.isintegral()) 150 if (!e2.type.isintegral())
145 typeCombine(sc); 151 typeCombine(sc);
152 // In fact, if it *could* have been an integer, make it one.
153 if (e2.op == TOKfloat64 && intpow != 0)
154 e2 = new IntegerExp(loc, intpow, Type.tint64);
155
146 e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2); 156 e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2);
147 } 157 }
148 e = e.semantic(sc); 158 e = e.semantic(sc);
149 // Always constant fold integer powers of literals. This will run the interpreter 159 // Always constant fold integer powers of literals. This will run the interpreter
150 // on .std.math.pow 160 // on .std.math.pow