1 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 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 constant) { 35 super(Type.tUnknown); 36 if (constant instanceof Boolean ) { 37 updateParentType(Type.tBoolean); 38 constant = new Integer (((Boolean )constant).booleanValue() ? 1 : 0); 39 } else if (constant instanceof Integer ) { 40 int intVal = ((Integer ) 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 ) 57 updateParentType(Type.tLong); 58 else if (constant instanceof Float ) 59 updateParentType(Type.tFloat); 60 else if (constant instanceof Double ) 61 updateParentType(Type.tDouble); 62 else if (constant instanceof String ) 63 updateParentType(Type.tString); 64 else if (constant == null) 65 updateParentType(Type.tUObject); 66 else 67 throw new IllegalArgumentException ("Illegal constant type: " 68 +constant.getClass()); 69 value = constant; 70 } 71 72 public Object getValue() { 73 return value; 74 } 75 76 82 public boolean isOne(Type type) { 83 if (type instanceof IntegerType) { 84 return (value instanceof Integer 85 && ((Integer )value).intValue() == 1); 86 } else if (type == Type.tLong) { 87 return (value instanceof Long 88 && ((Long )value).longValue() == 1L); 89 } else if (type == Type.tFloat) { 90 return (value instanceof Float 91 && ((Float )value).floatValue() == 1.0f); 92 } else if (type == Type.tDouble) { 93 return (value instanceof Double 94 && ((Double )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 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 quoted(String str) { 117 StringBuffer result = new StringBuffer ("\""); 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 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 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 toString() { 157 String strVal = String.valueOf(value); 158 if (type.isOfType(Type.tBoolean)) { 159 int intVal = ((Integer )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 ) 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 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 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 207 if (type.isOfType(Type.tUInt)) { 208 int i = ((Integer ) 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 ) 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 254 return "("+type.getHint()+") "+strVal; 255 } 256 257 return strVal; 258 } 259 260 public void dumpExpression(TabbedPrintWriter writer) 261 throws java.io.IOException { 262 writer.print(toString()); 263 } 264 } 265 | Popular Tags |