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