annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
1 module dmd.PowExp;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
2
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
3 import dmd.BinExp;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
4 import dmd.Scope;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
5 import dmd.Loc;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
6 import dmd.Identifier;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
7 import dmd.Expression;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
8
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
9 version(DMDV2) {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
10
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
11 class PowExp : BinExp
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
12 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
13 this(Loc loc, Expression e1, Expression e2)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
14 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
15 super(loc, TOK.TOKpow, PowExp.sizeof, e1, e2);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
16 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
17
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
18 Expression semantic(Scope sc)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
19 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
20 Expression e;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
21
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
22 if (type)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
23 return this;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
24
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
25 BinExp.semanticp(sc);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
26 e = op_overload(sc);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
27 if (e)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
28 return e;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
29
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
30 static int importMathChecked = 0;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
31 if (!importMathChecked)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
32 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
33 importMathChecked = 1;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
34 for (int i = 0; i < Module.amodules.dim; i++)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
35 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
36 auto mi = cast(Module)Module.amodules.data[i];
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
37 //printf("\t[%d] %s\n", i, mi->toChars());
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
38 if (mi.ident == Id.math &&
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
39 mi.parent.ident == Id.std &&
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
40 !mi.parent.parent)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
41 goto L1;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
42 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
43 error("must import std.math to use ^^ operator");
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
44
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
45 L1: ;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
46 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
47
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
48 assert(e1.type && e2.type);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
49 if ( (e1.type.isintegral() || e1.type.isfloating()) &&
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
50 (e2.type.isintegral() || e2.type.isfloating()))
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
51 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
52 // For built-in numeric types, there are three cases:
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
53 // x ^^ 1 ----> x
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
54 // x ^^ 0.5 ----> sqrt(x)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
55 // x ^^ y ----> pow(x, y)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
56 // TODO: backend support, especially for e1 ^^ 2.
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
57 bool wantSqrt = false;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
58 e2 = e2.optimize(0);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
59 if ((e2.op == TOK.TOKfloat64 && e2.toReal() == 1.0) ||
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
60 (e2.op == TOK.TOKint64 && e2.toInteger() == 1))
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
61 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
62 return e1; // Replace x ^^ 1 with x.
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
63 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
64
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
65 e = new IdentifierExp(loc, Id.empty);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
66 e = new DotIdExp(loc, e, Id.std);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
67 e = new DotIdExp(loc, e, Id.math);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
68 if (e2.op == TOKfloat64 && e2.toReal() == 0.5)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
69 { // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
70 e = new CallExp(loc, new DotIdExp(loc, e, Id._sqrt), e1);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
71 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
72 else
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
73 { // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
74 e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
75 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
76 e = e.semantic(sc);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
77 return e;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
78 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
79 error("%s ^^ %s is not supported", e1.type.toChars(), e2.type.toChars() );
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
80 return new ErrorExp();
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
81 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
82
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
83
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
84 // For operator overloading
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
85 Identifier opId()
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
86 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
87 return Id.pow;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
88 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
89
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
90 Identifier opId_r()
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
91 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
92 return Id.pow_r;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
93 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
94 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
95
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
diff changeset
96 }