Mercurial > projects > ddmd
annotate dmd/RealExp.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
72 | 1 module dmd.RealExp; |
2 | |
114 | 3 import dmd.common; |
129 | 4 import dmd.Complex; |
72 | 5 import dmd.Expression; |
6 import dmd.backend.elem; | |
7 import dmd.InterState; | |
8 import dmd.Type; | |
9 import dmd.OutBuffer; | |
10 import dmd.Loc; | |
11 import dmd.TOK; | |
12 import dmd.Scope; | |
0 | 13 import dmd.IRState; |
72 | 14 import dmd.Type; |
0 | 15 import dmd.HdrGenState; |
16 import dmd.Port; | |
17 import dmd.TY; | |
72 | 18 |
129 | 19 import dmd.expression.Util; |
20 | |
0 | 21 import dmd.backend.dt_t; |
22 import dmd.backend.Util; | |
23 import dmd.backend.TYM; | |
24 import dmd.backend.mTY; | |
25 | |
73 | 26 import std.stdio; |
148 | 27 import std.string; |
73 | 28 |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
29 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 |
0 | 31 class RealExp : Expression |
32 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
33 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
34 |
0 | 35 real value; |
36 | |
37 this(Loc loc, real value, Type type) | |
38 { | |
178 | 39 register(); |
0 | 40 super(loc, TOK.TOKfloat64, RealExp.sizeof); |
41 //printf("RealExp.RealExp(%Lg)\n", value); | |
42 this.value = value; | |
43 this.type = type; | |
44 } | |
45 | |
72 | 46 override bool equals(Object o) |
0 | 47 { |
129 | 48 if (this is o) |
49 return true; | |
50 | |
51 Expression e = cast(Expression)o; | |
52 if (e.op == TOKfloat64) { | |
53 RealExp ne = cast(RealExp)e; | |
54 if (type.toHeadMutable().equals(ne.type.toHeadMutable())) { | |
55 if (RealEquals(value, ne.value)) { | |
56 return true; | |
57 } | |
58 } | |
59 } | |
60 | |
148 | 61 return false; |
0 | 62 } |
63 | |
72 | 64 override Expression semantic(Scope sc) |
0 | 65 { |
66 if (!type) | |
67 type = Type.tfloat64; | |
68 else | |
69 type = type.semantic(loc, sc); | |
70 return this; | |
71 } | |
72 | |
72 | 73 override Expression interpret(InterState istate) |
0 | 74 { |
148 | 75 version(LOG) |
76 writef("RealExp::interpret() %s\n", toChars()); | |
77 | |
78 return this; | |
0 | 79 } |
80 | |
72 | 81 override string toChars() |
0 | 82 { |
148 | 83 return format(type.isimaginary() ? "%gi" : "%g", value); |
0 | 84 } |
85 | |
72 | 86 override ulong toInteger() |
0 | 87 { |
148 | 88 version(IN_GCC) |
89 return toReal().toInt(); | |
90 else | |
91 return cast(ulong) toReal(); | |
0 | 92 } |
93 | |
72 | 94 override ulong toUInteger() |
0 | 95 { |
148 | 96 version(IN_GCC) |
97 return cast(ulong) toReal().toInt(); | |
98 else | |
99 return cast(ulong) toReal(); | |
0 | 100 } |
101 | |
72 | 102 override real toReal() |
0 | 103 { |
104 return type.isreal() ? value : 0; | |
105 } | |
106 | |
72 | 107 override real toImaginary() |
0 | 108 { |
109 return type.isreal() ? 0 : value; | |
110 } | |
111 | |
72 | 112 override Complex!(real) toComplex() |
0 | 113 { |
114 return Complex!(real)(toReal(), toImaginary()); | |
115 } | |
116 | |
72 | 117 override Expression castTo(Scope sc, Type t) |
0 | 118 { |
119 Expression e = this; | |
120 if (type != t) | |
121 { | |
122 if ((type.isreal() && t.isreal()) || | |
123 (type.isimaginary() && t.isimaginary()) | |
124 ) | |
125 { | |
126 e = copy(); | |
127 e.type = t; | |
128 } | |
129 else | |
130 e = Expression.castTo(sc, t); | |
131 } | |
132 return e; | |
133 } | |
134 | |
72 | 135 override int isConst() |
0 | 136 { |
137 return 1; | |
138 } | |
139 | |
72 | 140 override bool isBool(bool result) |
0 | 141 { |
123 | 142 return result ? (value != 0) : (value == 0); |
0 | 143 } |
144 | |
72 | 145 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 146 { |
148 | 147 floatToBuffer(buf, type, value); |
0 | 148 } |
149 | |
72 | 150 override void toMangleBuffer(OutBuffer buf) |
0 | 151 { |
129 | 152 buf.writeByte('e'); |
153 realToMangleBuffer(buf, value); | |
0 | 154 } |
155 | |
72 | 156 override elem* toElem(IRState* irs) |
0 | 157 { |
158 eve c; | |
159 tym_t ty; | |
160 | |
161 //printf("RealExp.toElem(%p) %s\n", this, toChars()); | |
162 ///memset(&c, 0, sizeof(c)); | |
163 ty = type.toBasetype().totym(); | |
164 switch (tybasic(ty)) | |
165 { | |
166 case TYfloat: | |
167 case TYifloat: | |
168 c.Vfloat = value; | |
169 if (Port.isSignallingNan(value)) { | |
170 std.stdio.writeln("signalling float"); | |
171 (cast(uint*)&c.Vfloat)[0] &= 0xFFBFFFFFL; | |
172 } | |
173 break; | |
174 | |
175 case TYdouble: | |
176 case TYidouble: | |
177 c.Vdouble = value; // unfortunately, this converts SNAN to QNAN | |
178 if (Port.isSignallingNan(value)) { | |
179 std.stdio.writeln("signalling double"); | |
180 // Put SNAN back | |
181 (cast(uint*)&c.Vdouble)[1] &= 0xFFF7FFFFL; | |
182 } | |
183 break; | |
184 | |
185 case TYldouble: | |
186 case TYildouble: | |
187 c.Vldouble = value; | |
188 break; | |
189 | |
190 default: | |
191 print(); | |
192 ///type.print(); | |
193 ///type.toBasetype().print(); | |
148 | 194 printf("ty = %d, tym = %lx\n", type.ty, ty); |
0 | 195 assert(0); |
196 } | |
197 return el_const(ty, &c); | |
198 } | |
199 | |
170 | 200 private enum char[6] zeropad = [0]; |
0 | 201 |
72 | 202 override dt_t** toDt(dt_t** pdt) |
0 | 203 { |
204 float fvalue; | |
205 double dvalue; | |
206 real evalue; | |
207 | |
208 //printf("RealExp.toDt(%Lg)\n", value); | |
209 switch (type.toBasetype().ty) | |
210 { | |
211 case Tfloat32: | |
212 case Timaginary32: | |
213 fvalue = value; | |
214 pdt = dtnbytes(pdt,4,cast(char*)&fvalue); | |
215 break; | |
216 | |
217 case Tfloat64: | |
218 case Timaginary64: | |
219 dvalue = value; | |
220 pdt = dtnbytes(pdt,8,cast(char*)&dvalue); | |
221 break; | |
222 | |
223 case Tfloat80: | |
224 case Timaginary80: | |
225 evalue = value; | |
226 pdt = dtnbytes(pdt,REALSIZE - REALPAD,cast(char*)&evalue); | |
227 pdt = dtnbytes(pdt,REALPAD,zeropad.ptr); | |
228 assert(REALPAD <= zeropad.sizeof); | |
229 break; | |
230 | |
231 default: | |
232 writef("%s\n", toChars()); | |
233 ///type.print(); | |
234 assert(0); | |
235 } | |
236 return pdt; | |
237 } | |
148 | 238 } |