5 public class RelationExpr extends Expr {
8 RelationDescriptor relation;
11 public Set getfunctions() {
12 HashSet functions=new HashSet();
13 Set exprfunctions=expr.getfunctions();
14 if (exprfunctions!=null)
15 functions.addAll(exprfunctions);
16 functions.add(new ConstraintDependence.Function(relation,expr.getSet(),inverse,this));
21 public SetDescriptor getSet() {
23 return relation.getDomain();
25 return relation.getRange();
28 public RelationExpr(Expr expr, RelationDescriptor relation, boolean inverse) {
30 this.relation = relation;
31 this.inverse = inverse;
34 public Set freeVars() {
35 return expr.freeVars();
38 public String name() {
39 String name=expr.name()+".";
42 name+=relation.toString();
46 public Expr getExpr() {
50 public boolean equals(Map remap, Expr e) {
51 if (e==null||!(e instanceof RelationExpr))
53 RelationExpr re=(RelationExpr)e;
54 if (re.relation!=relation)
56 if (!expr.equals(remap,re.expr))
58 if (inverse!=re.inverse)
63 public boolean usesDescriptor(Descriptor rd) {
67 return expr.usesDescriptor(rd);
70 public Set useDescriptor(Descriptor rd) {
71 HashSet newset=new HashSet();
74 newset.addAll(expr.useDescriptor(rd));
78 public RelationDescriptor getRelation() {
82 public Descriptor getDescriptor() {
86 public boolean inverted() {
90 public Set getInversedRelations() {
91 Set set = expr.getInversedRelations();
98 public Set getRequiredDescriptors() {
99 Set v = expr.getRequiredDescriptors();
104 public void generate(CodeWriter writer, VarDescriptor dest) {
105 VarDescriptor domain = VarDescriptor.makeNew("domain");
106 String strinverse = inverse ? "inv" : "";
107 String found = (VarDescriptor.makeNew("found")).getSafeSymbol();
108 expr.generate(writer, domain);
109 writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + ";");
110 writer.outputline("int " + found + " = " + relation.getSafeSymbol() + "_hash" + strinverse + "->get(" + domain.getSafeSymbol() + ", " + dest.getSafeSymbol() + ");");
111 writer.outputline("if (!" + found + ") { maybe = 1; }");
114 // #TBD#: don't think this method is needed (or even called/referenced)
116 public void generate_set(CodeWriter writer, VarDescriptor dest) {
117 VarDescriptor domain = VarDescriptor.makeNew("domain");
118 expr.generate(writer, domain);
119 writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
123 public void prettyPrint(PrettyPrinter pp) {
124 expr.prettyPrint(pp);
131 pp.output(relation.getSafeSymbol());
134 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
136 TypeDescriptor type = expr.typecheck(sa);
142 /* check to make sure that the types of the relation match up */
144 TypeDescriptor rangetype = relation.getRange().getType();
146 if (rangetype != type) {
147 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
148 "' but must be '" + rangetype.getSymbol() +
149 "', the type of the range of the relation '" + relation.getSymbol() + "'");
153 this.td = relation.getDomain().getType();
155 } else { /* not inverse */
156 TypeDescriptor domaintype = relation.getDomain().getType();
158 if (domaintype != type) {
159 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
160 "' but must be '" + domaintype.getSymbol() +
161 "', the type of the domain of the relation '" + relation.getSymbol() + "'");
165 this.td = relation.getRange().getType();