a6d2f1a8fb6bd82a8949362494b03bfe77bdcbc5
[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.addDeclaration("int", dest.getSafeSymbol());
128             writer.outputline(dest.getSafeSymbol() + " = SimpleHashcontainskeydata(" + rd.getSafeSymbol() + hash + vd.getSafeSymbol() + ", " + element.getSafeSymbol() + ");");
129         } else {
130             VarDescriptor newset=VarDescriptor.makeNew("newset");
131             generate_set(writer,newset);
132             writer.addDeclaration("int", dest.getSafeSymbol());
133             writer.outputline(dest.getSafeSymbol()+"=SimpleHashcontainskey("+newset.getSafeSymbol()+","+element.getSafeSymbol()+");");
134             writer.outputline("freeSimpleHash("+newset.getSafeSymbol()+");");
135         }
136     }
137
138     public void generate_size(CodeWriter writer, VarDescriptor dest) {
139         assert dest != null;
140         assert rd != null;
141         if (!isimageset) {
142             String hash = inverse ? "_hashinv, " : "_hash, " ;
143             writer.addDeclaration("int", dest.getSafeSymbol());
144             writer.outputline(dest.getSafeSymbol() + " = SimpleHashcount(" + rd.getSafeSymbol() + hash + vd.getSafeSymbol() + ");");
145         } else {
146             VarDescriptor newset=VarDescriptor.makeNew("newset");
147             generate_set(writer,newset);
148             writer.addDeclaration("int", dest.getSafeSymbol());
149             writer.outputline(dest.getSafeSymbol()+"=SimpleHashcountset("+newset.getSafeSymbol()+");");
150             writer.outputline("freeSimpleHash("+newset.getSafeSymbol()+");");
151         }
152     }
153
154     public void generate_leftside(CodeWriter writer, VarDescriptor dest) {
155         if (!isimageset) {
156             writer.addDeclaration(vd.getType().getGenerateType().toString(), dest.getSafeSymbol());
157             writer.outputline(dest.getSafeSymbol()+" = "+vd.getSafeSymbol()+";");
158         } else {
159             VarDescriptor iseset=VarDescriptor.makeNew("set");
160             ise.generate_set(writer,iseset);
161             writer.addDeclaration("int",dest.getSafeSymbol());
162             writer.outputline(dest.getSafeSymbol()+" = SimpleHashfirstkey("+iseset.getSafeSymbol()+");");
163             writer.outputline("freeSimpleHash("+iseset.getSafeSymbol()+");");
164         }
165     }
166
167     public void generate_set(CodeWriter writer, VarDescriptor dest) {
168         if (!isimageset) {
169             String hash = inverse ? "_hashinv, " : "_hash, " ;
170             writer.addDeclaration("struct SimpleHash *",dest.getSafeSymbol());
171             writer.outputline(dest.getSafeSymbol()+"=SimpleHashimageSet("+rd.getSafeSymbol()+hash+vd.getSafeSymbol()+");");
172         } else {
173             VarDescriptor iseset=VarDescriptor.makeNew("set");
174             ise.generate_set(writer,iseset);
175
176             VarDescriptor itvd=VarDescriptor.makeNew("iterator");
177             writer.addDeclaration("struct SimpleIterator",itvd.getSafeSymbol());
178             writer.outputline("SimpleHashiterator("+iseset.getSafeSymbol()+",&"+itvd.getSafeSymbol()+");");
179             writer.addDeclaration("struct SimpleHash *", dest.getSafeSymbol());
180             writer.outputline(dest.getSafeSymbol()+"=allocateSimpleHash(10);");
181             writer.outputline("while (hasNext(&"+itvd.getSafeSymbol()+")) {");
182
183             VarDescriptor keyvd=VarDescriptor.makeNew("key");
184
185             writer.addDeclaration("int",keyvd.getSafeSymbol());
186             writer.outputline(keyvd.getSafeSymbol()+"=next(&"+itvd.getSafeSymbol()+");");
187             String hash = inverse ? "_hashinv, " : "_hash, " ;
188             VarDescriptor newset=VarDescriptor.makeNew("newset");
189             writer.addDeclaration("struct SimpleHash *", newset.getSafeSymbol());
190             writer.outputline(newset.getSafeSymbol()+"=SimpleHashimageSet("+rd.getSafeSymbol()+hash+keyvd.getSafeSymbol()+");");
191             writer.outputline("SimpleHashaddAll("+dest.getSafeSymbol()+", "+ newset.getSafeSymbol()+");");
192             writer.outputline("freeSimpleHash("+newset.getSafeSymbol()+");");
193             writer.outputline("}");
194             writer.outputline("freeSimpleHash("+iseset.getSafeSymbol()+");");
195         }
196     }
197
198     public void prettyPrint(PrettyPrinter pp) {
199         if (!isimageset)
200             pp.output(vd.toString());
201         else
202             ise.prettyPrint(pp);
203         pp.output(".");
204         if (inverse) {
205             pp.output("~");
206         }
207         pp.output(rd.toString());
208     }
209
210     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
211         throw new IRException("not supported");
212     }
213 }