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