Checking in changes that:
[repair.git] / Repair / RepairCompiler / MCC / IR / ImageSetExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class ImageSetExpr extends SetExpr {
6     static final public boolean INVERSE=true;
7     VarDescriptor vd;
8     RelationDescriptor rd;
9     boolean inverse;
10     ImageSetExpr ise;
11     boolean isimageset=false;
12
13     public ImageSetExpr(boolean inverse, VarDescriptor vd, RelationDescriptor rd) {
14         this.vd = vd;
15         this.rd = rd;
16         this.inverse = inverse;
17     }
18
19     public ImageSetExpr(VarDescriptor vd, RelationDescriptor rd) {
20         this.vd = vd;
21         this.rd = rd;
22         this.inverse = false;
23     }
24
25     public ImageSetExpr(boolean inverse, ImageSetExpr ise, RelationDescriptor rd) {
26         this.ise = ise;
27         this.isimageset=true;
28         this.rd = rd;
29         this.inverse = inverse;
30     }
31
32     public ImageSetExpr(ImageSetExpr ise, RelationDescriptor rd) {
33         this.ise = ise;
34         this.isimageset=true;
35         this.rd = rd;
36         this.inverse = false;
37     }
38
39     public Set freeVars() {
40         HashSet hs=new HashSet();
41         hs.add(vd);
42         return hs;
43     }
44
45     public String name() {
46         String name="";
47         if (isimageset)
48             name+=ise.name();
49         else
50             name+=vd.toString()+".";
51         if (inverse)
52             name+="~";
53         name+=rd.toString();
54         return name;
55     }
56
57     public boolean equals(Map remap, Expr e) {
58         if (e==null||!(e instanceof ImageSetExpr))
59             return false;
60         ImageSetExpr ise2=(ImageSetExpr)e;
61         if (ise2.isimageset!=isimageset)
62             return false;
63         if (ise2.inverse!=inverse)
64             return false;
65         if (ise2.rd!=rd)
66             return false;
67
68         if (isimageset) {
69             return ise.equals(remap,ise2.ise);
70         } else {
71             VarDescriptor nvde=vd;
72             if (remap!=null&&remap.containsKey(nvde))
73                 nvde=(VarDescriptor)remap.get(nvde);
74             if (nvde!=ise2.vd)
75                 return false;
76             return true;
77         }
78     }
79
80     public boolean inverted() {
81         return inverse;
82     }
83
84     public VarDescriptor getVar() {
85         return vd;
86     }
87
88     public ImageSetExpr getImageSetExpr() {
89         return ise;
90     }
91
92     public RelationDescriptor getRelation() {
93         return rd;
94     }
95
96     public Descriptor getDescriptor() {
97         return rd;
98     }
99
100     public boolean usesDescriptor(Descriptor d) {
101         if (isimageset)
102             return d==rd||ise.usesDescriptor(d);
103         return (d==rd)||(d==vd);
104     }
105
106     public Set getInversedRelations() {
107         HashSet set = new HashSet();
108         if (inverse) {
109             set.add(rd);
110         }
111         return set;
112     }
113
114     public Set getRequiredDescriptors() {
115         HashSet v = new HashSet();
116         v.add(rd);
117         return v;
118     }
119
120     public void generate(CodeWriter writer, VarDescriptor dest) {
121         throw new IRException("not supported");
122     }
123
124     public void generate_inclusion(CodeWriter writer, VarDescriptor dest, VarDescriptor element) {
125         String hash = inverse ? "_hashinv, " : "_hash, " ;
126         if (!isimageset) {
127             writer.outputline("int " + dest.getSafeSymbol() + " = SimpleHashcontainskeydata(" + rd.getSafeSymbol() + hash + vd.getSafeSymbol() + ", " + element.getSafeSymbol() + ");");
128         } else {
129             VarDescriptor newset=VarDescriptor.makeNew("newset");
130             generate_set(writer,newset);
131             writer.outputline("int "+dest.getSafeSymbol()+"=SimpleHashcontainskey("+newset.getSafeSymbol()+","+element.getSafeSymbol()+");");
132             writer.outputline("delete "+newset.getSafeSymbol()+";");
133         }
134     }
135
136     public void generate_size(CodeWriter writer, VarDescriptor dest) {
137         assert dest != null;
138         assert rd != null;
139         if (!isimageset) {
140             String hash = inverse ? "_hashinv, " : "_hash, " ;
141             writer.outputline("int " + dest.getSafeSymbol() + " = SimpleHashcount(" + rd.getSafeSymbol() + hash + vd.getSafeSymbol() + ");");
142         } else {
143             VarDescriptor newset=VarDescriptor.makeNew("newset");
144             generate_set(writer,newset);
145             writer.outputline("int "+dest.getSafeSymbol()+"=SimpleHashcountset("+newset.getSafeSymbol()+");");
146             writer.outputline("delete "+newset.getSafeSymbol()+";");
147         }
148     }
149
150     public void generate_leftside(CodeWriter writer, VarDescriptor dest) {
151         if (!isimageset) {
152             writer.outputline(vd.getType().getGenerateType()+" "+dest.getSafeSymbol()+" = "+vd.getSafeSymbol()+";");
153         } else {
154             VarDescriptor iseset=VarDescriptor.makeNew("set");
155             ise.generate_set(writer,iseset);
156             writer.outputline("int "+dest.getSafeSymbol()+" = SimpleHashfirstkey("+iseset.getSafeSymbol()+");");
157             writer.outputline("delete "+iseset.getSafeSymbol()+";");
158         }
159     }
160
161     public void generate_set(CodeWriter writer, VarDescriptor dest) {
162         if (!isimageset) {
163             String hash = inverse ? "_hashinv, " : "_hash, " ;
164             writer.outputline("struct SimpleHash * "+dest.getSafeSymbol()+"=SimpleHashimageSet("+rd.getSafeSymbol()+hash+vd.getSafeSymbol()+");");
165         } else {
166             VarDescriptor iseset=VarDescriptor.makeNew("set");
167             ise.generate_set(writer,iseset);
168
169             VarDescriptor itvd=VarDescriptor.makeNew("iterator");
170             writer.outputline("struct SimpleIterator "+itvd.getSafeSymbol()+";");
171             writer.outputline("SimpleHashiterator("+iseset.getSafeSymbol()+",&"+itvd.getSafeSymbol()+");");
172
173             writer.outputline("struct SimpleHash *"+dest.getSafeSymbol()+"=allocateSimpleHash(10);");
174             writer.outputline("while (hasNext(&"+itvd.getSafeSymbol()+")) {");
175
176             VarDescriptor keyvd=VarDescriptor.makeNew("key");
177
178             writer.outputline("int "+keyvd.getSafeSymbol()+"=next(&"+itvd.getSafeSymbol()+");");
179             String hash = inverse ? "_hashinv, " : "_hash, " ;
180             VarDescriptor newset=VarDescriptor.makeNew("newset");
181             writer.outputline("SimpleHash * "+newset.getSafeSymbol()+"=SimpleHashimageSet("+rd.getSafeSymbol()+hash+keyvd.getSafeSymbol()+");");
182             writer.outputline("SimpleHashaddAll("+dest.getSafeSymbol()+", "+ newset.getSafeSymbol()+");");
183             writer.outputline("freeSimpleHash("+newset.getSafeSymbol()+");");
184             writer.outputline("}");
185             writer.outputline("freeSimpleHash("+iseset.getSafeSymbol()+");");
186         }
187     }
188
189     public void prettyPrint(PrettyPrinter pp) {
190         if (!isimageset)
191             pp.output(vd.toString());
192         else
193             ise.prettyPrint(pp);
194         pp.output(".");
195         if (inverse) {
196             pp.output("~");
197         }
198         pp.output(rd.toString());
199     }
200
201     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
202         throw new IRException("not supported");
203     }
204 }