b3af82790dede1e7479e376f8d0e9da86b5970ca
[repair.git] / Repair / RepairCompiler / MCC / IR / OpExpr.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class OpExpr extends Expr {
6
7     Expr left;
8     Expr right;
9     Opcode opcode;
10
11     public OpExpr(Opcode opcode, Expr left, Expr right) {
12         this.opcode = opcode;
13         this.left = left;
14         this.right = right;
15
16         assert (right == null && opcode == Opcode.NOT) || (right != null);
17     }
18
19     public Opcode getOpcode() {
20         return opcode;
21     }
22
23     public DNFRule constructDNF() {
24         if (opcode==Opcode.AND) {
25             DNFRule leftd=left.constructDNF();
26             DNFRule rightd=right.constructDNF();
27             return leftd.and(rightd);
28         } else if (opcode==Opcode.OR) {
29             DNFRule leftd=left.constructDNF();
30             DNFRule rightd=right.constructDNF();
31             return leftd.or(rightd);
32         } else if (opcode==Opcode.NOT) {
33             DNFRule leftd=left.constructDNF();
34             return leftd.not();
35         } else return new DNFRule(this);
36     }
37
38     public boolean usesDescriptor(RelationDescriptor rd) {
39         if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
40             opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
41             return right.usesDescriptor(rd);
42         else
43             return left.usesDescriptor(rd)||(right!=null&&right.usesDescriptor(rd));
44     }
45     
46     public int[] getRepairs(boolean negated) {
47         if (left instanceof RelationExpr)
48             return new int[] {AbstractRepair.MODIFYRELATION};
49         if (left instanceof SizeofExpr) {
50             boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
51             if (isRelation) {
52                 if (opcode==Opcode.EQ)
53                     return new int[] {AbstractRepair.ADDTORELATION,
54                                           AbstractRepair.REMOVEFROMRELATION};
55                 if (((opcode==Opcode.GE)&&!negated)||
56                     ((opcode==Opcode.LE)&&negated))
57                     return new int[]{AbstractRepair.ADDTORELATION};
58                 else
59                     return new int[]{AbstractRepair.REMOVEFROMRELATION};
60             } else {
61                 if (opcode==Opcode.EQ)
62                     return new int[] {AbstractRepair.ADDTOSET,
63                                           AbstractRepair.REMOVEFROMSET};
64                 
65                 if (((opcode==Opcode.GE)&&!negated)||
66                     ((opcode==Opcode.LE)&&negated))
67                     return new int[] {AbstractRepair.ADDTOSET};
68                 else
69                     return new int[] {AbstractRepair.REMOVEFROMSET};
70             }
71         }
72         throw new Error("BAD");
73     }
74     
75     public Descriptor getDescriptor() {
76         return left.getDescriptor();
77     }
78
79     public boolean inverted() {
80         return left.inverted();
81     }
82
83     public Set getInversedRelations() {
84         Set set = left.getInversedRelations();
85         if (right != null) {
86             set.addAll(right.getInversedRelations());
87         }
88         return set;
89     }
90
91     public Set getRequiredDescriptors() {
92         Set v = left.getRequiredDescriptors();
93      
94         if (right != null) {
95             v.addAll(right.getRequiredDescriptors());
96         }
97
98         return v;
99     }   
100
101     public void generate(CodeWriter writer, VarDescriptor dest) {
102         VarDescriptor ld = VarDescriptor.makeNew("leftop");
103         left.generate(writer, ld);        
104         VarDescriptor rd = null;
105
106         if (right != null) {
107             rd = VarDescriptor.makeNew("rightop");
108             right.generate(writer, rd);
109         }
110
111         String code;
112         if (opcode != Opcode.NOT) { /* two operands */
113             assert rd != null;
114             writer.outputline("int " + dest.getSafeSymbol() + " = " + 
115                               ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
116         } else {
117             writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
118         }
119     }
120
121     public void prettyPrint(PrettyPrinter pp) {
122         pp.output("(");
123         if (opcode == Opcode.NOT) {
124             left.prettyPrint(pp);
125         } else {           
126             left.prettyPrint(pp);
127             pp.output(" " + opcode.toString() + " ");
128             assert right != null;
129             right.prettyPrint(pp);
130         }
131         pp.output(")");
132     }
133
134     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
135         TypeDescriptor lt = left.typecheck(sa);
136         TypeDescriptor rt = right == null ? null : right.typecheck(sa);
137
138         if (lt == null) {
139             return null;
140         } else if (right != null && rt == null) {
141             return null;
142         }
143
144         boolean ok = true;
145
146         // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
147         // either that or we use a isvalid clause to check for null
148
149         /*
150         if (lt != ReservedTypeDescriptor.INT) {
151             sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
152             ok = false;
153         }
154
155         if (right != null) {
156             if (rt != ReservedTypeDescriptor.INT) {
157                 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
158                 ok = false;
159             }
160         }
161         */
162
163         if (!ok) {
164             return null;
165         }
166
167         this.td = ReservedTypeDescriptor.INT;
168         return this.td;
169     }
170
171 }
172
173
174
175
176