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