5 public class RelationInclusion extends Inclusion {
7 Expr leftelementexpr, rightelementexpr;
8 RelationDescriptor relation;
10 // #TBD#: this flag needs to be set by some static analysis
11 boolean typesafe = true;
13 public RelationInclusion(Expr leftelementexpr, Expr rightelementexpr, RelationDescriptor relation) {
14 this.leftelementexpr = leftelementexpr;
15 this.rightelementexpr = rightelementexpr;
16 this.relation = relation;
19 public Set getTargetDescriptors() {
20 HashSet v = new HashSet();
25 public Set getRequiredDescriptors() {
26 Set v = leftelementexpr.getRequiredDescriptors();
27 v.addAll(rightelementexpr.getRequiredDescriptors());
29 if (!typesafe) { /* if not typesafe then domain and range are needed to make typesafety checks! */
30 v.add(relation.getDomain());
31 v.add(relation.getRange());
37 public void generate(CodeWriter writer) {
38 VarDescriptor ld = VarDescriptor.makeNew("leftele");
39 leftelementexpr.generate(writer, ld);
40 VarDescriptor rd = VarDescriptor.makeNew("rightele");
41 rightelementexpr.generate(writer, rd);
43 /* typesafe checks! */
44 String typesafecheck = (VarDescriptor.makeNew("typesafecheck")).getSafeSymbol();
47 String check = "int " + typesafecheck + " = " ;
49 if (!(relation.getDomain() instanceof ReservedSetDescriptor)) {
50 check += relation.getDomain().getSafeSymbol() + "_hash->contains(" + ld.getSafeSymbol() + ") && ";
53 if (!(relation.getRange() instanceof ReservedSetDescriptor)) {
54 check += relation.getRange().getSafeSymbol() + "_hash->contains(" + rd.getSafeSymbol() + ") && ";
57 check += "1;"; // terminate boolean expression
59 writer.outputline(check);
60 writer.outputline("if (" + typesafecheck + ") {");
64 if (relation.testUsage(RelationDescriptor.IMAGE)) {
65 writer.outputline(relation.getSafeSymbol() + "_hash->add((int)" + ld.getSafeSymbol() + ", (int)" + rd.getSafeSymbol() + ");");
68 if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
69 writer.outputline(relation.getSafeSymbol() + "_hashinv->add((int)" + rd.getSafeSymbol() + ", (int)" + ld.getSafeSymbol() + ");");
74 writer.outputline("}");
77 //writer.outputline("printf(\"" + relation.getSafeSymbol() + " (add): <%d, %d>\\n\", " + ld.getSafeSymbol() + ", " + rd.getSafeSymbol() + ");");
80 public boolean typecheck(SemanticAnalyzer sa) {
81 TypeDescriptor ld = leftelementexpr.typecheck(sa);
82 TypeDescriptor rd = rightelementexpr.typecheck(sa);
84 if (ld == null || rd == null) {
90 /* #ATTN#: this check makes sure that the types match up,
91 a runtime check needs to made that the set relationships
94 if (ld != relation.getDomain().getType()) {
95 sa.getErrorReporter().report(null, "Type of left element '" + ld.getSymbol() + "' must match domain type '" + relation.getDomain().getType().getSymbol() + "'");
99 if (rd != relation.getRange().getType()) {
100 assert rd.getSymbol() != null;
101 assert relation.getRange().getType() != null : relation.getRange().getSymbol();
102 sa.getErrorReporter().report(null, "Type of right element '" + rd.getSymbol() + "' must match range type '" + relation.getRange().getType().getSymbol() + "'");