KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > lispexpr > LangPrimType


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 /** Use to implement some special types that convert differently. */
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 JavaDoc nam, String JavaDoc sig, int siz, Class JavaDoc reflectClass)
48   {
49     super (nam, sig, siz, reflectClass);
50   }
51
52   public LangPrimType (String JavaDoc nam, String JavaDoc sig, int siz, Class JavaDoc 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 JavaDoc coerceFromObject (Object JavaDoc 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 JavaDoc(((Char) obj).charValue());
76       case 'V':
77         return Values.empty;
78       }
79     return super.coerceFromObject(obj);
80   }
81
82   public char charValue (Object JavaDoc value)
83   {
84     if (value instanceof Character JavaDoc)
85       return ((Character JavaDoc) 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     // We handle char specially, because Kawa does not use standard
117
// java.lang.Character type.
118
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 JavaDoc coerceToObject (Object JavaDoc obj)
129   {
130     char sig1 = getSignature().charAt(0);
131     switch (sig1)
132       {
133       case 'Z':
134     return language.booleanObject(((Boolean JavaDoc) obj).booleanValue());
135       case 'C':
136     if (obj instanceof Char)
137       return obj;
138     return Char.make(((Character JavaDoc) obj).charValue());
139       case 'B': case 'S': case 'I':
140     return IntNum.make(((Number JavaDoc) obj).intValue());
141       case 'J':
142     return IntNum.make(((Number JavaDoc) obj).longValue());
143       case 'D': case 'F':
144     return DFloNum.make(((Number JavaDoc) obj).doubleValue());
145       case 'V':
146         // Perhaps we should return Language.noValue() instead?
147
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 JavaDoc 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     // ... fall through ...
182
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     // Anything (except void) can be converted to boolean.
200
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     /*
220     switch (sig1)
221       {
222       case 'Z':
223       }
224     */

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