Updates
[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 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();
30             return leftd.not();
31         } else throw new Error();
32     }
33
34
35
36     public Set getInversedRelations() {
37         Set set = left.getInversedRelations();
38         if (right != null) {
39             set.addAll(right.getInversedRelations());
40         }
41         return set;
42     }
43
44     public Set getRequiredDescriptors() {
45         Set v = left.getRequiredDescriptors();
46      
47         if (right != null) {
48             v.addAll(right.getRequiredDescriptors());
49         }
50
51         return v;
52     }   
53
54     public void generate(CodeWriter writer, VarDescriptor dest) {
55         VarDescriptor ld = VarDescriptor.makeNew("leftop");
56         left.generate(writer, ld);        
57         VarDescriptor rd = null;
58
59         if (right != null) {
60             rd = VarDescriptor.makeNew("rightop");
61             right.generate(writer, rd);
62         }
63
64         String code;
65         if (opcode != Opcode.NOT) { /* two operands */
66             assert rd != null;
67             writer.outputline("int " + dest.getSafeSymbol() + " = " + 
68                               ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
69         } else {
70             writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
71         }
72     }
73
74     public void prettyPrint(PrettyPrinter pp) {
75         pp.output("(");
76         if (opcode == Opcode.NOT) {
77             left.prettyPrint(pp);
78         } else {           
79             left.prettyPrint(pp);
80             pp.output(" " + opcode.toString() + " ");
81             assert right != null;
82             right.prettyPrint(pp);
83         }
84         pp.output(")");
85     }
86
87     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
88         TypeDescriptor lt = left.typecheck(sa);
89         TypeDescriptor rt = right == null ? null : right.typecheck(sa);
90
91         if (lt == null) {
92             return null;
93         } else if (right != null && rt == null) {
94             return null;
95         }
96
97         boolean ok = true;
98
99         // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
100         // either that or we use a isvalid clause to check for null
101
102         /*
103         if (lt != ReservedTypeDescriptor.INT) {
104             sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
105             ok = false;
106         }
107
108         if (right != null) {
109             if (rt != ReservedTypeDescriptor.INT) {
110                 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
111                 ok = false;
112             }
113         }
114         */
115
116         if (!ok) {
117             return null;
118         }
119
120         this.td = ReservedTypeDescriptor.INT;
121         return this.td;
122     }
123
124 }
125
126
127
128
129