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