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