5 public class OpExpr extends Expr {
11 public OpExpr(Opcode opcode, Expr left, Expr right) {
16 assert (right == null && opcode == Opcode.NOT) || (right != null);
19 public Expr getRightExpr() {
23 public Expr getLeftExpr() {
27 public Set freeVars() {
28 Set lset=left.freeVars();
31 rset=right.freeVars();
39 public String name() {
40 if (opcode==Opcode.NOT)
41 return "!("+left.name()+")";
42 String name=left.name()+opcode.toString();
48 public Opcode getOpcode() {
55 public boolean equals(Map remap, Expr e) {
56 if (e==null||!(e instanceof OpExpr))
59 if (opcode!=oe.opcode)
61 if (!left.equals(remap,oe.left))
63 if (opcode!=Opcode.NOT)
64 if (!right.equals(remap,oe.right))
69 public DNFRule constructDNF() {
70 if (opcode==Opcode.AND) {
71 DNFRule leftd=left.constructDNF();
72 DNFRule rightd=right.constructDNF();
73 return leftd.and(rightd);
74 } else if (opcode==Opcode.OR) {
75 DNFRule leftd=left.constructDNF();
76 DNFRule rightd=right.constructDNF();
77 return leftd.or(rightd);
78 } else if (opcode==Opcode.NOT) {
79 DNFRule leftd=left.constructDNF();
81 } else return new DNFRule(this);
84 public boolean usesDescriptor(Descriptor d) {
85 if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
86 opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
87 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
88 // return right.usesDescriptor(d);
90 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
94 public int[] getRepairs(boolean negated) {
95 if (left instanceof RelationExpr)
96 return new int[] {AbstractRepair.MODIFYRELATION};
97 if (left instanceof SizeofExpr) {
98 boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
100 if (opcode==Opcode.EQ)
101 if (((IntegerLiteralExpr)right).getValue()==0)
102 return new int[] {AbstractRepair.REMOVEFROMRELATION};
104 return new int[] {AbstractRepair.ADDTORELATION,
105 AbstractRepair.REMOVEFROMRELATION};
106 if (((opcode==Opcode.GE)&&!negated)||
107 ((opcode==Opcode.LE)&&negated)) {
108 if (((IntegerLiteralExpr)right).getValue()==0)
111 return new int[]{AbstractRepair.ADDTORELATION}; }
113 return new int[]{AbstractRepair.REMOVEFROMRELATION};
115 if (opcode==Opcode.EQ)
116 if (((IntegerLiteralExpr)right).getValue()==0)
117 return new int[] {AbstractRepair.REMOVEFROMSET};
119 return new int[] {AbstractRepair.ADDTOSET,
120 AbstractRepair.REMOVEFROMSET};
122 if (((opcode==Opcode.GE)&&!negated)||
123 ((opcode==Opcode.LE)&&negated)) {
124 if (((IntegerLiteralExpr)right).getValue()==0)
127 return new int[] {AbstractRepair.ADDTOSET}; }
129 return new int[] {AbstractRepair.REMOVEFROMSET};
132 throw new Error("BAD");
135 public Descriptor getDescriptor() {
136 return left.getDescriptor();
139 public boolean inverted() {
140 return left.inverted();
143 public Set getInversedRelations() {
144 Set set = left.getInversedRelations();
146 set.addAll(right.getInversedRelations());
151 public Set getRequiredDescriptors() {
152 Set v = left.getRequiredDescriptors();
155 v.addAll(right.getRequiredDescriptors());
161 public void generate(CodeWriter writer, VarDescriptor dest) {
162 VarDescriptor ld = VarDescriptor.makeNew("leftop");
163 left.generate(writer, ld);
164 VarDescriptor rd = null;
167 rd = VarDescriptor.makeNew("rightop");
168 right.generate(writer, rd);
172 if (opcode != Opcode.NOT) { /* two operands */
174 writer.outputline("int " + dest.getSafeSymbol() + " = " +
175 ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
177 writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
181 public void prettyPrint(PrettyPrinter pp) {
183 if (opcode == Opcode.NOT) {
184 left.prettyPrint(pp);
186 left.prettyPrint(pp);
187 pp.output(" " + opcode.toString() + " ");
188 assert right != null;
189 right.prettyPrint(pp);
194 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
195 TypeDescriptor lt = left.typecheck(sa);
196 TypeDescriptor rt = right == null ? null : right.typecheck(sa);
200 } else if (right != null && rt == null) {
206 // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
207 // either that or we use a isvalid clause to check for null
210 if (lt != ReservedTypeDescriptor.INT) {
211 sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
216 if (rt != ReservedTypeDescriptor.INT) {
217 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
227 this.td = ReservedTypeDescriptor.INT;