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