1 package gnu.kawa.lispexpr; 2 import gnu.bytecode.*; 3 import gnu.math.IntNum; 4 import gnu.math.DFloNum; 5 import gnu.expr.*; 6 import gnu.text.Char; 7 import gnu.mapping.Procedure; 8 import gnu.mapping.Values; 9 10 11 12 public class LangPrimType extends PrimType implements TypeValue 13 { 14 Language language; 15 PrimType implementationType; 16 17 public static final LangPrimType byteType 18 = new LangPrimType(Type.byte_type); 19 public static final LangPrimType shortType 20 = new LangPrimType(Type.short_type); 21 public static final LangPrimType intType 22 = new LangPrimType(Type.int_type); 23 public static final LangPrimType longType 24 = new LangPrimType(Type.long_type); 25 public static final LangPrimType floatType 26 = new LangPrimType(Type.float_type); 27 public static final LangPrimType doubleType 28 = new LangPrimType(Type.double_type); 29 public static final LangPrimType charType 30 = new LangPrimType(Type.char_type); 31 public static final LangPrimType voidType 32 = new LangPrimType(Type.void_type); 33 34 public LangPrimType (PrimType type) 35 { 36 super(type); 37 implementationType = type; 38 } 39 40 public LangPrimType (PrimType type, Language language) 41 { 42 super(type); 43 this.language = language; 44 implementationType = type; 45 } 46 47 public LangPrimType (String nam, String sig, int siz, Class reflectClass) 48 { 49 super (nam, sig, siz, reflectClass); 50 } 51 52 public LangPrimType (String nam, String sig, int siz, Class reflectClass, 53 Language language) 54 { 55 this(nam, sig, siz, reflectClass); 56 implementationType = Type.signatureToPrimitive(sig.charAt(0)); 57 this.language = language; 58 } 59 60 public Type getImplementationType() 61 { 62 return implementationType; 63 } 64 65 public Object coerceFromObject (Object obj) 66 { 67 if (obj.getClass() == reflectClass) 68 return obj; 69 char sig1 = getSignature().charAt(0); 70 switch (sig1) 71 { 72 case 'Z': 73 return language.isTrue(obj) ? Boolean.TRUE : Boolean.FALSE; 74 case 'C': 75 return new Character (((Char) obj).charValue()); 76 case 'V': 77 return Values.empty; 78 } 79 return super.coerceFromObject(obj); 80 } 81 82 public char charValue (Object value) 83 { 84 if (value instanceof Character ) 85 return ((Character ) value).charValue(); 86 return ((Char) value).charValue(); 87 } 88 89 public void emitIsInstance (CodeAttr code) 90 { 91 char sig1 = getSignature().charAt(0); 92 switch (sig1) 93 { 94 case 'Z': 95 code.emitPop(1); 96 code.emitPushInt(1); 97 break; 98 case 'C': 99 ClassType scmCharType = ClassType.make("gnu.text.Char"); 100 code.emitInstanceof(scmCharType); 101 break; 102 default: 103 super.emitIsInstance(code); 104 } 105 } 106 107 public void emitCoerceFromObject (CodeAttr code) 108 { 109 char sig1 = getSignature().charAt(0); 110 switch (sig1) 111 { 112 case 'Z': 113 language.emitCoerceToBoolean(code); 114 break; 115 case 'C': 116 ClassType scmCharType = ClassType.make("gnu.text.Char"); 119 Method charValueMethod = scmCharType.getDeclaredMethod("charValue", 0); 120 code.emitCheckcast(scmCharType); 121 code.emitInvokeVirtual(charValueMethod); 122 break; 123 default: 124 super.emitCoerceFromObject(code); 125 } 126 } 127 128 public Object coerceToObject (Object obj) 129 { 130 char sig1 = getSignature().charAt(0); 131 switch (sig1) 132 { 133 case 'Z': 134 return language.booleanObject(((Boolean ) obj).booleanValue()); 135 case 'C': 136 if (obj instanceof Char) 137 return obj; 138 return Char.make(((Character ) obj).charValue()); 139 case 'B': case 'S': case 'I': 140 return IntNum.make(((Number ) obj).intValue()); 141 case 'J': 142 return IntNum.make(((Number ) obj).longValue()); 143 case 'D': case 'F': 144 return DFloNum.make(((Number ) obj).doubleValue()); 145 case 'V': 146 return gnu.mapping.Values.empty; 148 } 149 return super.coerceToObject(obj); 150 } 151 152 public void emitCoerceToObject (CodeAttr code) 153 { 154 char sig1 = getSignature().charAt(0); 155 Type argType = null; 156 String cname = null; 157 switch (sig1) 158 { 159 case 'Z': 160 code.emitIfIntNotZero(); 161 language.emitPushBoolean(true, code); 162 code.emitElse(); 163 language.emitPushBoolean(false, code); 164 code.emitFi(); 165 break; 166 case 'C': 167 ClassType scmCharType = ClassType.make("gnu.text.Char"); 168 Method makeCharMethod = scmCharType.getDeclaredMethod("make", 1); 169 code.emitInvokeStatic(makeCharMethod); 170 break; 171 case 'B': case 'S': case 'I': 172 cname = "gnu.math.IntNum"; 173 argType = Type.int_type; 174 break; 175 case 'J': 176 cname = "gnu.math.IntNum"; 177 argType = Type.long_type; 178 break; 179 case 'F': 180 code.emitConvert(Type.float_type, Type.double_type); 181 case 'D': 183 cname = "gnu.math.DFloNum"; 184 argType = Type.double_type; 185 break; 186 default: 187 super.emitCoerceToObject(code); 188 } 189 if (cname != null) 190 { 191 ClassType clas = ClassType.make(cname); 192 Type[] args = { argType }; 193 code.emitInvokeStatic(clas.getDeclaredMethod("make", args)); 194 } 195 } 196 197 public int compare(Type other) 198 { 199 char sig1 = getSignature().charAt(0); 201 if (other instanceof PrimType) 202 { 203 char sig2 = other.getSignature().charAt(0); 204 if (sig1 == sig2) 205 return 0; 206 if (sig1 == 'V') 207 return 1; 208 if (sig2 == 'V' || sig2 == 'Z') 209 return -1; 210 } 211 if (sig1 == 'V' || sig1 == 'Z') 212 return 1; 213 return super.compare(other); 214 } 215 216 public void emitTestIf(Variable incoming, Declaration decl, Compilation comp) 217 { 218 char sig1 = getSignature().charAt(0); 219 225 CodeAttr code = comp.getCode(); 226 if (incoming != null) 227 code.emitLoad(incoming); 228 if (decl != null) 229 { 230 code.emitDup(); 231 decl.compileStore(comp); 232 } 233 emitIsInstance(code); 234 code.emitIfIntNotZero(); 235 } 236 237 public void emitIsInstance(Variable incoming, 238 Compilation comp, Target target) 239 { 240 gnu.kawa.reflect.InstanceOf.emitIsInstance(this, incoming, comp, target); 241 } 242 243 public Procedure getConstructor () 244 { 245 return null; 246 } 247 } 248 | Popular Tags |