5 public class RelationExpr extends Expr {
8 RelationDescriptor relation;
11 public RelationExpr(Expr expr, RelationDescriptor relation, boolean inverse) {
13 this.relation = relation;
14 this.inverse = inverse;
17 public Set freeVars() {
18 return expr.freeVars();
21 public String name() {
22 String name=expr.name()+".";
25 name+=relation.toString();
29 public Expr getExpr() {
33 public boolean equals(Map remap, Expr e) {
34 if (e==null||!(e instanceof RelationExpr))
36 RelationExpr re=(RelationExpr)e;
37 if (re.relation!=relation)
39 if (!expr.equals(remap,re.expr))
41 if (inverse!=re.inverse)
46 public boolean usesDescriptor(Descriptor rd) {
50 return expr.usesDescriptor(rd);
53 public RelationDescriptor getRelation() {
57 public Descriptor getDescriptor() {
61 public boolean inverted() {
65 public Set getInversedRelations() {
66 Set set = expr.getInversedRelations();
73 public Set getRequiredDescriptors() {
74 Set v = expr.getRequiredDescriptors();
79 public void generate(CodeWriter writer, VarDescriptor dest) {
80 VarDescriptor domain = VarDescriptor.makeNew("domain");
81 String strinverse = inverse ? "inv" : "";
82 String found = (VarDescriptor.makeNew("found")).getSafeSymbol();
83 expr.generate(writer, domain);
84 writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + ";");
85 writer.outputline("int " + found + " = " + relation.getSafeSymbol() + "_hash" + strinverse + "->get(" + domain.getSafeSymbol() + ", " + dest.getSafeSymbol() + ");");
86 writer.outputline("if (!" + found + ") { maybe = 1; }");
89 // #TBD#: don't think this method is needed (or even called/referenced)
91 public void generate_set(CodeWriter writer, VarDescriptor dest) {
92 VarDescriptor domain = VarDescriptor.makeNew("domain");
93 expr.generate(writer, domain);
94 writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
98 public void prettyPrint(PrettyPrinter pp) {
106 pp.output(relation.getSafeSymbol());
109 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
111 TypeDescriptor type = expr.typecheck(sa);
117 /* check to make sure that the types of the relation match up */
119 TypeDescriptor rangetype = relation.getRange().getType();
121 if (rangetype != type) {
122 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
123 "' but must be '" + rangetype.getSymbol() +
124 "', the type of the range of the relation '" + relation.getSymbol() + "'");
128 this.td = relation.getDomain().getType();
130 } else { /* not inverse */
131 TypeDescriptor domaintype = relation.getDomain().getType();
133 if (domaintype != type) {
134 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
135 "' but must be '" + domaintype.getSymbol() +
136 "', the type of the domain of the relation '" + relation.getSymbol() + "'");
140 this.td = relation.getRange().getType();