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 String name() {
20 if (opcode==Opcode.NOT)
21 return "!("+left.name()+")";
22 String name=left.name()+opcode.toString();
28 public Opcode getOpcode() {
32 public boolean equals(Map remap, Expr e) {
33 if (e==null||!(e instanceof OpExpr))
36 if (opcode!=oe.opcode)
38 if (!left.equals(remap,oe.left))
40 if (opcode!=Opcode.NOT)
41 if (!right.equals(remap,oe.right))
46 public DNFRule constructDNF() {
47 if (opcode==Opcode.AND) {
48 DNFRule leftd=left.constructDNF();
49 DNFRule rightd=right.constructDNF();
50 return leftd.and(rightd);
51 } else if (opcode==Opcode.OR) {
52 DNFRule leftd=left.constructDNF();
53 DNFRule rightd=right.constructDNF();
54 return leftd.or(rightd);
55 } else if (opcode==Opcode.NOT) {
56 DNFRule leftd=left.constructDNF();
58 } else return new DNFRule(this);
61 public boolean usesDescriptor(Descriptor d) {
62 if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
63 opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
64 return right.usesDescriptor(d);
66 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
69 public int[] getRepairs(boolean negated) {
70 if (left instanceof RelationExpr)
71 return new int[] {AbstractRepair.MODIFYRELATION};
72 if (left instanceof SizeofExpr) {
73 boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
75 if (opcode==Opcode.EQ)
76 return new int[] {AbstractRepair.ADDTORELATION,
77 AbstractRepair.REMOVEFROMRELATION};
78 if (((opcode==Opcode.GE)&&!negated)||
79 ((opcode==Opcode.LE)&&negated))
80 return new int[]{AbstractRepair.ADDTORELATION};
82 return new int[]{AbstractRepair.REMOVEFROMRELATION};
84 if (opcode==Opcode.EQ)
85 return new int[] {AbstractRepair.ADDTOSET,
86 AbstractRepair.REMOVEFROMSET};
88 if (((opcode==Opcode.GE)&&!negated)||
89 ((opcode==Opcode.LE)&&negated))
90 return new int[] {AbstractRepair.ADDTOSET};
92 return new int[] {AbstractRepair.REMOVEFROMSET};
95 throw new Error("BAD");
98 public Descriptor getDescriptor() {
99 return left.getDescriptor();
102 public boolean inverted() {
103 return left.inverted();
106 public Set getInversedRelations() {
107 Set set = left.getInversedRelations();
109 set.addAll(right.getInversedRelations());
114 public Set getRequiredDescriptors() {
115 Set v = left.getRequiredDescriptors();
118 v.addAll(right.getRequiredDescriptors());
124 public void generate(CodeWriter writer, VarDescriptor dest) {
125 VarDescriptor ld = VarDescriptor.makeNew("leftop");
126 left.generate(writer, ld);
127 VarDescriptor rd = null;
130 rd = VarDescriptor.makeNew("rightop");
131 right.generate(writer, rd);
135 if (opcode != Opcode.NOT) { /* two operands */
137 writer.outputline("int " + dest.getSafeSymbol() + " = " +
138 ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
140 writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
144 public void prettyPrint(PrettyPrinter pp) {
146 if (opcode == Opcode.NOT) {
147 left.prettyPrint(pp);
149 left.prettyPrint(pp);
150 pp.output(" " + opcode.toString() + " ");
151 assert right != null;
152 right.prettyPrint(pp);
157 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
158 TypeDescriptor lt = left.typecheck(sa);
159 TypeDescriptor rt = right == null ? null : right.typecheck(sa);
163 } else if (right != null && rt == null) {
169 // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
170 // either that or we use a isvalid clause to check for null
173 if (lt != ReservedTypeDescriptor.INT) {
174 sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
179 if (rt != ReservedTypeDescriptor.INT) {
180 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
190 this.td = ReservedTypeDescriptor.INT;