5 public class RelationExpr extends Expr {
7 // #TBD#: right now i'm not sure if this is the best way to organize the relationexpr... it may be better
8 // to have one class represent each a.B.B'.B'' expression with a VarDescriptor for the a and a vector
10 RelationExpr subdomain;
13 RelationDescriptor relation;
16 public RelationExpr() {
18 this.subdomain = null;
23 public RelationExpr(RelationExpr subdomain) {
24 this.subdomain = subdomain;
30 public void setRelation(RelationDescriptor rd, boolean inverse) {
32 this.inverse = inverse;
35 public void setDomain(VarDescriptor vd) {
39 public Set getRequiredDescriptors() {
40 HashSet v = new HashSet();
42 if (subdomain != null) {
43 v.addAll(subdomain.getRequiredDescriptors());
48 public void generate(CodeWriter writer, VarDescriptor dest) {
49 if (domain != null) { /* base case */
50 writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.getFirst(" + domain.getSafeSymbol() + ");");
52 VarDescriptor ld = VarDescriptor.makeNew();
53 subdomain.generate(writer, ld);
54 writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.getFirst(" + ld.getSafeSymbol() + ");");
59 public void generate_set(CodeWriter writer, VarDescriptor dest) {
60 if (domain != null) { /* base case */
61 writer.outputline("Set " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.get(" + domain.getSafeSymbol() + ");");
63 VarDescriptor ld = VarDescriptor.makeNew();
64 subdomain.generate(writer, ld);
65 writer.outputline("Set " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash.get(" + domain.getSafeSymbol() + ");");
69 public void prettyPrint(PrettyPrinter pp) {
70 if (subdomain != null) {
71 subdomain.prettyPrint(pp);
73 pp.output(domain.getSafeSymbol());
82 pp.output(relation.getSafeSymbol());
85 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
86 TypeDescriptor type = null;
89 type = domain.getType();
91 type = subdomain.typecheck(sa);
98 /* check to make sure that the types of the relation match up */
100 TypeDescriptor rangetype = relation.getRange().getType();
102 if (rangetype != type) {
103 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
104 "' but must be the '" + rangetype.getSymbol() +
105 "', the type of the range of the relation '" + relation.getSymbol() + "'");
109 this.td = relation.getDomain().getType();
111 } else { /* not inverse */
112 TypeDescriptor domaintype = relation.getDomain().getType();
114 if (domaintype != type) {
115 sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
116 "' but must be the '" + domaintype.getSymbol() +
117 "', the type of the range of the relation '" + relation.getSymbol() + "'");
121 this.td = relation.getRange().getType();