correct
[repair.git] / Repair / RepairCompiler / MCC / IR / TupleOfExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class TupleOfExpr extends Expr {
6
7     Expr left = null;
8     Expr right = null;
9     RelationDescriptor relation = null;
10
11     public Set freeVars() {
12         Set lset=left.freeVars();
13         Set rset=right.freeVars();
14         if (lset==null)
15             return rset;
16         if (rset!=null)
17             lset.addAll(rset);
18         return lset;
19     }
20
21     public TupleOfExpr(Expr left, Expr right, RelationDescriptor relation) {
22         if ((left == null) || (right == null) || (relation == null)) {
23             throw new NullPointerException();
24         }
25
26         this.left = left;
27         this.right = right;
28         this.relation = relation;
29     }
30
31     public String name() {
32         return "<"+left.name()+","+right.name()+"> in "+relation.toString();
33     }
34
35     public boolean usesDescriptor(Descriptor d) {
36         if (d==relation)
37             return true;
38         else
39             return left.usesDescriptor(d)||right.usesDescriptor(d);
40     }
41
42     public Set useDescriptor(Descriptor d) {
43         HashSet newset=new HashSet();
44         if (d==relation)
45             newset.add(this);
46         newset.addAll(left.useDescriptor(d));
47         newset.addAll(right.useDescriptor(d));
48         return newset;
49     }
50
51     public boolean equals(Map remap, Expr e) {
52         if (e==null||!(e instanceof TupleOfExpr))
53             return false;
54         TupleOfExpr toe=(TupleOfExpr)e;
55         if (!left.equals(remap,toe.left))
56             return false;
57         if (!right.equals(remap,toe.right))
58             return false;
59         if (relation!=toe.relation)
60             return false;
61         return true;
62     }
63
64     public Set getRequiredDescriptors() {
65         Set v = left.getRequiredDescriptors();
66         v.addAll(right.getRequiredDescriptors());
67         v.add(relation);
68         return v;
69     }
70
71     public void generate(CodeWriter writer, VarDescriptor dest) {
72         VarDescriptor ld = VarDescriptor.makeNew();
73         left.generate(writer, ld);
74
75         VarDescriptor rd = VarDescriptor.makeNew();
76         right.generate(writer, rd);
77
78         writer.addDeclaration("int", dest.getSafeSymbol());
79
80         writer.outputline(dest.getSafeSymbol() + " = SimpleHashcontainskeydata("
81                           +relation.getSafeSymbol() +"_hash, "+
82                           ld.getSafeSymbol() + ", " +
83                           rd.getSafeSymbol() + ");");
84     }
85
86     public void prettyPrint(PrettyPrinter pp) {
87         pp.output("<");
88         left.prettyPrint(pp);
89         pp.output(", ");
90         right.prettyPrint(pp);
91         pp.output("> in? " + relation.getSafeSymbol());
92     }
93
94     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
95         TypeDescriptor ld = left.typecheck(sa);
96         TypeDescriptor rd = right.typecheck(sa);
97
98         if (ld == null || rd == null) {
99             return null;
100         }
101
102         boolean ok = true;
103
104         if (ld != relation.getDomain().getType()) {
105             sa.getErrorReporter().report(null, "Type of left element '" + ld.getSymbol() + "' must match domain type '" + relation.getDomain().getType().getSymbol() + "'");
106             ok = false;
107         }
108
109         if (rd != relation.getRange().getType()) {
110             sa.getErrorReporter().report(null, "Type of right element '" + rd.getSymbol() + "' must match range type '" + relation.getRange().getType().getSymbol() + "'");
111             ok = false;
112         }
113
114         if (!ok) {
115             return null;
116         }
117
118         this.td = ReservedTypeDescriptor.INT;
119         return this.td;
120     }
121
122
123 }