Adding code to generate repair algorithms. Its not complete yet...
[repair.git] / Repair / RepairCompiler / MCC / IR / RepairGenerator.java
1 package MCC.IR;
2
3 import java.io.*;
4 import java.util.*;
5 import MCC.State;
6
7 public class RepairGenerator {
8
9     State state;
10     java.io.PrintWriter outputrepair = null;
11     java.io.PrintWriter outputaux = null;
12     java.io.PrintWriter outputhead = null;
13     String name="foo";
14     String headername;
15     public RepairGenerator(State state) {
16         this.state = state;
17     }
18
19     public void generate(OutputStream outputrepair, OutputStream outputaux,OutputStream outputhead, String st) {
20         this.outputrepair = new java.io.PrintWriter(outputrepair, true); 
21         this.outputaux = new java.io.PrintWriter(outputaux, true); 
22         this.outputhead = new java.io.PrintWriter(outputhead, true); 
23         headername=st;
24
25         generate_tokentable();
26         generate_hashtables();
27         generate_stateobject();
28         generate_call();
29         /*        generate_worklist();
30         generate_rules();
31         generate_checks();
32         generate_teardown();*/
33
34     }
35
36     private void generate_call() {
37         CodeWriter cr = new StandardCodeWriter(outputrepair);        
38         VarDescriptor vdstate=VarDescriptor.makeNew("repairstate");
39         cr.outputline(name+"_state * "+vdstate.getSafeSymbol()+"=new "+name+"_state();");
40         
41
42         Iterator globals=state.stGlobals.descriptors();
43         while (globals.hasNext()) {
44             VarDescriptor vd=(VarDescriptor) globals.next();
45             cr.outputline(vdstate.getSafeSymbol()+"->"+vd.getSafeSymbol()+"=("+vd.getType().getGenerateType().getSafeSymbol()+")"+vd.getSafeSymbol()+";");
46         }
47         /* Insert repair here */
48
49         globals=state.stGlobals.descriptors();
50         while (globals.hasNext()) {
51             VarDescriptor vd=(VarDescriptor) globals.next();
52             cr.outputline("*(("+vd.getType().getGenerateType().getSafeSymbol()+"*) &"+vd.getSafeSymbol()+")="+vdstate.getSafeSymbol()+"->"+vd.getSafeSymbol()+";");
53         }
54         
55         cr.outputline("delete ("+vdstate.getSafeSymbol()+");");
56     }
57     private void generate_tokentable() {
58
59         CodeWriter cr = new StandardCodeWriter(outputrepair);        
60         Iterator tokens = TokenLiteralExpr.tokens.keySet().iterator();        
61
62         cr.outputline("");
63         cr.outputline("// Token values");
64         cr.outputline("");
65
66         while (tokens.hasNext()) {
67             Object token = tokens.next();
68             cr.outputline("// " + token.toString() + " = " + TokenLiteralExpr.tokens.get(token).toString());            
69         }
70
71         cr.outputline("");
72         cr.outputline("");
73     }
74
75     private void generate_stateobject() {
76         CodeWriter crhead = new StandardCodeWriter(outputhead);
77         crhead.outputline("class "+name+"_state {");
78         crhead.outputline("public:");
79         Iterator globals=state.stGlobals.descriptors();
80         while (globals.hasNext()) {
81             VarDescriptor vd=(VarDescriptor) globals.next();
82             crhead.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+";");
83         }
84     }
85
86     private void generate_hashtables() {
87         CodeWriter craux = new StandardCodeWriter(outputaux);
88         CodeWriter crhead = new StandardCodeWriter(outputhead);
89         crhead.outputline("#include \"SimpleHash.h\"");
90         crhead.outputline("class "+name+" {");
91         crhead.outputline("public:");
92         crhead.outputline(name+"();");
93         crhead.outputline("~"+name+"();");
94         craux.outputline("#include \""+headername+"\"");
95
96         craux.outputline(name+"::"+name+"() {");
97         craux.outputline("// creating hashtables ");
98         
99         /* build sets */
100         Iterator sets = state.stSets.descriptors();
101         
102         /* first pass create all the hash tables */
103         while (sets.hasNext()) {
104             SetDescriptor set = (SetDescriptor) sets.next();
105             crhead.outputline("SimpleHash* " + set.getSafeSymbol() + "_hash;");
106             craux.outputline(set.getSafeSymbol() + "_hash = new SimpleHash();");
107         } 
108         
109         /* second pass build relationships between hashtables */
110         sets = state.stSets.descriptors();
111         
112         while (sets.hasNext()) {
113             SetDescriptor set = (SetDescriptor) sets.next();
114             Iterator subsets = set.subsets();
115             
116             while (subsets.hasNext()) {
117                 SetDescriptor subset = (SetDescriptor) subsets.next();                
118                 craux.outputline(subset.getSafeSymbol() + "_hash->addParent(" + set.getSafeSymbol() + "_hash);");
119             }
120         } 
121
122         /* build relations */
123         Iterator relations = state.stRelations.descriptors();
124         
125         /* first pass create all the hash tables */
126         while (relations.hasNext()) {
127             RelationDescriptor relation = (RelationDescriptor) relations.next();
128             
129             if (relation.testUsage(RelationDescriptor.IMAGE)) {
130                 crhead.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hash;");
131                 craux.outputline(relation.getSafeSymbol() + "_hash = new SimpleHash();");
132             }
133
134             if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
135                 crhead.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hashinv;");
136                 craux.outputline(relation.getSafeSymbol() + "_hashinv = new SimpleHash();");
137             } 
138         }
139
140         craux.outputline("}");
141         crhead.outputline("};");
142         craux.outputline(name+"::~"+name+"() {");
143         craux.outputline("// deleting hashtables");
144
145         /* build destructor */
146         sets = state.stSets.descriptors();
147         
148         /* first pass create all the hash tables */
149         while (sets.hasNext()) {
150             SetDescriptor set = (SetDescriptor) sets.next();
151             craux.outputline("delete("+set.getSafeSymbol() + "_hash);");
152         } 
153         
154         /* destroy relations */
155         relations = state.stRelations.descriptors();
156         
157         /* first pass create all the hash tables */
158         while (relations.hasNext()) {
159             RelationDescriptor relation = (RelationDescriptor) relations.next();
160             
161             if (relation.testUsage(RelationDescriptor.IMAGE)) {
162                 craux.outputline("delete("+relation.getSafeSymbol() + "_hash);");
163             }
164
165             if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
166                 craux.outputline("delete(" + relation.getSafeSymbol() + ");");
167             } 
168         }
169         craux.outputline("}");
170     }
171
172     private void generate_worklist() {
173         CodeWriter cr = new StandardCodeWriter(outputrepair);
174         cr.outputline("WORKLIST = new WorkList();");
175     }
176     
177     private void generate_teardown() {
178         CodeWriter cr = new StandardCodeWriter(outputrepair);        
179         cr.outputline("delete WORKLIST;");
180     }
181
182     private void generate_rules() {
183         
184         /* first we must sort the rules */
185         Iterator allrules = state.vRules.iterator();
186
187         Vector emptyrules = new Vector(); // rules with no quantifiers
188         Vector worklistrules = new Vector(); // the rest of the rules
189
190         while (allrules.hasNext()) {
191             Rule rule = (Rule) allrules.next();
192             ListIterator quantifiers = rule.quantifiers();
193
194             boolean noquantifiers = true;
195             while (quantifiers.hasNext()) {
196                 Quantifier quantifier = (Quantifier) quantifiers.next();
197                 if (quantifier instanceof ForQuantifier) {
198                     // ok, because integers exist already!
199                 } else {
200                     // real quantifier
201                     noquantifiers = false;
202                     break;
203                 }
204             }
205
206             if (noquantifiers) {
207                 emptyrules.add(rule);
208             } else {
209                 worklistrules.add(rule);
210             }
211         }
212        
213         Iterator iterator_er = emptyrules.iterator();
214         while (iterator_er.hasNext()) {
215
216             Rule rule = (Rule) iterator_er.next();            
217
218             {
219                 final SymbolTable st = rule.getSymbolTable();                
220                 CodeWriter cr = new StandardCodeWriter(outputrepair) {
221                         public SymbolTable getSymbolTable() { return st; }
222                     };
223                 
224                 cr.outputline("// build " + rule.getLabel());
225                 cr.startblock();
226
227                 ListIterator quantifiers = rule.quantifiers();
228
229                 while (quantifiers.hasNext()) {
230                     Quantifier quantifier = (Quantifier) quantifiers.next();                   
231                     quantifier.generate_open(cr);
232                 }            
233                         
234                 /* pretty print! */
235                 cr.output("//");
236                 rule.getGuardExpr().prettyPrint(cr);
237                 cr.outputline("");
238
239                 /* now we have to generate the guard test */
240         
241                 VarDescriptor guardval = VarDescriptor.makeNew();
242                 rule.getGuardExpr().generate(cr, guardval);
243                 
244                 cr.outputline("if (" + guardval.getSafeSymbol() + ")");
245                 cr.startblock();
246
247                 /* now we have to generate the inclusion code */
248                 rule.getInclusion().generate(cr);
249                 cr.endblock();
250
251                 while (quantifiers.hasPrevious()) {
252                     Quantifier quantifier = (Quantifier) quantifiers.previous();
253                     cr.endblock();
254                 }
255
256                 cr.endblock();
257                 cr.outputline("");
258                 cr.outputline("");
259             }
260         }
261
262         CodeWriter cr2 = new StandardCodeWriter(outputrepair);        
263
264         cr2.outputline("WORKLIST->reset();");
265         cr2.outputline("while (WORKLIST->hasMoreElements())");
266         cr2.startblock();
267         cr2.outputline("WORKITEM *wi = (WORKITEM *) WORKLIST->nextElement();");
268         
269         String elseladder = "if";
270
271         Iterator iterator_rules = worklistrules.iterator();
272         while (iterator_rules.hasNext()) {
273             
274             Rule rule = (Rule) iterator_rules.next();            
275             int dispatchid = rule.getNum();
276
277             {
278                 final SymbolTable st = rule.getSymbolTable();                
279                 CodeWriter cr = new StandardCodeWriter(outputrepair) {
280                         public SymbolTable getSymbolTable() { return st; }
281                     };
282
283                 cr.indent();
284                 cr.outputline(elseladder + " (wi->id == " + dispatchid + ")");
285                 cr.startblock();
286
287                 cr.outputline("// build " + rule.getLabel());
288
289                 ListIterator quantifiers = rule.quantifiers();
290
291                 int count = 0;
292                 while (quantifiers.hasNext()) {
293                     Quantifier quantifier = (Quantifier) quantifiers.next();
294                     count = quantifier.generate_worklistload(cr, count );                    
295                 }
296                         
297                 /* pretty print! */
298                 cr.output("//");
299                 rule.getGuardExpr().prettyPrint(cr);
300                 cr.outputline("");
301
302                 /* now we have to generate the guard test */
303         
304                 VarDescriptor guardval = VarDescriptor.makeNew();
305                 rule.getGuardExpr().generate(cr, guardval);
306                 
307                 cr.outputline("if (" + guardval.getSafeSymbol() + ")");
308                 cr.startblock();
309
310                 /* now we have to generate the inclusion code */
311                 rule.getInclusion().generate(cr);
312                 cr.endblock();
313
314                 // close startblocks generated by DotExpr memory checks
315                 //DotExpr.generate_memory_endblocks(cr);                
316
317                 cr.endblock(); // end else-if WORKLIST ladder
318
319                 elseladder = "else if";
320             }
321         }
322
323         cr2.outputline("else");
324         cr2.startblock();
325         cr2.outputline("printf(\"VERY BAD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\\n\\n\");");
326         cr2.outputline("exit(1);");
327         cr2.endblock();
328
329         // end block created for worklist
330         cr2.endblock();
331
332     }
333
334     private void generate_checks() {
335
336         /* do constraint checks */
337         Vector constraints = state.vConstraints;
338
339         for (int i = 0; i < constraints.size(); i++) {
340
341             Constraint constraint = (Constraint) constraints.elementAt(i); 
342
343             {
344
345                 final SymbolTable st = constraint.getSymbolTable();
346                 
347                 CodeWriter cr = new StandardCodeWriter(outputrepair) {
348                         public SymbolTable getSymbolTable() { return st; }
349                     };
350                 
351                 cr.outputline("// checking " + constraint.getLabel());
352                 cr.startblock();
353
354                 ListIterator quantifiers = constraint.quantifiers();
355
356                 while (quantifiers.hasNext()) {
357                     Quantifier quantifier = (Quantifier) quantifiers.next();                   
358                     quantifier.generate_open(cr);
359                 }            
360
361                 cr.outputline("int maybe = 0;");
362                         
363                 /* now we have to generate the guard test */
364         
365                 VarDescriptor constraintboolean = VarDescriptor.makeNew("constraintboolean");
366                 constraint.getLogicStatement().generate(cr, constraintboolean);
367                 
368                 cr.outputline("if (maybe)");
369                 cr.startblock();
370                 cr.outputline("__Success = 0;");
371                 cr.outputline("printf(\"maybe fail " + (i+1) + ". \");");
372                 cr.outputline("exit(1);");
373                 cr.endblock();
374
375                 cr.outputline("else if (!" + constraintboolean.getSafeSymbol() + ")");
376                 cr.startblock();
377
378                 cr.outputline("__Success = 0;");
379                 cr.outputline("printf(\"fail " + (i+1) + ". \");");
380                 cr.outputline("exit(1);");
381                 cr.endblock();
382
383                 while (quantifiers.hasPrevious()) {
384                     Quantifier quantifier = (Quantifier) quantifiers.previous();
385                     cr.endblock();
386                 }
387
388                 cr.endblock();
389                 cr.outputline("");
390                 cr.outputline("");
391             }
392             
393         }
394
395         outputrepair.println("// if (__Success) { printf(\"all tests passed\"); }");
396     }    
397
398 }
399
400
401