KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xalan > internal > xsltc > compiler > util > RealType


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: RealType.java,v 1.8 2004/02/16 22:26:44 minchau Exp $
18  */

19
20 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
21
22 import com.sun.org.apache.bcel.internal.generic.BranchHandle;
23 import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
24 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
25 import com.sun.org.apache.bcel.internal.generic.DLOAD;
26 import com.sun.org.apache.bcel.internal.generic.DSTORE;
27 import com.sun.org.apache.bcel.internal.generic.GOTO;
28 import com.sun.org.apache.bcel.internal.generic.IFEQ;
29 import com.sun.org.apache.bcel.internal.generic.IFNE;
30 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
31 import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
32 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
33 import com.sun.org.apache.bcel.internal.generic.Instruction;
34 import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
35 import com.sun.org.apache.bcel.internal.generic.InstructionList;
36 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
37 import com.sun.org.apache.bcel.internal.generic.NEW;
38 import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
39 import com.sun.org.apache.xalan.internal.xsltc.compiler.FlowList;
40
41 /**
42  * @author Jacek Ambroziak
43  * @author Santiago Pericas-Geertsen
44  */

45 public final class RealType extends NumberType {
46     protected RealType() {}
47
48     public String JavaDoc toString() {
49     return "real";
50     }
51
52     public boolean identicalTo(Type other) {
53     return this == other;
54     }
55
56     public String JavaDoc toSignature() {
57     return "D";
58     }
59
60     public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
61     return com.sun.org.apache.bcel.internal.generic.Type.DOUBLE;
62     }
63
64     /**
65      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#distanceTo
66      */

67     public int distanceTo(Type type) {
68     if (type == this) {
69         return 0;
70     }
71     else if (type == Type.Int) {
72         return 1;
73     }
74     else {
75         return Integer.MAX_VALUE;
76     }
77     }
78
79     /**
80      * Translates a real into an object of internal type <code>type</code>. The
81      * translation to int is undefined since reals are never converted to ints.
82      *
83      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
84      */

85     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
86                 Type type) {
87     if (type == Type.String) {
88         translateTo(classGen, methodGen, (StringType) type);
89     }
90     else if (type == Type.Boolean) {
91         translateTo(classGen, methodGen, (BooleanType) type);
92     }
93     else if (type == Type.Reference) {
94         translateTo(classGen, methodGen, (ReferenceType) type);
95     }
96     else if (type == Type.Int) {
97         translateTo(classGen, methodGen, (IntType) type);
98     }
99     else {
100         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
101                     toString(), type.toString());
102         classGen.getParser().reportError(Constants.FATAL, err);
103     }
104     }
105
106     /**
107      * Expects a real on the stack and pushes its string value by calling
108      * <code>Double.toString(double d)</code>.
109      *
110      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
111      */

112     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
113                 StringType type) {
114     final ConstantPoolGen cpg = classGen.getConstantPool();
115     final InstructionList il = methodGen.getInstructionList();
116     il.append(new INVOKESTATIC(cpg.addMethodref(BASIS_LIBRARY_CLASS,
117                             "realToString",
118                             "(D)" + STRING_SIG)));
119     }
120
121     /**
122      * Expects a real on the stack and pushes a 0 if that number is 0.0 and
123      * a 1 otherwise.
124      *
125      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
126      */

127     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
128                 BooleanType type) {
129     final InstructionList il = methodGen.getInstructionList();
130     FlowList falsel = translateToDesynthesized(classGen, methodGen, type);
131     il.append(ICONST_1);
132     final BranchHandle truec = il.append(new GOTO(null));
133     falsel.backPatch(il.append(ICONST_0));
134     truec.setTarget(il.append(NOP));
135     }
136
137     /**
138      * Expects a real on the stack and pushes a truncated integer value
139      *
140      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
141      */

142     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
143                 IntType type) {
144     final ConstantPoolGen cpg = classGen.getConstantPool();
145     final InstructionList il = methodGen.getInstructionList();
146     il.append(new INVOKESTATIC(cpg.addMethodref(BASIS_LIBRARY_CLASS,
147                             "realToInt","(D)I")));
148     }
149
150     /**
151      * Translates a real into a non-synthesized boolean. It does not push a
152      * 0 or a 1 but instead returns branchhandle list to be appended to the
153      * false list. A NaN must be converted to "false".
154      *
155      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized
156      */

157     public FlowList translateToDesynthesized(ClassGenerator classGen,
158                          MethodGenerator methodGen,
159                          BooleanType type) {
160     LocalVariableGen local;
161     final FlowList flowlist = new FlowList();
162     final ConstantPoolGen cpg = classGen.getConstantPool();
163     final InstructionList il = methodGen.getInstructionList();
164
165     // Store real into a local variable
166
il.append(DUP2);
167     local = methodGen.addLocalVariable("real_to_boolean_tmp",
168                        com.sun.org.apache.bcel.internal.generic.Type.DOUBLE,
169                        il.getEnd(), null);
170     il.append(new DSTORE(local.getIndex()));
171
172     // Compare it to 0.0
173
il.append(DCONST_0);
174     il.append(DCMPG);
175     flowlist.add(il.append(new IFEQ(null)));
176
177     //!!! call isNaN
178
// Compare it to itself to see if NaN
179
il.append(new DLOAD(local.getIndex()));
180     il.append(new DLOAD(local.getIndex()));
181     il.append(DCMPG);
182     flowlist.add(il.append(new IFNE(null))); // NaN != NaN
183
return flowlist;
184     }
185
186     /**
187      * Expects a double on the stack and pushes a boxed double. Boxed
188      * double are represented by an instance of <code>java.lang.Double</code>.
189      *
190      * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
191      */

