updates
[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 Descriptor getDescriptor() {
21         return relation;
22     }
23
24     public RelationDescriptor getRelation() {
25         return relation;
26     }
27
28     public Set getInversedRelations() {
29         return expr.getInversedRelations();
30     }
31
32     public Set getRequiredDescriptors() {
33         Set v = expr.getRequiredDescriptors();        
34         v.add(relation);
35         return v;
36     }
37
38     public boolean usesDescriptor(RelationDescriptor rd) {
39         if (rd==relation)
40             return true;
41         else
42             return expr.usesDescriptor(rd);
43     }
44
45     public void generate(CodeWriter cr, VarDescriptor dest) {
46         
47         String destname = dest.getSafeSymbol();
48         cr.outputline("int " + destname + ";");
49
50         // ok... destination is declared... we gotta expand this rule inplace... and instead of the inclusion we 
51         // set the destination in the guard ... otherwise maybe!
52         
53         VarDescriptor domain = VarDescriptor.makeNew("domain");
54         expr.generate(cr, domain);
55
56         cr.pushSymbolTable(rule.getSymbolTable());
57         cr.startblock(); {
58
59             // ok... symbol table is set up... lets bind that initial vardescriptor of the quantifier
60             SetQuantifier sq = ((SetQuantifier) rule.quantifiers().next());
61             VarDescriptor rulebinding = sq.getVar();
62             String tempvar = (VarDescriptor.makeNew("tempvar")).getSafeSymbol();
63             
64             // this is to be safe about name overlap because int t = t; sets t to 0!
65             cr.outputline("int " + tempvar + " = " + domain.getSafeSymbol() + ";");
66             cr.outputline("int " + rulebinding.getSafeSymbol() + " = " + tempvar + ";");
67             
68             /* pretty print! */
69             cr.outputline("// about to inbed relational function");
70             cr.output("// ");
71             rule.getGuardExpr().prettyPrint(cr);
72             cr.outputline("");
73             
74             /* now we have to generate the guard test */
75             VarDescriptor guardval = VarDescriptor.makeNew();
76             rule.getGuardExpr().generate(cr, guardval);
77             
78             cr.outputline("if (" + guardval.getSafeSymbol() + ")");
79             cr.startblock(); {
80                 
81                 /* now we have to generate the inclusion code */
82                 RelationInclusion ri = (RelationInclusion) rule.getInclusion();
83                 
84                 // basically, destname = righthandside<r, r.field>            
85                 VarDescriptor tempdest = VarDescriptor.makeNew("tempdest");
86                 Expr rhs = ri.getRightExpr();
87                 rhs.generate(cr, tempdest);
88                 
89                 cr.outputline(destname + " = " + tempdest.getSafeSymbol() + ";");
90                 
91             } cr.endblock();
92             cr.outputline("else");
93             cr.startblock(); {
94
95                 // three valued logic. if the relation (which is a partial function)
96                 // fails its guard, then we have a "maybe" condition, which must
97                 // propagate
98
99                 cr.outputline("maybe = 1;");
100
101             } cr.endblock();
102
103         } cr.endblock();
104
105     }
106
107     public void prettyPrint(PrettyPrinter pp) {
108         expr.prettyPrint(pp);
109         pp.output(".");
110         pp.output(relation.getSafeSymbol());
111     }
112
113     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
114         throw new IRException();
115     }
116
117 }