b966628be324d52be7701c935b1172ed867a7d02
[repair.git] / Repair / RepairCompiler / MCC / IR / RelationExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class RelationExpr extends Expr {
6
7     Expr expr;
8     RelationDescriptor relation;
9     boolean inverse;
10
11     public RelationExpr(Expr expr, RelationDescriptor relation, boolean inverse) {
12         this.expr = expr;
13         this.relation = relation;
14         this.inverse = inverse;
15     }
16
17     public Set getRequiredDescriptors() {
18         Set v = expr.getRequiredDescriptors();        
19         v.add(relation);
20         return v;
21     }
22
23     public void generate(CodeWriter writer, VarDescriptor dest) {
24         VarDescriptor domain = VarDescriptor.makeNew("domain");
25         expr.generate(writer, domain);
26         writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
27     }
28
29     public void generate_set(CodeWriter writer, VarDescriptor dest) {
30         VarDescriptor domain = VarDescriptor.makeNew("domain");
31         expr.generate(writer, domain);
32         writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
33     }
34
35     public void prettyPrint(PrettyPrinter pp) {
36         expr.prettyPrint(pp);
37         pp.output(".");
38         
39         if (inverse) {
40             pp.output("~");
41         }
42
43         pp.output(relation.getSafeSymbol());
44     }
45
46     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
47
48         TypeDescriptor type = expr.typecheck(sa);
49         
50         if (type == null) {
51             return null;
52         }
53
54         /* check to make sure that the types of the relation match up */
55         if (inverse) {
56             TypeDescriptor rangetype = relation.getRange().getType();
57             
58             if (rangetype != type) {
59                 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
60                                     "' but must be the '" + rangetype.getSymbol() + 
61                                     "', the type of the range of the relation '" + relation.getSymbol() + "'");
62                 return null;
63             }
64             
65             this.td = relation.getDomain().getType();
66             return this.td;
67         } else { /* not inverse */
68             TypeDescriptor domaintype = relation.getDomain().getType();
69             
70             if (domaintype != type) {
71                 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
72                                     "' but must be the '" + domaintype.getSymbol() + 
73                                     "', the type of the range of the relation '" + relation.getSymbol() + "'");
74                 return null;
75             }
76
77             this.td = relation.getRange().getType();
78             return this.td;
79         }
80     }
81
82 }