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