Mercurial > projects > ddmd
view dmd/PowExp.d @ 131:206db751bd4c
dmdfe 2.037 compiles now
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Fri, 10 Sep 2010 00:27:37 +0100 |
parents | 60bb0fe4563e |
children | af1bebfd96a4 |
line wrap: on
line source
module dmd.PowExp; import dmd.BinExp; import dmd.Scope; import dmd.Loc; import dmd.Identifier; import dmd.Expression; import dmd.TOK; import dmd.Module; import dmd.Id; import dmd.IdentifierExp; import dmd.DotIdExp; import dmd.CallExp; import dmd.ErrorExp; 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; } } }