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 Opcode getOpcode() {
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();
35 } else return new DNFRule(this);
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);
43 return left.usesDescriptor(rd)||(right!=null&&right.usesDescriptor(rd));
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;
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};
59 return new int[]{AbstractRepair.REMOVEFROMRELATION};
61 if (opcode==Opcode.EQ)
62 return new int[] {AbstractRepair.ADDTOSET,
63 AbstractRepair.REMOVEFROMSET};
65 if (((opcode==Opcode.GE)&&!negated)||
66 ((opcode==Opcode.LE)&&negated))
67 return new int[] {AbstractRepair.ADDTOSET};
69 return new int[] {AbstractRepair.REMOVEFROMSET};
72 throw new Error("BAD");
75 public Descriptor getDescriptor() {
76 return left.getDescriptor();
79 public boolean inverted() {
80 return left.inverted();
83 public Set getInversedRelations() {
84 Set set = left.getInversedRelations();
86 set.addAll(right.getInversedRelations());
91 public Set getRequiredDescriptors() {
92 Set v = left.getRequiredDescriptors();
95 v.addAll(right.getRequiredDescriptors());
101 public void generate(CodeWriter writer, VarDescriptor dest) {
102 VarDescriptor ld = VarDescriptor.makeNew("leftop");
103 left.generate(writer, ld);
104 VarDescriptor rd = null;
107 rd = VarDescriptor.makeNew("rightop");
108 right.generate(writer, rd);
112 if (opcode != Opcode.NOT) { /* two operands */
114 writer.outputline("int " + dest.getSafeSymbol() + " = " +
115 ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
117 writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
121 public void prettyPrint(PrettyPrinter pp) {
123 if (opcode == Opcode.NOT) {
124 left.prettyPrint(pp);
126 left.prettyPrint(pp);
127 pp.output(" " + opcode.toString() + " ");
128 assert right != null;
129 right.prettyPrint(pp);
134 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
135 TypeDescriptor lt = left.typecheck(sa);
136 TypeDescriptor rt = right == null ? null : right.typecheck(sa);
140 } else if (right != null && rt == null) {
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
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'");
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'");
167 this.td = ReservedTypeDescriptor.INT;