Bug fix in array initialization: handle the special case like {{null,null}}
[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) {
86     TypeDescriptor td=new TypeDescriptor(getSymbol());
87     td.arraycount=arraycount+1;
88     td.type=type;
89     td.class_desc=class_desc;
90     state.addArrayType(td);
91     return td;
92   }
93
94   public boolean isArray() {
95     return (arraycount>0);
96   }
97
98   public int getArrayCount() {
99     return arraycount;
100   }
101
102   /* Only use this method if you really know what you are doing.  It
103    * doesn't have the effect you might expect. */
104
105   public void setArrayCount(int a) {
106     arraycount=a;
107   }
108
109   public TypeDescriptor dereference() {
110     TypeDescriptor td=new TypeDescriptor(getSymbol());
111     if (arraycount==0)
112       throw new Error();
113     td.arraycount=arraycount-1;
114     td.type=type;
115     td.class_desc=class_desc;
116     return td;
117   }
118
119   public String getSafeSymbol() {
120     if (isArray())
121       return IR.Flat.BuildCode.arraytype;
122     else if (isClass()) {
123       return class_desc.getSafeSymbol();
124     } else if (isByte())
125       return "char";
126     else if (isChar())
127       return "short";
128     else if (isShort())
129       return "short";
130     else if (isInt())
131       return "int";
132     else if (isBoolean())     //Booleans are ints in C
133       return "int";
134     else if (isLong())
135       return "long long";
136     else if (isVoid())
137       return "void";
138     else if (isDouble())
139       return "double";
140     else if (isFloat())
141       return "float";
142     else if (isOffset())
143       return "short";
144     else 
145       throw new Error("Error Type: "+type);
146   }
147
148   public String getRepairSymbol() {
149     if (isArray())
150       return IR.Flat.BuildCode.arraytype;
151     else if (isClass()) {
152       return class_desc.getSymbol();
153     } else if (isByte())
154       return "byte";
155     else if (isChar())
156       return "short";
157     else if (isShort())
158       return "short";
159     else if (isInt())
160       return "int";
161     else if (isBoolean())     //Booleans are ints in C
162       return "int";
163     else if (isLong())
164       return "long long";
165     else if (isVoid())
166       return "void";
167     else if (isDouble())
168       return "double";
169     else if (isFloat())
170       return "float";
171     else throw new Error("Error Type: "+type);
172   }
173
174   public String getSafeDescriptor() {
175     //Can't safely use [ in C
176     if (isArray())
177       return "_AR_"+this.dereference().getSafeDescriptor();
178     else if (isClass())
179       return class_desc.getSafeDescriptor();
180     else if (isByte())
181       return "B";
182     else if (isChar())
183       return "C";
184     else if (isShort())
185       return "S";
186     else if (isBoolean())
187       return "Z";
188     else if (isInt())
189       return "I";
190     else if (isLong())
191       return "J";
192     else if (isDouble())
193       return "D";
194     else if (isFloat())
195       return "F";
196     else if (isTag())
197       return "T";
198     else throw new Error();
199   }
200
201   public boolean isNumber() {
202     return (isIntegerType()||isFloat()||isDouble());
203   }
204
205   public boolean isByte() {
206     return type==BYTE;
207   }
208   public boolean isNull() {
209     return type==NULL;
210   }
211   public boolean isShort() {
212     return type==SHORT;
213   }
214   public boolean isInt() {
215     return type==INT;
216   }
217   public boolean isLong() {
218     return type==LONG;
219   }
220   public boolean isChar() {
221     return type==CHAR;
222   }
223   public boolean isBoolean() {
224     return type==BOOLEAN;
225   }
226   public boolean isFloat() {
227     return type==FLOAT;
228   }
229   public boolean isDouble() {
230     return type==DOUBLE;
231   }
232   public boolean isVoid() {
233     return type==VOID;
234   }
235
236   public boolean isOffset() {
237     return type==OFFSET;
238   }
239
240   public boolean isPtr() {
241     return ((isClass()&&!isEnum())||isNull()||isTag()||isArray());
242   }
243
244   public boolean isIntegerType() {
245     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
246   }
247
248   public void setClassDescriptor(ClassDescriptor cd) {
249     class_desc=cd;
250   }
251
252   public boolean isPrimitive() {
253     return ((type>=BYTE)&&(type<=DOUBLE));
254   }
255
256   public boolean isEnum() {
257     if(this.type != CLASS) {
258       return false;
259     } else if(this.class_desc != null){
260       return this.class_desc.isEnum();
261     }
262     return false;
263   }
264   
265   public boolean isClass() {
266     return type==CLASS;
267   }
268
269   public boolean isTag() {
270     return type==TAG;
271   }
272
273   public boolean isImmutable() {
274     return isPrimitive() || isString();
275   }
276
277   public TypeDescriptor(NameDescriptor name) {
278     super(name.toString());
279     this.type=CLASS;
280     this.class_desc=null;
281     this.arraycount=0;
282     this.isClassNameRef =false;
283   }
284
285   public TypeDescriptor(String st) {
286     super(st);
287     this.type=CLASS;
288     this.class_desc=null;
289     this.arraycount=0;
290     this.isClassNameRef =false;
291   }
292
293   public ClassDescriptor getClassDesc() {
294     return class_desc;
295   }
296
297   public TypeDescriptor(ClassDescriptor cd) {
298     super(cd.getSymbol());
299     this.type=CLASS;
300     this.class_desc=cd;
301     this.arraycount=0;
302     this.isClassNameRef =false;
303   }
304
305   public TypeDescriptor(int t) {
306     super(decodeInt(t));
307     this.type=t;
308     this.arraycount=0;
309     this.isClassNameRef =false;
310   }
311
312   public String toString() {
313     if (type==CLASS) {
314       return name;
315     } else
316       return decodeInt(type);
317   }
318
319   public String toPrettyString() {
320     String str=name;
321     if (type!=CLASS) {
322       str=decodeInt(type);
323     }
324     for(int i=0; i<arraycount; i++)
325       str+="[]";
326     return str;    
327   }
328
329   private static String decodeInt(int type) {
330     if (type==BYTE)
331       return "byte";
332     else if (type==BOOLEAN)
333       return "boolean";
334     else if (type==SHORT)
335       return "short";
336     else if (type==INT)
337       return "int";
338     else if (type==LONG)
339       return "long";
340     else if (type==CHAR)
341       return "char";
342     else if (type==FLOAT)
343       return "float";
344     else if (type==DOUBLE)
345       return "double";
346     else if (type==VOID)
347       return "void";
348     else if (type==NULL)
349       return "NULL";
350     else if (type==TAG)
351       return TypeUtil.TagClass;
352     else if (type==OFFSET)
353       return "offset";
354     else throw new Error();
355   }
356 }