1ca436236593d1d1769a5684938ff2978c34a493
[IRC.git] / Robust / src / IR / TypeDescriptor.java
1 package IR;
2
3 /**
4  * Descriptor
5  *
6  * represents a symbol in the language (var name, function name, etc).
7  */
8
9 public class TypeDescriptor extends Descriptor {
10   public static final int BYTE=1;
11   public static final int SHORT=2;
12   public static final int INT=3;
13   public static final int LONG=4;
14   public static final int CHAR=5;
15   public static final int BOOLEAN=6;
16   public static final int FLOAT=7;
17   public static final int DOUBLE=8;
18   public static final int VOID=9;
19   public static final int NULL=10;
20   public static final int TAG=11;
21   public static final int CLASS=12;
22   public static final int OFFSET=13;
23
24
25   int arraycount;
26   private int type;
27   ClassDescriptor class_desc;
28   boolean isClassNameRef = false;
29
30   public boolean equals(Object o) {
31     if (o instanceof TypeDescriptor) {
32       TypeDescriptor t=(TypeDescriptor)o;
33       if (t.type!=type)
34         return false;
35       if ((type==CLASS)&&(!t.getSymbol().equals(getSymbol())))
36         return false;
37       if (t.arraycount!=arraycount)
38         return false;
39       if (t.isClassNameRef != this.isClassNameRef)
40         return false;
41       return true;
42     }
43     return false;
44   }
45
46   public boolean isString() {
47     if (type!=CLASS)
48       return false;
49     if (arraycount>0)
50       return false;
51     if (!getSymbol().equals(TypeUtil.StringClass))
52       return false;
53     return true;
54   }
55   
56   public boolean isClassNameRef() {
57     return this.isClassNameRef;
58   }
59   
60   public void setClassNameRef() {
61     this.isClassNameRef = true;
62   }
63
64   public int hashCode() {
65     int hashcode=type^arraycount;
66     if (type==CLASS)
67       hashcode^=getSymbol().hashCode();
68     return hashcode;
69   }
70
71   public boolean iswrapper() {
72     if (arraycount!=0||!isClass())
73       return false;
74     return (name.equals("bytewrapper")||
75             name.equals("booleanwrapper")||
76             name.equals("shortwrapper")||
77             name.equals("intwrapper")||
78             name.equals("longwrapper")||
79             name.equals("charwrapper")||
80             name.equals("floatwrapper")||
81             name.equals("doublewrapper")||
82             name.equals("Objectwrapper"));
83   }
84
85   public TypeDescriptor makeArray(State state, boolean addflag) {
86     TypeDescriptor td=new TypeDescriptor(getSymbol());
87     td.arraycount=arraycount+1;
88     td.type=type;
89     td.class_desc=class_desc;
90     if(addflag) {
91       state.addArrayType(td);
92     }
93     return td;
94   }
95
96   public boolean isArray() {
97     return (arraycount>0);
98   }
99
100   public int getArrayCount() {
101     return arraycount;
102   }
103
104   /* Only use this method if you really know what you are doing.  It
105    * doesn't have the effect you might expect. */
106
107   public void setArrayCount(int a) {
108     arraycount=a;
109   }
110
111   public TypeDescriptor dereference() {
112     TypeDescriptor td=new TypeDescriptor(getSymbol());
113     if (arraycount==0)
114       throw new Error();
115     td.arraycount=arraycount-1;
116     td.type=type;
117     td.class_desc=class_desc;
118     return td;
119   }
120
121   public String getSafeSymbol() {
122     if (isArray())
123       return IR.Flat.BuildCode.arraytype;
124     else if (isClass()) {
125       return class_desc.getSafeSymbol();
126     } else if (isByte())
127       return "char";
128     else if (isChar())
129       return "short";
130     else if (isShort())
131       return "short";
132     else if (isInt())
133       return "int";
134     else if (isBoolean())     //Booleans are ints in C
135       return "int";
136     else if (isLong())
137       return "long long";
138     else if (isVoid())
139       return "void";
140     else if (isDouble())
141       return "double";
142     else if (isFloat())
143       return "float";
144     else if (isOffset())
145       return "short";
146     else throw new Error("Error Type: "+type);
147   }
148
149   public String getRepairSymbol() {
150     if (isArray())
151       return IR.Flat.BuildCode.arraytype;
152     else if (isClass()) {
153       return class_desc.getSymbol();
154     } else if (isByte())
155       return "byte";
156     else if (isChar())
157       return "short";
158     else if (isShort())
159       return "short";
160     else if (isInt())
161       return "int";
162     else if (isBoolean())     //Booleans are ints in C
163       return "int";
164     else if (isLong())
165       return "long long";
166     else if (isVoid())
167       return "void";
168     else if (isDouble())
169       return "double";
170     else if (isFloat())
171       return "float";
172     else throw new Error("Error Type: "+type);
173   }
174
175   public String getSafeDescriptor() {
176     //Can't safely use [ in C
177     if (isArray())
178       return "_AR_"+this.dereference().getSafeDescriptor();
179     else if (isClass())
180       return class_desc.getSafeDescriptor();
181     else if (isByte())
182       return "B";
183     else if (isChar())
184       return "C";
185     else if (isShort())
186       return "S";
187     else if (isBoolean())
188       return "Z";
189     else if (isInt())
190       return "I";
191     else if (isLong())
192       return "J";
193     else if (isDouble())
194       return "D";
195     else if (isFloat())
196       return "F";
197     else if (isTag())
198       return "T";
199     else throw new Error();
200   }
201
202   public boolean isNumber() {
203     return (isIntegerType()||isFloat()||isDouble());
204   }
205
206   public boolean isByte() {
207     return type==BYTE;
208   }
209   public boolean isNull() {
210     return type==NULL;
211   }
212   public boolean isShort() {
213     return type==SHORT;
214   }
215   public boolean isInt() {
216     return type==INT;
217   }
218   public boolean isLong() {
219     return type==LONG;
220   }
221   public boolean isChar() {
222     return type==CHAR;
223   }
224   public boolean isBoolean() {
225     return type==BOOLEAN;
226   }
227   public boolean isFloat() {
228     return type==FLOAT;
229   }
230   public boolean isDouble() {
231     return type==DOUBLE;
232   }
233   public boolean isVoid() {
234     return type==VOID;
235   }
236
237   public boolean isOffset() {
238     return type==OFFSET;
239   }
240
241   public boolean isPtr() {
242     return ((isClass()&&!isEnum())||isNull()||isTag()||isArray());
243   }
244
245   public boolean isIntegerType() {
246     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
247   }
248
249   public void setClassDescriptor(ClassDescriptor cd) {
250     class_desc=cd;
251   }
252
253   public boolean isPrimitive() {
254     return ((type>=BYTE)&&(type<=DOUBLE));
255   }
256
257   public boolean isEnum() {
258     if(this.type != CLASS) {
259       return false;
260     } else if(this.class_desc != null){
261       return this.class_desc.isEnum();
262     }
263     return false;
264   }
265   
266   public boolean isClass() {
267     return type==CLASS;
268   }
269
270   public boolean isTag() {
271     return type==TAG;
272   }
273
274   public boolean isImmutable() {
275     return isPrimitive() || isString();
276   }
277
278   public TypeDescriptor(NameDescriptor name) {
279     super(name.toString());
280     this.type=CLASS;
281     this.class_desc=null;
282     this.arraycount=0;
283     this.isClassNameRef =false;
284   }
285
286   public TypeDescriptor(String st) {
287     super(st);
288     this.type=CLASS;
289     this.class_desc=null;
290     this.arraycount=0;
291     this.isClassNameRef =false;
292   }
293
294   public ClassDescriptor getClassDesc() {
295     return class_desc;
296   }
297
298   public TypeDescriptor(ClassDescriptor cd) {
299     super(cd.getSymbol());
300     this.type=CLASS;
301     this.class_desc=cd;
302     this.arraycount=0;
303     this.isClassNameRef =false;
304   }
305
306   public TypeDescriptor(int t) {
307     super(decodeInt(t));
308     this.type=t;
309     this.arraycount=0;
310     this.isClassNameRef =false;
311   }
312
313   public String toString() {
314     if (type==CLASS) {
315       return name;
316     } else
317       return decodeInt(type);
318   }
319
320   public String toPrettyString() {
321     String str=name;
322     if (type!=CLASS) {
323       str=decodeInt(type);
324     }
325     for(int i=0; i<arraycount; i++)
326       str+="[]";
327     return str;    
328   }
329
330   private static String decodeInt(int type) {
331     if (type==BYTE)
332       return "byte";
333     else if (type==BOOLEAN)
334       return "boolean";
335     else if (type==SHORT)
336       return "short";
337     else if (type==INT)
338       return "int";
339     else if (type==LONG)
340       return "long";
341     else if (type==CHAR)
342       return "char";
343     else if (type==FLOAT)
344       return "float";
345     else if (type==DOUBLE)
346       return "double";
347     else if (type==VOID)
348       return "void";
349     else if (type==NULL)
350       return "null";
351     else if (type==TAG)
352       return TypeUtil.TagClass;
353     else if (type==OFFSET)
354       return "offset";
355     else throw new Error();
356   }
357 }