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;
12 public static boolean worklist = false;
14 public RelationInclusion(Expr leftelementexpr, Expr rightelementexpr, RelationDescriptor relation) {
15 this.leftelementexpr = leftelementexpr;
16 this.rightelementexpr = rightelementexpr;
17 this.relation = relation;
20 public String toString() {
21 String str="<"+leftelementexpr.name()+","+rightelementexpr.name()+"> in "+relation.toString();
25 public boolean usesDescriptor(Descriptor d) {
29 return(leftelementexpr.usesDescriptor(d)
30 ||rightelementexpr.usesDescriptor(d));
33 public Expr getLeftExpr() {
34 return leftelementexpr;
37 public Expr getRightExpr() {
38 return rightelementexpr;
41 public RelationDescriptor getRelation() {
45 public Set getTargetDescriptors() {
46 HashSet v = new HashSet();
51 public Set getRequiredDescriptors() {
52 Set v = leftelementexpr.getRequiredDescriptors();
53 v.addAll(rightelementexpr.getRequiredDescriptors());
55 if (!typesafe) { /* if not typesafe then domain and range are needed to make typesafety checks! */
56 v.add(relation.getDomain());
57 v.add(relation.getRange());
63 public void generate(CodeWriter writer) {
64 VarDescriptor ld = VarDescriptor.makeNew("leftele");
65 leftelementexpr.generate(writer, ld);
66 VarDescriptor rd = VarDescriptor.makeNew("rightele");
67 rightelementexpr.generate(writer, rd);
69 /* typesafe checks! */
70 String typesafecheck = (VarDescriptor.makeNew("typesafecheck")).getSafeSymbol();
73 String check = "int " + typesafecheck + " = " ;
75 if (!(relation.getDomain() instanceof ReservedSetDescriptor)) {
76 check += "SimpleHashcontainskey("+relation.getDomain().getSafeSymbol() + "_hash, "+ld.getSafeSymbol() + ") && ";
79 if (!(relation.getRange() instanceof ReservedSetDescriptor)) {
80 check += "SimpleHashcontainskey("+relation.getRange().getSafeSymbol() +"_hash, "+ rd.getSafeSymbol() + ") && ";
83 check += "1;"; // terminate boolean expression
85 writer.outputline(check);
86 writer.outputline("if (" + typesafecheck + ")");
90 String addeditem = (VarDescriptor.makeNew("addeditem")).getSafeSymbol();
91 Repair.generate_dispatch(writer, relation, ld.getSafeSymbol(), rd.getSafeSymbol());
93 if (RelationInclusion.worklist) {
94 writer.outputline("if (" + addeditem + ")");
95 writer.startblock(); {
96 WorkList.generate_dispatch(writer, relation, rd.getSafeSymbol(), ld.getSafeSymbol());
105 //writer.outputline("printf(\"" + relation.getSafeSymbol() + " (add): <%d, %d>\\n\", " + ld.getSafeSymbol() + ", " + rd.getSafeSymbol() + ");");
108 public boolean typecheck(SemanticAnalyzer sa) {
109 TypeDescriptor ld = leftelementexpr.typecheck(sa);
110 TypeDescriptor rd = rightelementexpr.typecheck(sa);
112 if (ld == null || rd == null) {
118 /* #ATTN#: this check makes sure that the types match up,
119 a runtime check needs to made that the set relationships
122 if (ld != relation.getDomain().getType()) {
123 sa.getErrorReporter().report(null, "Type of left element '" + ld.getSymbol() + "' must match domain type '" + relation.getDomain().getType().getSymbol() + "'");
127 if (rd != relation.getRange().getType()) {
128 assert rd.getSymbol() != null;
129 assert relation.getRange().getType() != null : relation.getRange().getSymbol();
130 sa.getErrorReporter().report(null, "Type of right element '" + rd.getSymbol() + "' must match range type '" + relation.getRange().getType().getSymbol() + "'");