c2b30ff3ff42a0fe06fd5c194ae1fed4b05dfe06
[repair.git] / Repair / RepairCompiler / MCC / IR / SumExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class SumExpr extends Expr {
6
7     SetDescriptor sd;
8     RelationDescriptor rd;
9
10
11     public SumExpr(SetDescriptor sd, RelationDescriptor rd) {
12         if (sd == null||rd==null) {
13             throw new NullPointerException();
14         }
15         this.sd=sd;
16         this.rd=rd;
17     }
18
19     public String name() {
20         return "sum("+sd.toString()+"."+rd.toString()+")";
21     }
22
23     public boolean equals(Map remap, Expr e) {
24         if (e==null||!(e instanceof SumExpr))
25             return false;
26         SumExpr se=(SumExpr)e;
27         return (se.sd==sd)&&(se.rd==rd);
28     }
29
30     public boolean usesDescriptor(Descriptor d) {
31         return (sd==d)||(rd==d);
32     }
33
34     public Set useDescriptor(Descriptor d) {
35         HashSet newset=new HashSet();
36         if ((d==sd)||(d==rd))
37             newset.add(this);
38         return newset;
39     }
40
41     public Descriptor getDescriptor() {
42         throw new Error("Sum shouldn't appear on left hand side!");
43     }
44
45     public boolean inverted() {
46         return false;
47     }
48
49     public Set getRequiredDescriptors() {
50         HashSet v=new HashSet();
51         v.add(sd);
52         v.add(rd);
53         return v;
54     }
55
56     public void generate(CodeWriter writer, VarDescriptor dest) {
57         writer.addDeclaration("int",dest.getSafeSymbol());
58         writer.outputline(dest.getSafeSymbol()+"=0;");
59
60
61         VarDescriptor itvd=VarDescriptor.makeNew("iterator");
62         writer.addDeclaration("struct SimpleIterator",itvd.getSafeSymbol());
63         writer.outputline("SimpleHashiterator("+sd.getSafeSymbol()+"_hash , &"+itvd.getSafeSymbol()+");");
64         writer.outputline("while (hasNext(&"+itvd.getSafeSymbol()+"))");
65         writer.startblock();
66         {
67             VarDescriptor keyvd=VarDescriptor.makeNew("key");
68             writer.addDeclaration("int",keyvd.getSafeSymbol());
69             writer.outputline(keyvd.getSafeSymbol()+"=next(&"+itvd.getSafeSymbol()+");");
70             VarDescriptor tmpvar=VarDescriptor.makeNew("tmp");
71             writer.addDeclaration("int",tmpvar.getSafeSymbol());
72
73             VarDescriptor newset=VarDescriptor.makeNew("newset");
74             writer.addDeclaration("struct SimpleHash *",newset.getSafeSymbol());
75             writer.outputline(newset.getSafeSymbol()+"=SimpleHashimageSet("+rd.getSafeSymbol()+"_hash, "+keyvd.getSafeSymbol()+", &"+tmpvar.getSafeSymbol()+");");
76
77             VarDescriptor itvd2=VarDescriptor.makeNew("iterator");
78             writer.addDeclaration("struct SimpleIterator",itvd2.getSafeSymbol());
79             writer.outputline("SimpleHashiterator("+newset.getSafeSymbol()+", &"+itvd2.getSafeSymbol()+");");
80
81             writer.outputline("while (hasNext(&"+itvd2.getSafeSymbol()+"))");
82             writer.startblock();
83             {
84                 VarDescriptor keyvd2=VarDescriptor.makeNew("keyinner");
85                 writer.outputline(dest.getSafeSymbol()+"+=next(&"+itvd2.getSafeSymbol()+");");
86                 writer.endblock();
87             }
88             writer.outputline("freeSimpleHash("+newset.getSafeSymbol()+");");
89             writer.endblock();
90         }
91     }
92
93     public void prettyPrint(PrettyPrinter pp) {
94         pp.output("sum(");
95         pp.output(sd.toString());
96         pp.output(".");
97         pp.output(rd.toString());
98         pp.output(")");
99     }
100
101     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
102         this.td = ReservedTypeDescriptor.INT;
103         return this.td;
104     }
105
106     public Set getInversedRelations() {
107         return new HashSet();
108     }
109
110 }