Updates
[repair.git] / Repair / RepairCompiler / MCC / IR / LogicStatement.java
1 package MCC.IR;
2
3 import java.util.*;
4
5 public class LogicStatement {
6
7     public static final Operation AND = new Operation("AND");
8     public static final Operation OR = new Operation("OR");
9     public static final Operation NOT = new Operation("NOT");
10
11     public Set getInversedRelations() {
12         if (left == null) {
13             throw new IRException();
14         }
15         Set set = left.getInversedRelations();
16         if (right != null) {
17             set.addAll(right.getInversedRelations());
18         }
19         return set;
20     }
21     
22     public DNFConstraint constructDNF() {
23         if (op==AND) {
24             DNFConstraint leftd=left.constructDNF();
25             DNFConstraint rightd=right.constructDNF();
26             return leftd.and(rightd);
27         } else if (op==OR) {
28             DNFConstraint leftd=left.constructDNF();
29             DNFConstraint rightd=right.constructDNF();
30             return leftd.or(rightd);
31         } else if (op==NOT) {
32             DNFConstraint leftd=left.constructDNF();
33             return leftd.not();
34         } else throw new Error();
35     }
36
37     public static class Operation {
38         private final String name;
39         private Operation(String opname) { name = opname; }
40         public String toString() { return name; }
41     }
42
43     Operation op;
44     LogicStatement left;
45     LogicStatement right;
46
47     public LogicStatement(Operation op, LogicStatement left, LogicStatement right) {
48         if (op == NOT) {
49             throw new IllegalArgumentException("Must be a AND or OR expression.");
50         }
51
52         this.op = op;
53         this.left = left;
54         this.right = right;
55     }
56
57     public LogicStatement(Operation op, LogicStatement left) {
58         if (op != NOT) {
59             throw new IllegalArgumentException("Must be a NOT expression.");
60         }
61
62         this.op = op;
63         this.left = left;
64         this.right = null;
65     }
66
67     protected LogicStatement() {
68         this.op = null;
69         this.left = null;
70         this.right = null;
71     }
72
73     public Set getRequiredDescriptors() {
74         Set v = left.getRequiredDescriptors();
75         if (right != null) {
76             v.addAll(right.getRequiredDescriptors());
77         }
78         return v;
79     }
80
81     public void generate(CodeWriter writer, VarDescriptor dest) {
82
83         writer.outputline("int " + dest.getSafeSymbol() + ";");
84
85         if (op == NOT) {
86
87             VarDescriptor leftd = VarDescriptor.makeNew("leftboolean");
88             left.generate(writer, leftd);
89
90             writer.outputline("// 3-valued NOT");
91             writer.outputline("if (!maybe)");
92             writer.startblock();
93             writer.outputline(dest.getSafeSymbol() + " =  !" + leftd.getSafeSymbol() + ";");
94             writer.endblock();
95
96         } else { // two operands
97
98             VarDescriptor leftd = VarDescriptor.makeNew("leftboolean");
99             String lm = (VarDescriptor.makeNew("leftmaybe")).getSafeSymbol();
100             left.generate(writer, leftd);
101             writer.outputline("int " + lm + " = maybe;");
102             
103             VarDescriptor rightd = VarDescriptor.makeNew("rightboolean");
104             String rm = (VarDescriptor.makeNew("rightmaybe")).getSafeSymbol();
105             assert right != null;
106             right.generate(writer, rightd);
107             writer.outputline("int " + rm + " = maybe;");
108
109             String l = leftd.getSafeSymbol();
110             String r = rightd.getSafeSymbol();
111             
112             if (op == AND) {
113
114                 /* 
115                  * 3-value AND LOGIC
116                  *
117                  * LRLR
118                  * MM    M O
119                  * ----  ---
120                  * 0000  0 0
121                  * 0001  0 0
122                  * 0010  0 0
123                  * 0011  0 1
124                  * 0100  0 0
125                  * 0101  0 0
126                  * 0110  1 X
127                  * 0111  1 X
128                  * 1000  0 0
129                  * 1001  1 X
130                  * 1010  0 0
131                  * 1011  1 X
132                  * 1100  1 X
133                  * 1101  1 X
134                  * 1110  1 X
135                  * 1111  1 X
136                  *
137                  * M = (L*RM) + (R*LM) + (LM*RM)                 
138                  * O = (L*R)
139                  */
140                
141                 // maybe = (l && rm) || (r && lm) || (lm && rm)
142                 writer.outputline("maybe = (" + l + " && " + rm + ") || (" + r + " && " + lm + ") || (" + lm + " && " + rm + ");");
143                 writer.outputline(dest.getSafeSymbol() + " = " + l + " && " + r + ";");
144
145             } else if (op == OR) {
146
147                 /* 
148                  * 3-value OR LOGIC
149                  *
150                  * LRLR
151                  * MM    M O
152                  * ----  ---
153                  * 0000  0 0
154                  * 0001  0 1
155                  * 0010  0 1
156                  * 0011  0 1
157                  * 0100  1 X
158                  * 0101  1 X
159                  * 0110  0 1
160                  * 0111  0 1
161                  * 1000  1 X
162                  * 1001  0 1
163                  * 1010  1 X
164                  * 1011  0 1
165                  * 1100  1 X
166                  * 1101  1 X
167                  * 1110  1 X
168                  * 1111  1 X
169                  *
170                  * M = (!L*RM) + (!R*LM) + (LM*RM)
171                  * O = L+R
172                  */
173
174                 // maybe = (!l && rm) || (!r && lm) || (lm && rm)
175                 writer.outputline("maybe = (!" + l + " && " + rm + ") || (!" + r + " && " + lm + ") || (" + lm + " && " + rm + ");");
176                 writer.outputline(dest.getSafeSymbol() + " = " + l + " || " + r + ";");
177             } else {
178                 throw new IRException();
179             }        
180         }
181     }   
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195