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 Expr getExpr() {
21 public boolean usesDescriptor(RelationDescriptor rd) {
25 return expr.usesDescriptor(rd);
28 public RelationDescriptor getRelation() {
32 public Descriptor getDescriptor() {
36 public boolean inverted() {
40 public Set getInversedRelations() {
41 Set set = expr.getInversedRelations();
48 public Set getRequiredDescriptors() {
49 Set v = expr.getRequiredDescriptors();
54 public void generate(CodeWriter writer, VarDescriptor dest) {
55 VarDescriptor domain = VarDescriptor.makeNew("domain");
56 String strinverse = inverse ? "inv" : "";
57 String found = (VarDescriptor.makeNew("found")).getSafeSymbol();
58 expr.generate(writer, domain);
59 writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + ";");
60 writer.outputline("int " + found + " = " + relation.getSafeSymbol() + "_hash" + strinverse + "->get(" + domain.getSafeSymbol() + ", " + dest.getSafeSymbol() + ");");
61 writer.outputline("if (!" + found + ") { maybe = 1; }");
64 // #TBD#: don't think this method is needed (or even called/referenced)
66 public void generate_set(CodeWriter writer, VarDescriptor dest) {
67 VarDescriptor domain = VarDescriptor.makeNew("domain");
68 expr.generate(writer, domain);
69 writer.outputline(relation.getRange().getType().getGenerateType().getSafeSymbol() + " " + dest.getSafeSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
73 public void prettyPrint(PrettyPrinter pp) {
81 pp.output(relation.getSafeSymbol());
84 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
86 TypeDescriptor type = expr.typecheck(sa);
92 /* check to make sure that the types of the relation match up */
94 TypeDescriptor rangetype = relation.getRange().getType();
96 if (rangetype != type) {
97 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
98 "' but must be '" + rangetype.getSymbol() +
99 "', the type of the range of the relation '" + relation.getSymbol() + "'");
103 this.td = relation.getDomain().getType();
105 } else { /* not inverse */
106 TypeDescriptor domaintype = relation.getDomain().getType();
108 if (domaintype != type) {
109 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
110 "' but must be '" + domaintype.getSymbol() +
111 "', the type of the domain of the relation '" + relation.getSymbol() + "'");
115 this.td = relation.getRange().getType();