Completed support for generating C code.
[repair.git] / Repair / RepairCompiler / MCC / IR / StructureGenerator.java
1 package MCC.IR;
2
3 import java.io.*;
4 import java.util.*;
5 import MCC.State;
6
7 public class StructureGenerator {
8     State state;
9     CodeWriter cr;
10     CodeWriter crhead;
11     TypeDescriptor[] tdarray;
12     RepairGenerator rg;
13     StructureGenerator(State state, RepairGenerator rg) {
14         this.state=state;
15         this.rg=rg;
16         try {
17             cr=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.c"),true));
18             crhead=new StandardCodeWriter(new java.io.PrintWriter(new FileOutputStream("size.h"),true));
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23
24     void buildall() {
25         int max=TypeDescriptor.counter;
26         tdarray=new TypeDescriptor[max];
27         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
28             TypeDescriptor ttd=(TypeDescriptor)it.next();
29             tdarray[ttd.getId()]=ttd;
30         }
31         cr.outputline("#include \"size.h\"");
32         generategetfield();
33         generategetnumfields();
34         generateisArray();
35         generateisPtr();
36         generateissubtype();
37         generatecalls();
38         generatecomputesize();
39         generateheader();
40     }
41
42     private void generatecalls() {
43         int max=TypeDescriptor.counter;
44         cr.outputline("int arsize["+max+"];");
45         cr.outputline("int arsizeBytes["+max+"];");
46
47         for(int i=0;i<max;i++) {
48             TypeDescriptor ttd=tdarray[i];
49             if (ttd instanceof StructureTypeDescriptor) {
50                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
51                 String str="int arnumelement"+std.getId()+"["+std.fieldlist.size()+"]={";
52                 for(int j=0;j<std.fieldlist.size();j++) {
53                     str+=0;
54                     if (((j+1)!=std.fieldlist.size()))
55                         str+=",";
56                 }
57                 str+="};";
58                 cr.outputline(str);
59             } else
60                 cr.outputline("int arnumelement"+ttd.getId()+"[1];"); // c doesn't like 0 length arrays
61         }
62         String str="int* arnumelements["+String.valueOf(max)+"]={";
63         for(int i=0;i<max;i++) {
64             str+="arnumelement"+i;
65             if (((i+1)!=max))
66                 str+=",";
67         }
68         str+="};";
69         cr.outputline(str);
70
71
72         cr.outputline("int size(int type) {");
73         cr.outputline("return arsize[type];");
74         cr.outputline("}");
75
76         cr.outputline("int sizeBytes(int type) {");
77         cr.outputline("return arsizeBytes[type];");
78         cr.outputline("}");
79
80         cr.outputline("int numElements(int type, int fieldindex) {");
81         cr.outputline("return arnumelements[type][fieldindex];");
82         cr.outputline("}");
83     }
84
85     private void generatecomputesize() {
86         int max=TypeDescriptor.counter;
87         cr.outputline("void computesizes(struct "+rg.name+"_state * obj) {");
88         cr.outputline("int i;");
89         cr.outputline(rg.name+"_statecomputesizes(obj,arsize,arnumelements);");
90         cr.outputline("for(i=0;i<"+max+";i++) {");
91         cr.outputline("int bits=arsize[i];");
92         cr.outputline("int bytes=bits>>3;");
93         cr.outputline("if (bits%8) bytes++;");
94         cr.outputline("arsizeBytes[i]=bytes;");
95         cr.outputline("}");
96         cr.outputline("}");
97     }
98
99     private void generateheader() {
100         crhead.outputline("#include \""+rg.headername + "\"");
101         crhead.outputline("int getfield(int type, int fieldindex);");
102         crhead.outputline("int isArray(int type, int fieldindex);");
103         crhead.outputline("int isPtr(int type, int fieldindex);");
104         crhead.outputline("int numElements(int type, int fieldindex);");
105         crhead.outputline("int size(int type);");
106         crhead.outputline("int sizeBytes(int type);");
107         crhead.outputline("int getnumfields(int type);");
108         crhead.outputline("bool issubtype(int subtype, int type);");
109         crhead.outputline("void computesizes(struct "+rg.name+"_state *);");
110     }
111
112
113     private void generategetfield() {
114         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
115             TypeDescriptor ttd=(TypeDescriptor)it.next();
116             String str="";
117
118             if (ttd instanceof StructureTypeDescriptor) {
119                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
120                 str="int argetfield"+std.getId()+"["+std.fieldlist.size()+"]={";
121                 for(int i=0;i<std.fieldlist.size();i++) {
122                     FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
123                     TypeDescriptor td = fd.getType();
124                     str+=String.valueOf(td.getId());
125                     if ((i+1)!=std.fieldlist.size())
126                         str+=",";
127                 }
128                 str+="};";
129                 cr.outputline(str);
130             } else
131                 cr.outputline("int argetfield"+ttd.getId()+"[1];"); //c doesn't like zero length arrays
132         }
133         int max=TypeDescriptor.counter;
134         String str="int* argetfield["+String.valueOf(max)+"]={";
135         for(int i=0;i<max;i++) {
136             str+="argetfield"+i;
137             if (((i+1)!=max))
138                 str+=",";
139         }
140         str+="};";
141         cr.outputline(str);
142
143         cr.outputline("int getfield(int type, int fieldindex) {");
144         cr.outputline("return argetfield[type][fieldindex];");
145         cr.outputline("}");
146     }
147
148    private void generategetnumfields() {
149         int max=TypeDescriptor.counter;
150         String str="int argetnumfield["+String.valueOf(max)+"]={";
151         for(int i=0;i<max;i++) {
152             TypeDescriptor ttd=tdarray[i];
153             if (ttd instanceof StructureTypeDescriptor) {
154                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
155                 str+=String.valueOf(std.fieldlist.size());
156             } else
157                 str+="0";
158             if (((i+1)!=max))
159                 str+=",";
160         }
161         str+="};";
162         cr.outputline(str);
163
164         cr.outputline("int getnumfields(int type) {");
165         cr.outputline("return argetnumfield[type];");
166         cr.outputline("}");
167     }
168     private void generateisArray() {
169         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
170             TypeDescriptor ttd=(TypeDescriptor)it.next();
171             String str="";
172
173             if (ttd instanceof StructureTypeDescriptor) {
174                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
175                 str="int arisArray"+std.getId()+"["+std.fieldlist.size()+"]={";
176                 for(int i=0;i<std.fieldlist.size();i++) {
177                     FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
178                     TypeDescriptor td = fd.getType();
179                     if (fd instanceof ArrayDescriptor)
180                         str+="1";
181                     else
182                         str+="0";
183                     if ((i+1)!=std.fieldlist.size())
184                         str+=",";
185                 }
186                 str+="};";
187                 cr.outputline(str);
188             } else
189                 cr.outputline("int arisArray"+ttd.getId()+"[1];"); // c doesn't like 0 length arrays
190         }
191         int max=TypeDescriptor.counter;
192         String str="int* arisArray["+String.valueOf(max)+"]={";
193         for(int i=0;i<max;i++) {
194             str+="arisArray"+i;
195             if (((i+1)!=max))
196                 str+=",";
197         }
198         str+="};";
199         cr.outputline(str);
200
201         cr.outputline("int isArray(int type, int fieldindex) {");
202         cr.outputline("return arisArray[type][fieldindex];");
203         cr.outputline("}");
204     }
205     private void generateisPtr() {
206         for(Iterator it=state.stTypes.descriptors();it.hasNext();) {
207             TypeDescriptor ttd=(TypeDescriptor)it.next();
208             String str="";
209
210             if (ttd instanceof StructureTypeDescriptor) {
211                 StructureTypeDescriptor std=(StructureTypeDescriptor) ttd;
212                 str="int arisPtr"+std.getId()+"["+std.fieldlist.size()+"]={";
213                 for(int i=0;i<std.fieldlist.size();i++) {
214                     FieldDescriptor fd = (FieldDescriptor)std.fieldlist.elementAt(i);
215                     if (fd.getPtr())
216                         str+="1";
217                     else
218                         str+="0";
219                     if ((i+1)!=std.fieldlist.size())
220                         str+=",";
221                 }
222                 str+="};";
223                 cr.outputline(str);
224             } else
225                 cr.outputline("int arisPtr"+ttd.getId()+"[1];"); // c doesn't like 0 length arrays
226         }
227         int max=TypeDescriptor.counter;
228         String str="int* arisPtr["+String.valueOf(max)+"]={";
229         for(int i=0;i<max;i++) {
230             str+="arisPtr"+i;
231             if (((i+1)!=max))
232                 str+=",";
233         }
234         str+="};";
235         cr.outputline(str);
236
237         cr.outputline("int isPtr(int type, int fieldindex) {");
238         cr.outputline("return arisPtr[type][fieldindex];");
239         cr.outputline("}");
240     }
241
242     void generateissubtype() {
243         int max=TypeDescriptor.counter;
244         String str="bool arissubtype["+max+"]["+max+"]={";
245         for(int i=0;i<max;i++) {
246             str+="{";
247             for(int j=0;j<max;j++) {
248                 TypeDescriptor tdi=tdarray[i];
249                 TypeDescriptor tdj=tdarray[j];
250                 if (tdi.isSubtypeOf(tdj))
251                     str+="1";
252                 else
253                     str+="0";
254                 if ((j+1)!=max)
255                     str+=",";
256             }
257             str+="}";
258             if ((i+1)!=max)
259                 str+=",";
260         }
261         str+="};";
262         cr.outputline(str);
263         cr.outputline("bool issubtype(int subtype, int type) {");
264         cr.outputline("return arissubtype[subtype][type];");
265         cr.outputline("}");
266     }
267 }