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 DNFRule constructDNF() {
20 if (opcode==Opcode.AND) {
21 DNFRule leftd=left.constructDNF();
22 DNFRule rightd=right.constructDNF();
23 return leftd.and(rightd);
24 } else if (opcode==Opcode.OR) {
25 DNFRule leftd=left.constructDNF();
26 DNFRule rightd=right.constructDNF();
27 return leftd.or(rightd);
28 } else if (opcode==Opcode.NOT) {
29 DNFRule leftd=left.constructDNF();
31 } else throw new Error();
34 public boolean usesDescriptor(RelationDescriptor rd) {
35 if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
36 opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
37 return right.usesDescriptor(rd);
39 return left.usesDescriptor(rd)||(right!=null&&right.usesDescriptor(rd));
42 public int[] getRepairs(boolean negated) {
43 if (left instanceof RelationExpr)
44 return new int[] {AbstractRepair.MODIFYRELATION};
45 if (left instanceof SizeofExpr) {
46 boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
48 if (opcode==Opcode.EQ)
49 return new int[] {AbstractRepair.ADDTORELATION,
50 AbstractRepair.REMOVEFROMRELATION};
51 if (((opcode==Opcode.GE)&&!negated)||
52 ((opcode==Opcode.LE)&&negated))
53 return new int[]{AbstractRepair.ADDTORELATION};
55 return new int[]{AbstractRepair.REMOVEFROMRELATION};
57 if (opcode==Opcode.EQ)
58 return new int[] {AbstractRepair.ADDTOSET,
59 AbstractRepair.REMOVEFROMSET};
61 if (((opcode==Opcode.GE)&&!negated)||
62 ((opcode==Opcode.LE)&&negated))
63 return new int[] {AbstractRepair.ADDTOSET};
65 return new int[] {AbstractRepair.REMOVEFROMSET};
68 throw new Error("BAD");
71 public Descriptor getDescriptor() {
72 return left.getDescriptor();
75 public boolean inverted() {
76 return left.inverted();
79 public Set getInversedRelations() {
80 Set set = left.getInversedRelations();
82 set.addAll(right.getInversedRelations());
87 public Set getRequiredDescriptors() {
88 Set v = left.getRequiredDescriptors();
91 v.addAll(right.getRequiredDescriptors());
97 public void generate(CodeWriter writer, VarDescriptor dest) {
98 VarDescriptor ld = VarDescriptor.makeNew("leftop");
99 left.generate(writer, ld);
100 VarDescriptor rd = null;
103 rd = VarDescriptor.makeNew("rightop");
104 right.generate(writer, rd);
108 if (opcode != Opcode.NOT) { /* two operands */
110 writer.outputline("int " + dest.getSafeSymbol() + " = " +
111 ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
113 writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
117 public void prettyPrint(PrettyPrinter pp) {
119 if (opcode == Opcode.NOT) {
120 left.prettyPrint(pp);
122 left.prettyPrint(pp);
123 pp.output(" " + opcode.toString() + " ");
124 assert right != null;
125 right.prettyPrint(pp);
130 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
131 TypeDescriptor lt = left.typecheck(sa);
132 TypeDescriptor rt = right == null ? null : right.typecheck(sa);
136 } else if (right != null && rt == null) {
142 // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
143 // either that or we use a isvalid clause to check for null
146 if (lt != ReservedTypeDescriptor.INT) {
147 sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
152 if (rt != ReservedTypeDescriptor.INT) {
153 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
163 this.td = ReservedTypeDescriptor.INT;