Mercurial > projects > ddmd
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 |