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