9f795e281c34971a6e6f765e73d5faba0bbff38c
[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         String strinverse = inverse ? "inv" : "";
26         String found = (VarDescriptor.makeNew("found")).getSafeSymbol();
27         expr.generate(writer, domain);
28         writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + ";");
29         writer.outputline("int " + found + " = " + relation.getSafeSymbol() + "_hash" + strinverse + "->get(" + domain.getSafeSymbol() + ", " + dest.getSafeSymbol() + ");");
30         writer.outputline("if (!" + found + ") { maybe = 1; }");
31     }
32
33     // #TBD#: don't think this method is needed (or even called/referenced)
34     /*
35       public void generate_set(CodeWriter writer, VarDescriptor dest) {
36       VarDescriptor domain = VarDescriptor.makeNew("domain");
37       expr.generate(writer, domain);
38       writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
39       }
40     */
41
42     public void prettyPrint(PrettyPrinter pp) {
43         expr.prettyPrint(pp);
44         pp.output(".");
45         
46         if (inverse) {
47             pp.output("~");
48         }
49
50         pp.output(relation.getSafeSymbol());
51     }
52
53     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
54
55         TypeDescriptor type = expr.typecheck(sa);
56         
57         if (type == null) {
58             return null;
59         }
60
61         /* check to make sure that the types of the relation match up */
62         if (inverse) {
63             TypeDescriptor rangetype = relation.getRange().getType();
64             
65             if (rangetype != type) {
66                 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
67                                     "' but must be '" + rangetype.getSymbol() + 
68                                     "', the type of the range of the relation '" + relation.getSymbol() + "'");
69                 return null;
70             }
71             
72             this.td = relation.getDomain().getType();
73             return this.td;
74         } else { /* not inverse */
75             TypeDescriptor domaintype = relation.getDomain().getType();
76             
77             if (domaintype != type) {
78                 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
79                                     "' but must be '" + domaintype.getSymbol() + 
80                                     "', the type of the domain of the relation '" + relation.getSymbol() + "'");
81                 return null;
82             }
83
84             this.td = relation.getRange().getType();
85             return this.td;
86         }
87     }
88
89 }