heh
[repair.git] / Repair / RepairCompiler / MCC / IR / RelationFunctionExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class RelationFunctionExpr extends Expr {
6
7     // #WHAT I WAS DOING: about to define relationfunctionexpr thich should take a expr, relation and rule and generated
8     // the functional value or "maybe" if not there!
9
10     Expr expr;
11     RelationDescriptor relation;
12     Rule rule;
13
14     public RelationFunctionExpr(Expr expr, RelationDescriptor relation, Rule rule) {
15         this.expr = expr;
16         this.relation = relation;
17         this.rule = rule;
18     }
19
20     public RelationDescriptor getRelation() {
21         return relation;
22     }
23
24     public Set getInversedRelations() {
25         return expr.getInversedRelations();
26     }
27
28     public Set getRequiredDescriptors() {
29         Set v = expr.getRequiredDescriptors();        
30         v.add(relation);
31         return v;
32     }
33
34     public void generate(CodeWriter cr, VarDescriptor dest) {
35         
36         String destname = dest.getSafeSymbol();
37         cr.outputline("int " + destname + ";");
38
39         // ok... destination is declared... we gotta expand this rule inplace... and instead of the inclusion we 
40         // set the destination in the guard ... otherwise maybe!
41         
42         VarDescriptor domain = VarDescriptor.makeNew("domain");
43         expr.generate(cr, domain);
44
45         cr.pushSymbolTable(rule.getSymbolTable());
46         cr.startblock(); {
47
48             // ok... symbol table is set up... lets bind that initial vardescriptor of the quantifier
49             SetQuantifier sq = ((SetQuantifier) rule.quantifiers().next());
50             VarDescriptor rulebinding = sq.getVar();
51             String tempvar = (VarDescriptor.makeNew("tempvar")).getSafeSymbol();
52             
53             // this is to be safe about name overlap because int t = t; sets t to 0!
54             cr.outputline("int " + tempvar + " = " + domain.getSafeSymbol() + ";");
55             cr.outputline("int " + rulebinding.getSafeSymbol() + " = " + tempvar + ";");
56             
57             /* pretty print! */
58             cr.outputline("// about to inbed relational function");
59             cr.output("// ");
60             rule.getGuardExpr().prettyPrint(cr);
61             cr.outputline("");
62             
63             /* now we have to generate the guard test */
64             VarDescriptor guardval = VarDescriptor.makeNew();
65             rule.getGuardExpr().generate(cr, guardval);
66             
67             cr.outputline("if (" + guardval.getSafeSymbol() + ")");
68             cr.startblock(); {
69                 
70                 /* now we have to generate the inclusion code */
71                 RelationInclusion ri = (RelationInclusion) rule.getInclusion();
72                 
73                 // basically, destname = righthandside<r, r.field>            
74                 VarDescriptor tempdest = VarDescriptor.makeNew("tempdest");
75                 Expr rhs = ri.getRightExpr();
76                 rhs.generate(cr, tempdest);
77                 
78                 cr.outputline(destname + " = " + tempdest.getSafeSymbol() + ";");
79                 
80             } cr.endblock();
81             cr.outputline("else");
82             cr.startblock(); {
83
84                 // three valued logic. if the relation (which is a partial function)
85                 // fails its guard, then we have a "maybe" condition, which must
86                 // propagate
87
88                 cr.outputline("maybe = 1;");
89
90             } cr.endblock();
91
92         } cr.endblock();
93
94     }
95
96     public void prettyPrint(PrettyPrinter pp) {
97         expr.prettyPrint(pp);
98         pp.output(".");
99         pp.output(relation.getSafeSymbol());
100     }
101
102     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
103         throw new IRException();
104     }
105
106 }