192     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
193                 ReferenceType type) {
194     final ConstantPoolGen cpg = classGen.getConstantPool();
195     final InstructionList il = methodGen.getInstructionList();
196     il.append(new NEW(cpg.addClass(DOUBLE_CLASS)));
197     il.append(DUP_X2);
198     il.append(DUP_X2);
199     il.append(POP);
200     il.append(new INVOKESPECIAL(cpg.addMethodref(DOUBLE_CLASS,
201                              "<init>", "(D)V")));
202     }
203
204     /**
205      * Translates a real into the Java type denoted by <code>clazz</code>.
206      * Expects a real on the stack and pushes a number of the appropriate
207      * type after coercion.
208      */

209     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
210                 final Class JavaDoc clazz) {
211     final InstructionList il = methodGen.getInstructionList();
212     if (clazz == Character.TYPE) {
213         il.append(D2I);
214         il.append(I2C);
215     }
216     else if (clazz == Byte.TYPE) {
217         il.append(D2I);
218         il.append(I2B);
219     }
220     else if (clazz == Short.TYPE) {
221         il.append(D2I);
222         il.append(I2S);
223     }
224     else if (clazz == Integer.TYPE) {
225         il.append(D2I);
226     }
227     else if (clazz == Long.TYPE) {
228         il.append(D2L);
229     }
230     else if (clazz == Float.TYPE) {
231         il.append(D2F);
232     }
233     else if (clazz == Double.TYPE) {
234         il.append(NOP);
235     }
236         // Is Double <: clazz? I.e. clazz in { Double, Number, Object }
237
else if (clazz.isAssignableFrom(java.lang.Double JavaDoc.class)) {
238             translateTo(classGen, methodGen, Type.Reference);
239         }
240     else {
241         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
242                     toString(), clazz.getName());
243         classGen.getParser().reportError(Constants.FATAL, err);
244     }
245     }
246
247     /**
248      * Translates an external (primitive) Java type into a real. Expects a java
249      * object on the stack and pushes a real (i.e., a double).
250      */

251     public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen,
252                   Class JavaDoc clazz) {
253     InstructionList il = methodGen.getInstructionList();
254
255     if (clazz == Character.TYPE || clazz == Byte.TYPE ||
256         clazz == Short.TYPE || clazz == Integer.TYPE) {
257         il.append(I2D);
258     }
259     else if (clazz == Long.TYPE) {
260         il.append(L2D);
261     }
262     else if (clazz == Float.TYPE) {
263         il.append(F2D);
264     }
265     else if (clazz == Double.TYPE) {
266         il.append(NOP);
267     }
268     else {
269         ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
270                     toString(), clazz.getName());
271         classGen.getParser().reportError(Constants.FATAL, err);
272     }
273     }
274
275     /**
276      * Translates an object of this type to its boxed representation.
277      */

278     public void translateBox(ClassGenerator classGen,
279                  MethodGenerator methodGen) {
280     translateTo(classGen, methodGen, Type.Reference);
281     }
282
283     /**
284      * Translates an object of this type to its unboxed representation.
285      */

286     public void translateUnBox(ClassGenerator classGen,
287                    MethodGenerator methodGen) {
288     final ConstantPoolGen cpg = classGen.getConstantPool();
289     final InstructionList il = methodGen.getInstructionList();
290     il.append(new CHECKCAST(cpg.addClass(DOUBLE_CLASS)));
291     il.append(new INVOKEVIRTUAL(cpg.addMethodref(DOUBLE_CLASS,
292                              DOUBLE_VALUE,
293                              DOUBLE_VALUE_SIG)));
294     }
295
296     public Instruction ADD() {
297     return InstructionConstants.DADD;
298     }
299
300     public Instruction SUB() {
301     return InstructionConstants.DSUB;
302     }
303
304     public Instruction MUL() {
305     return InstructionConstants.DMUL;
306     }
307
308     public Instruction DIV() {
309     return InstructionConstants.DDIV;
310     }
311
312     public Instruction REM() {
313     return InstructionConstants.DREM;
314     }
315
316     public Instruction NEG() {
317     return InstructionConstants.DNEG;
318     }
319
320     public Instruction LOAD(int slot) {
321     return new DLOAD(slot);
322     }
323     
324     public Instruction STORE(int slot) {
325     return new DSTORE(slot);
326     }
327
328     public Instruction POP() {
329     return POP2;
330     }
331     
332     public Instruction CMP(boolean less) {
333     return less ? InstructionConstants.DCMPG : InstructionConstants.DCMPL;
334     }
335
336     public Instruction DUP() {
337     return DUP2;
338     }
339 }
340
341
Popular Tags