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