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