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