KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > expr > ConstOperator


1 /* ConstOperator Copyright (C) 1998-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: ConstOperator.java,v 4.21.2.2 2002/05/28 17:34:06 hoenicke Exp $
18  */

19
20 package jode.expr;
21 import jode.type.Type;
22 import jode.type.IntegerType;
23 import jode.decompiler.TabbedPrintWriter;
24
25 public class ConstOperator extends NoArgOperator {
26     Object JavaDoc value;
27     boolean isInitializer = false;
28
29     private static final Type tBoolConstInt
30     = new IntegerType(IntegerType.IT_I | IntegerType.IT_C
31               | IntegerType.IT_Z
32               | IntegerType.IT_S | IntegerType.IT_B);
33
34     public ConstOperator(Object JavaDoc constant) {
35     super(Type.tUnknown);
36     if (constant instanceof Boolean JavaDoc) {
37         updateParentType(Type.tBoolean);
38         constant = new Integer JavaDoc(((Boolean JavaDoc)constant).booleanValue() ? 1 : 0);
39     } else if (constant instanceof Integer JavaDoc) {
40         int intVal = ((Integer JavaDoc) constant).intValue();
41         updateParentType
42         ((intVal == 0 || intVal == 1) ? tBoolConstInt
43          : (intVal < Short.MIN_VALUE
44             || intVal > Character.MAX_VALUE) ? Type.tInt
45          : new IntegerType
46          ((intVal < Byte.MIN_VALUE)
47           ? IntegerType.IT_S|IntegerType.IT_I
48           : (intVal < 0)
49           ? IntegerType.IT_S|IntegerType.IT_B|IntegerType.IT_I
50           : (intVal <= Byte.MAX_VALUE)
51           ? (IntegerType.IT_S|IntegerType.IT_B
52             |IntegerType.IT_C|IntegerType.IT_I)
53           : (intVal <= Short.MAX_VALUE)
54           ? IntegerType.IT_S|IntegerType.IT_C|IntegerType.IT_I
55           : IntegerType.IT_C|IntegerType.IT_I));
56     } else if (constant instanceof Long JavaDoc)
57         updateParentType(Type.tLong);
58     else if (constant instanceof Float JavaDoc)
59         updateParentType(Type.tFloat);
60     else if (constant instanceof Double JavaDoc)
61         updateParentType(Type.tDouble);
62     else if (constant instanceof String JavaDoc)
63         updateParentType(Type.tString);
64     else if (constant == null)
65         updateParentType(Type.tUObject);
66     else
67         throw new IllegalArgumentException JavaDoc("Illegal constant type: "
68                            +constant.getClass());
69     value = constant;
70     }
71
72     public Object JavaDoc getValue() {
73         return value;
74     }
75
76     /**
77      * Return true, if this value is a one of the given type.
78      * This is used for ++ and -- instructions.
79      * @param type the type for which this must be a one. This may
80      * be different from the type this value actually is.
81      */

82     public boolean isOne(Type type) {
83     if (type instanceof IntegerType) {
84         return (value instanceof Integer JavaDoc
85             && ((Integer JavaDoc)value).intValue() == 1);
86     } else if (type == Type.tLong) {
87         return (value instanceof Long JavaDoc
88             && ((Long JavaDoc)value).longValue() == 1L);
89     } else if (type == Type.tFloat) {
90         return (value instanceof Float JavaDoc
91             && ((Float JavaDoc)value).floatValue() == 1.0f);
92     } else if (type == Type.tDouble) {
93         return (value instanceof Double JavaDoc
94             && ((Double JavaDoc)value).doubleValue() == 1.0);
95     }
96     return false;
97     }
98
99     public int getPriority() {
100         return 1000;
101     }
102
103     public boolean opEquals(Operator o) {
104     if (o instanceof ConstOperator) {
105         Object JavaDoc otherValue = ((ConstOperator)o).value;
106         return value == null
107         ? otherValue == null : value.equals(otherValue);
108     }
109     return false;
110     }
111
112     public void makeInitializer(Type type) {
113         isInitializer = true;
114     }
115
116     private static String JavaDoc quoted(String JavaDoc str) {
117         StringBuffer JavaDoc result = new StringBuffer JavaDoc("\"");
118         for (int i=0; i< str.length(); i++) {
119             char c;
120             switch (c = str.charAt(i)) {
121             case '\0':
122                 result.append("\\0");
123                 break;
124             case '\t':
125                 result.append("\\t");
126                 break;
127             case '\n':
128                 result.append("\\n");
129                 break;
130             case '\r':
131                 result.append("\\r");
132                 break;
133             case '\\':
134                 result.append("\\\\");
135                 break;
136             case '\"':
137                 result.append("\\\"");
138                 break;
139             default:
140                 if (c < 32) {
141                     String JavaDoc oct = Integer.toOctalString(c);
142                     result.append("\\000".substring(0, 4-oct.length()))
143                         .append(oct);
144                 } else if (c >= 32 && c < 127)
145                     result.append(str.charAt(i));
146                 else {
147                     String JavaDoc hex = Integer.toHexString(c);
148                     result.append("\\u0000".substring(0, 6-hex.length()))
149                         .append(hex);
150                 }
151             }
152         }
153         return result.append("\"").toString();
154     }
155
156     public String JavaDoc toString() {
157         String JavaDoc strVal = String.valueOf(value);
158         if (type.isOfType(Type.tBoolean)) {
159         int intVal = ((Integer JavaDoc)value).intValue();
160             if (intVal == 0)
161                 return "false";
162             else if (intVal == 1)
163                 return "true";
164         else
165         throw new jode.AssertError
166             ("boolean is neither false nor true");
167         }
168     if (type.getHint().equals(Type.tChar)) {
169             char c = (char) ((Integer JavaDoc) value).intValue();
170             switch (c) {
171             case '\0':
172         return "\'\\0\'";
173             case '\t':
174                 return "\'\\t\'";
175             case '\n':
176                 return "\'\\n\'";
177             case '\r':
178                 return "\'\\r\'";
179             case '\\':
180                 return "\'\\\\\'";
181             case '\"':
182                 return "\'\\\"\'";
183             case '\'':
184                 return "\'\\\'\'";
185             }
186             if (c < 32) {
187                 String JavaDoc oct = Integer.toOctalString(c);
188                 return "\'\\000".substring(0, 5-oct.length())+oct+"\'";
189             }
190             if (c >= 32 && c < 127)
191                 return "\'"+c+"\'";
192             else {
193                 String JavaDoc hex = Integer.toHexString(c);
194                 return "\'\\u0000".substring(0, 7-hex.length())+hex+"\'";
195             }
196     } else if (type.equals(Type.tString)) {
197         return quoted(strVal);
198         } else if (parent != null) {
199             int opindex = parent.getOperatorIndex();
200             if (opindex >= OPASSIGN_OP + ADD_OP
201                 && opindex < OPASSIGN_OP + ASSIGN_OP)
202                 opindex -= OPASSIGN_OP;
203
204             if (opindex >= AND_OP && opindex < AND_OP + 3) {
205                 /* For bit wise and/or/xor change representation.
206                  */

207                 if (type.isOfType(Type.tUInt)) {
208                     int i = ((Integer JavaDoc) value).intValue();
209                     if (i < -1)
210                         strVal = "~0x"+Integer.toHexString(-i-1);
211                     else
212                         strVal = "0x"+Integer.toHexString(i);
213                 } else if (type.equals(Type.tLong)) {
214                     long l = ((Long JavaDoc) value).longValue();
215                     if (l < -1)
216                         strVal = "~0x"+Long.toHexString(-l-1);
217                     else
218                         strVal = "0x"+Long.toHexString(l);
219                 }
220             }
221         }
222         if (type.isOfType(Type.tLong))
223             return strVal+"L";
224         if (type.isOfType(Type.tFloat)) {
225         if (strVal.equals("NaN"))
226         return "Float.NaN";
227         if (strVal.equals("-Infinity"))
228         return "Float.NEGATIVE_INFINITY";
229         if (strVal.equals("Infinity"))
230         return "Float.POSITIVE_INFINITY";
231             return strVal+"F";
232     }
233         if (type.isOfType(Type.tDouble)) {
234         if (strVal.equals("NaN"))
235         return "Double.NaN";
236         if (strVal.equals("-Infinity"))
237         return "Double.NEGATIVE_INFINITY";
238         if (strVal.equals("Infinity"))
239         return "Double.POSITIVE_INFINITY";
240             return strVal;
241     }
242         if (!type.isOfType(Type.tInt)
243         && (type.getHint().equals(Type.tByte)
244         || type.getHint().equals(Type.tShort))
245             && !isInitializer
246         && !(parent instanceof StoreInstruction
247          && parent.getOperatorIndex() != ASSIGN_OP
248          && parent.subExpressions[1] == this)) {
249             /* One of the strange things in java. All constants
250              * are int and must be explicitly casted to byte,...,short.
251              * But in assignments and initializers this cast is unnecessary.
252          * See JLS section 5.2
253              */

254             return "("+type.getHint()+") "+strVal;
255     }
256
257         return strVal;
258     }
259
260     public void dumpExpression(TabbedPrintWriter writer)
261     throws java.io.IOException JavaDoc {
262     writer.print(toString());
263     }
264 }
265
Popular Tags