Mercurial > projects > ddmd
diff dmd/PowExp.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 | |
children | 206db751bd4c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/PowExp.d Thu Sep 09 22:51:44 2010 +0100 @@ -0,0 +1,96 @@ +module dmd.PowExp; + +import dmd.BinExp; +import dmd.Scope; +import dmd.Loc; +import dmd.Identifier; +import dmd.Expression; + +version(DMDV2) { + +class PowExp : BinExp +{ + this(Loc loc, Expression e1, Expression e2) + { + super(loc, TOK.TOKpow, PowExp.sizeof, e1, e2); + } + + Expression semantic(Scope sc) + { + Expression e; + + if (type) + return this; + + BinExp.semanticp(sc); + e = op_overload(sc); + if (e) + return e; + + static int importMathChecked = 0; + if (!importMathChecked) + { + importMathChecked = 1; + for (int i = 0; i < Module.amodules.dim; i++) + { + auto mi = cast(Module)Module.amodules.data[i]; + //printf("\t[%d] %s\n", i, mi->toChars()); + if (mi.ident == Id.math && + mi.parent.ident == Id.std && + !mi.parent.parent) + goto L1; + } + error("must import std.math to use ^^ operator"); + + L1: ; + } + + assert(e1.type && e2.type); + if ( (e1.type.isintegral() || e1.type.isfloating()) && + (e2.type.isintegral() || e2.type.isfloating())) + { + // For built-in numeric types, there are three cases: + // x ^^ 1 ----> x + // x ^^ 0.5 ----> sqrt(x) + // x ^^ y ----> pow(x, y) + // TODO: backend support, especially for e1 ^^ 2. + bool wantSqrt = false; + e2 = e2.optimize(0); + if ((e2.op == TOK.TOKfloat64 && e2.toReal() == 1.0) || + (e2.op == TOK.TOKint64 && e2.toInteger() == 1)) + { + return e1; // Replace x ^^ 1 with x. + } + + e = new IdentifierExp(loc, Id.empty); + e = new DotIdExp(loc, e, Id.std); + e = new DotIdExp(loc, e, Id.math); + if (e2.op == TOKfloat64 && e2.toReal() == 0.5) + { // Replace e1 ^^ 0.5 with .std.math.sqrt(x) + e = new CallExp(loc, new DotIdExp(loc, e, Id._sqrt), e1); + } + else + { // Replace e1 ^^ e2 with .std.math.pow(e1, e2) + e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2); + } + e = e.semantic(sc); + return e; + } + error("%s ^^ %s is not supported", e1.type.toChars(), e2.type.toChars() ); + return new ErrorExp(); + } + + + // For operator overloading + Identifier opId() + { + return Id.pow; + } + + Identifier opId_r() + { + return Id.pow_r; + } +} + +} \ No newline at end of file