model and checks
[repair.git] / Repair / RepairCompiler / MCC / IR / NaiveGenerator.java
1 package MCC.IR;
2
3 import java.io.*;
4 import java.util.*;
5 import MCC.State;
6
7 public class NaiveGenerator {
8
9     State state;
10     java.io.PrintWriter output = null;
11             
12     public NaiveGenerator(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_rules();
22         generate_implicit_checks();
23         generate_checks();
24
25     }
26
27     private void generate_tokentable() {
28
29         CodeWriter cr = new CodeWriter() {
30                 
31                 int indent = 0;
32                 public void indent() { indent++; }
33                 public void unindent() { indent--; assert indent >= 0; }
34                 private void doindent() {
35                     for (int i = 0; i < indent; i++) { 
36                         output.print("  ");
37                     }
38                 }
39                 public void outputline(String s) {
40                     doindent();
41                     output.println(s);
42                 }                                                             
43                 public void output(String s) { throw new IRException(); }
44                 public SymbolTable getSymbolTable() { throw new IRException(); }
45             };
46         
47         Iterator tokens = TokenLiteralExpr.tokens.keySet().iterator();        
48
49         cr.outputline("");
50         cr.outputline("// Token values");
51         cr.outputline("");
52
53         while (tokens.hasNext()) {
54             Object token = tokens.next();
55             cr.outputline("// " + token.toString() + " = " + TokenLiteralExpr.tokens.get(token).toString());            
56         }
57
58         cr.outputline("");
59         cr.outputline("");
60     }
61
62     private void generate_hashtables() {
63
64         CodeWriter cr = new CodeWriter() {
65                 
66                 int indent = 0;
67                 public void indent() { indent++; }
68                 public void unindent() { indent--; assert indent >= 0; }
69                 private void doindent() {
70                     for (int i = 0; i < indent; i++) { 
71                         output.print("  ");
72                     }
73                 }
74                 public void outputline(String s) {
75                     doindent();
76                     output.println(s);
77                 }                                                             
78                 public void output(String s) { throw new IRException(); }
79                 public SymbolTable getSymbolTable() { throw new IRException(); }
80             };
81
82         cr.outputline("int __Success = 1;");
83         
84         cr.outputline("// creating hashtables ");
85         
86         /* build all the hashtables */
87         Hashtable hashtables = new Hashtable();
88
89         /* build sets */
90         Iterator sets = state.stSets.descriptors();
91         
92         /* first pass create all the hash tables */
93         while (sets.hasNext()) {
94             SetDescriptor set = (SetDescriptor) sets.next();
95             cr.outputline("SimpleHash* " + set.getSafeSymbol() + "_hash = new SimpleHash();");
96         } 
97
98         /* second pass build relationships between hashtables */
99         sets = state.stSets.descriptors();
100         
101         while (sets.hasNext()) {
102             SetDescriptor set = (SetDescriptor) sets.next();
103             Iterator subsets = set.subsets();
104             
105             while (subsets.hasNext()) {
106                 SetDescriptor subset = (SetDescriptor) subsets.next();                
107                 cr.outputline(subset.getSafeSymbol() + "_hash->addParent(" + set.getSafeSymbol() + "_hash);");
108             }
109         } 
110
111         /* build relations */
112         Iterator relations = state.stRelations.descriptors();
113         
114         /* first pass create all the hash tables */
115         while (relations.hasNext()) {
116             RelationDescriptor relation = (RelationDescriptor) relations.next();
117             cr.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hash = new SimpleHash();");
118             cr.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hashinv = new SimpleHash();");
119         } 
120
121         cr.outputline("");
122         cr.outputline("");
123     }
124
125     private void generate_rules() {
126
127         /* first we must sort the rules */
128         GraphNode.DFS.depthFirstSearch(state.rulenodes.values());
129
130         TreeSet topologicalsort = new TreeSet(new Comparator() {
131                 public boolean equals(Object obj) { return false; }
132                 public int compare(Object o1, Object o2) {
133                     GraphNode g1 = (GraphNode) o1;
134                     GraphNode g2 = (GraphNode) o2;
135                     return g2.getFinishingTime() - g1.getFinishingTime();
136                 }
137             });
138         
139         topologicalsort.addAll(state.rulenodes.values());        
140
141         /* build all the rules */
142         Iterator rules = topologicalsort.iterator();
143                 
144         while (rules.hasNext()) {
145
146             GraphNode rulenode = (GraphNode) rules.next();
147             Rule rule = (Rule) rulenode.getOwner();            
148
149             {
150
151                 final SymbolTable st = rule.getSymbolTable();
152                 
153                 CodeWriter cr = new CodeWriter() {
154                         boolean linestarted = false;
155                         int indent = 0;
156                         public void indent() { indent++; }
157                         public void unindent() { indent--; assert indent >= 0; }
158                         private void doindent() {
159                             for (int i = 0; i < indent; i++) { 
160                                 output.print("  ");
161                             }
162                             linestarted = true;
163                         }
164                         public void outputline(String s) {
165                             if (!linestarted) {
166                                 doindent();
167                             }
168                             output.println(s);
169                             linestarted = false;
170                         }                 
171                         public void output(String s) {
172                             if (!linestarted) {
173                                 doindent();
174                             }
175                             output.print(s);
176                             output.flush(); 
177                         }
178                         public SymbolTable getSymbolTable() { return st; }
179                     };
180                 
181                 cr.outputline("// build " + rule.getLabel());
182                 cr.outputline("{");
183                 cr.indent();
184
185                 ListIterator quantifiers = rule.quantifiers();
186
187                 while (quantifiers.hasNext()) {
188                     Quantifier quantifier = (Quantifier) quantifiers.next();                   
189                     quantifier.generate_open(cr);
190                 }            
191                         
192                 /* pretty print! */
193                 cr.output("//");
194                 rule.getGuardExpr().prettyPrint(cr);
195                 cr.outputline("");
196
197                 /* now we have to generate the guard test */
198         
199                 VarDescriptor guardval = VarDescriptor.makeNew();
200                 rule.getGuardExpr().generate(cr, guardval);
201                 
202                 cr.outputline("if (" + guardval.getSafeSymbol() + ") {");
203
204                 cr.indent();
205
206                 /* now we have to generate the inclusion code */
207                 rule.getInclusion().generate(cr);
208
209                 cr.unindent();
210
211                 cr.outputline("}");
212
213                 while (quantifiers.hasPrevious()) {
214                     Quantifier quantifier = (Quantifier) quantifiers.previous();
215                     cr.unindent();                    
216                     cr.outputline("}");
217                 }
218
219                 cr.unindent();
220                 cr.outputline("}");
221                 cr.outputline("");
222                 cr.outputline("");
223             }
224         }
225     }
226
227     private void generate_implicit_checks() {
228
229         // #STOPPED# : stop... modify relationdescriptor with flag to symbolize that
230         // static analysis has determined the relation to be type safe... for sets that 
231         // are not type safe do these tests in the 
232         // relation inclusion...
233
234         /* do post checks */
235
236         // check to make sure all relations are well typed
237         // for all relations (need to check reverse as well i guess) 
238         // make sure that each element is in the corresponding set for the domain and range
239         // use iterators
240         
241         CodeWriter cr = new CodeWriter() {
242                 boolean linestarted = false;
243                 int indent = 0;
244                 public void indent() { indent++; }
245                 public void unindent() { indent--; assert indent >= 0; }
246                 private void doindent() {
247                     for (int i = 0; i < indent; i++) { 
248                         output.print("  ");
249                     }
250                     linestarted = true;
251                 }
252                 public void outputline(String s) {
253                     if (!linestarted) {
254                         doindent();
255                     }
256                     output.println(s);
257                     linestarted = false;
258                 }                 
259                 public void output(String s) {
260                     if (!linestarted) {
261                         doindent();
262                     }
263                     output.print(s);
264                     output.flush(); 
265                 }
266                 public SymbolTable getSymbolTable() { throw new IRException(); }
267             };
268           
269         /* build relations */
270         Iterator relations = state.stRelations.descriptors();
271
272         /* first pass create all the hash tables */
273         while (relations.hasNext()) {
274             RelationDescriptor relation = (RelationDescriptor) relations.next();
275
276             if (relation.testUsage(RelationDescriptor.IMAGE)) {
277                 VarDescriptor x = VarDescriptor.makeNew("x");
278                 VarDescriptor y = VarDescriptor.makeNew("y");
279
280                 /* start iteration */
281                 cr.outputline("for (SimpleIterator* " + x.getSafeSymbol() + "_iterator = " + relation.getSafeSymbol() + "_hash->iterator(); " + x.getSafeSymbol() + "_iterator->hasNext(); ) {");
282                 cr.indent();
283                 cr.outputline("int " + y.getSafeSymbol() + " = (" + x.getSafeSymbol() + "_iterator->next();");        
284                 cr.outputline("int " + x.getSafeSymbol() + " = (" + x.getSafeSymbol() + "_iterator->key();");
285
286                 SetDescriptor domain = relation.getDomain();
287                 SetDescriptor range = relation.getRange();
288
289                 // #TBD#: decide if this is bad and go back and do checks in relationinclusion.. (have flag set by static analysis which determines whether or not these tests need to be made or 
290                 // not
291
292                 cr.outputline("if (!domain.get(x)) { remove x from hashtable, remove current iterator }");
293                 
294             } else if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
295                 throw new IRException("unsupported");
296             }
297             
298            
299         } 
300
301         cr.outputline("");
302         cr.outputline("");
303
304                            
305         //output.println("check multiplicity");
306
307     }
308
309     private void generate_checks() {
310
311         /* do constraint checks */
312         Vector constraints = state.vConstraints;
313
314         for (int i = 0; i < constraints.size(); i++) {
315
316             Constraint constraint = (Constraint) constraints.elementAt(i); 
317
318             {
319
320                 final SymbolTable st = constraint.getSymbolTable();
321                 
322                 CodeWriter cr = new CodeWriter() {
323                         boolean linestarted = false;
324                         int indent = 0;
325                         public void indent() { indent++; }
326                         public void unindent() { indent--; assert indent >= 0; }
327                         private void doindent() {
328                             for (int i = 0; i < indent; i++) { 
329                                 output.print("  ");
330                             }
331                             linestarted = true;
332                         }
333                         public void outputline(String s) {
334                             if (!linestarted) {
335                                 doindent();
336                             }
337                             output.println(s);
338                             linestarted = false;
339                         }                 
340                         public void output(String s) {
341                             if (!linestarted) {
342                                 doindent();
343                             }
344                             output.print(s);
345                             output.flush(); 
346                         }
347                         public SymbolTable getSymbolTable() { return st; }
348                     };
349                 
350                 cr.outputline("// checking " + constraint.getLabel());
351                 cr.outputline("{");
352                 cr.indent();
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                 /* now we have to generate the guard test */
362         
363                 VarDescriptor constraintboolean = VarDescriptor.makeNew("constraintboolean");
364                 constraint.getLogicStatement().generate(cr, constraintboolean);
365                 
366                 cr.outputline("if (!" + constraintboolean.getSafeSymbol() + ") {");
367
368                 cr.indent();
369
370                 cr.outputline("__Success = 0;");
371                 cr.outputline("printf(\"fail. \");");
372
373                 cr.unindent();
374
375                 cr.outputline("}");
376
377                 while (quantifiers.hasPrevious()) {
378                     Quantifier quantifier = (Quantifier) quantifiers.previous();
379                     cr.unindent();                    
380                     cr.outputline("}");
381                 }
382
383                 cr.unindent();
384                 cr.outputline("}");
385                 cr.outputline("");
386                 cr.outputline("");
387             }
388             
389         }
390
391         output.println("if (__Success) { printf(\"all tests passed\"); }");
392     }    
393
394 }