1   // Copyright 2012- Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2   
3   package jminusminus;
4   
5   import static jminusminus.CLConstants.*;
6   
7   /**
8    * This abstract base class is the AST node for binary expressions that return booleans.
9    */
10  abstract class JBooleanBinaryExpression extends JBinaryExpression {
11      /**
12       * Constructs an AST node for a boolean binary expression.
13       *
14       * @param line     line in which the boolean binary expression occurs in the source file.
15       * @param operator the boolean binary operator.
16       * @param lhs      lhs operand.
17       * @param rhs      rhs operand.
18       */
19  
20      protected JBooleanBinaryExpression(int line, String operator, JExpression lhs,
21                                         JExpression rhs) {
22          super(line, operator, lhs, rhs);
23      }
24  
25      /**
26       * {@inheritDoc}
27       */
28      public void codegen(CLEmitter output) {
29          String falseLabel = output.createLabel();
30          String trueLabel = output.createLabel();
31          this.codegen(output, falseLabel, false);
32          output.addNoArgInstruction(ICONST_1); // true
33          output.addBranchInstruction(GOTO, trueLabel);
34          output.addLabel(falseLabel);
35          output.addNoArgInstruction(ICONST_0); // false
36          output.addLabel(trueLabel);
37      }
38  }
39  
40  /**
41   * The AST node for an equality (==) expression.
42   */
43  class JEqualOp extends JBooleanBinaryExpression {
44      /**
45       * Constructs an AST node for an equality expression.
46       *
47       * @param line line number in which the equality expression occurs in the source file.
48       * @param lhs  lhs operand.
49       * @param rhs  rhs operand.
50       */
51  
52      public JEqualOp(int line, JExpression lhs, JExpression rhs) {
53          super(line, "==", lhs, rhs);
54      }
55  
56      /**
57       * {@inheritDoc}
58       */
59      public JExpression analyze(Context context) {
60          lhs = (JExpression) lhs.analyze(context);
61          rhs = (JExpression) rhs.analyze(context);
62          lhs.type().mustMatchExpected(line(), rhs.type());
63          type = Type.BOOLEAN;
64          return this;
65      }
66  
67      /**
68       * {@inheritDoc}
69       */
70      public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
71          lhs.codegen(output);
72          rhs.codegen(output);
73          if (lhs.type().isReference()) {
74              output.addBranchInstruction(onTrue ? IF_ACMPEQ : IF_ACMPNE, targetLabel);
75          } else {
76              output.addBranchInstruction(onTrue ? IF_ICMPEQ : IF_ICMPNE, targetLabel);
77          }
78      }
79  }
80  
81  /**
82   * The AST node for a logical-and (&&) expression.
83   */
84  class JLogicalAndOp extends JBooleanBinaryExpression {
85      /**
86       * Constructs an AST node for a logical-and expression.
87       *
88       * @param line line in which the logical-and expression occurs in the source file.
89       * @param lhs  lhs operand.
90       * @param rhs  rhs operand.
91       */
92      public JLogicalAndOp(int line, JExpression lhs, JExpression rhs) {
93          super(line, "&&", lhs, rhs);
94      }
95  
96      /**
97       * {@inheritDoc}
98       */
99      public JExpression analyze(Context context) {
100         lhs = (JExpression) lhs.analyze(context);
101         rhs = (JExpression) rhs.analyze(context);
102         lhs.type().mustMatchExpected(line(), Type.BOOLEAN);
103         rhs.type().mustMatchExpected(line(), Type.BOOLEAN);
104         type = Type.BOOLEAN;
105         return this;
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
112         if (onTrue) {
113             String falseLabel = output.createLabel();
114             lhs.codegen(output, falseLabel, false);
115             rhs.codegen(output, targetLabel, true);
116             output.addLabel(falseLabel);
117         } else {
118             lhs.codegen(output, targetLabel, false);
119             rhs.codegen(output, targetLabel, false);
120         }
121     }
122 }
123 
124 /**
125  * The AST node for a logical-or (||) expression.
126  */
127 class JLogicalOrOp extends JBooleanBinaryExpression {
128     /**
129      * Constructs an AST node for a logical-or expression.
130      *
131      * @param line line in which the logical-or expression occurs in the source file.
132      * @param lhs  lhs operand.
133      * @param rhs  rhs operand.
134      */
135     public JLogicalOrOp(int line, JExpression lhs, JExpression rhs) {
136         super(line, "||", lhs, rhs);
137     }
138 
139     /**
140      * {@inheritDoc}
141      */
142     public JExpression analyze(Context context) {
143         // TODO
144         return this;
145     }
146 
147     /**
148      * {@inheritDoc}
149      */
150     public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
151         // TODO
152     }
153 }
154 
155 /**
156  * The AST node for a not-equal-to (!=) expression.
157  */
158 class JNotEqualOp extends JBooleanBinaryExpression {
159     /**
160      * Constructs an AST node for not-equal-to (!=) expression.
161      *
162      * @param line line number in which the not-equal-to (!=) expression occurs in the source file.
163      * @param lhs  lhs operand.
164      * @param rhs  rhs operand.
165      */
166 
167     public JNotEqualOp(int line, JExpression lhs, JExpression rhs) {
168         super(line, "!=", lhs, rhs);
169     }
170 
171     /**
172      * {@inheritDoc}
173      */
174     public JExpression analyze(Context context) {
175         // TODO
176         return this;
177     }
178 
179     /**
180      * {@inheritDoc}
181      */
182     public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
183         // TODO
184     }
185 }
186