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 a binary expression --- an expression with a binary
9    * operator and two operands: lhs and rhs.
10   */
11  abstract class JBinaryExpression extends JExpression {
12      /**
13       * The binary operator.
14       */
15      protected String operator;
16  
17      /**
18       * The lhs operand.
19       */
20      protected JExpression lhs;
21  
22      /**
23       * The rhs operand.
24       */
25      protected JExpression rhs;
26  
27      /**
28       * Constructs an AST node for a binary expression.
29       *
30       * @param line     line in which the binary expression occurs in the source file.
31       * @param operator the binary operator.
32       * @param lhs      the lhs operand.
33       * @param rhs      the rhs operand.
34       */
35      protected JBinaryExpression(int line, String operator, JExpression lhs, JExpression rhs) {
36          super(line);
37          this.operator = operator;
38          this.lhs = lhs;
39          this.rhs = rhs;
40      }
41  
42      /**
43       * {@inheritDoc}
44       */
45      public void toJSON(JSONElement json) {
46          JSONElement e = new JSONElement();
47          json.addChild("JBinaryExpression:" + line, e);
48          e.addAttribute("operator", operator);
49          e.addAttribute("type", type == null ? "" : type.toString());
50          JSONElement e1 = new JSONElement();
51          e.addChild("Operand1", e1);
52          lhs.toJSON(e1);
53          JSONElement e2 = new JSONElement();
54          e.addChild("Operand2", e2);
55          rhs.toJSON(e2);
56      }
57  }
58  
59  /**
60   * The AST node for a multiplication (*) expression.
61   */
62  class JMultiplyOp extends JBinaryExpression {
63      /**
64       * Constructs an AST for a multiplication expression.
65       *
66       * @param line line in which the multiplication expression occurs in the source file.
67       * @param lhs  the lhs operand.
68       * @param rhs  the rhs operand.
69       */
70      public JMultiplyOp(int line, JExpression lhs, JExpression rhs) {
71          super(line, "*", lhs, rhs);
72      }
73  
74      /**
75       * {@inheritDoc}
76       */
77      public JExpression analyze(Context context) {
78          lhs = (JExpression) lhs.analyze(context);
79          rhs = (JExpression) rhs.analyze(context);
80          lhs.type().mustMatchExpected(line(), Type.INT);
81          rhs.type().mustMatchExpected(line(), Type.INT);
82          type = Type.INT;
83          return this;
84      }
85  
86      /**
87       * {@inheritDoc}
88       */
89      public void codegen(CLEmitter output) {
90          lhs.codegen(output);
91          rhs.codegen(output);
92          output.addNoArgInstruction(IMUL);
93      }
94  }
95  
96  /**
97   * The AST node for a plus (+) expression. In j--, as in Java, + is overloaded to denote addition
98   * for numbers and concatenation for Strings.
99   */
100 class JPlusOp extends JBinaryExpression {
101     /**
102      * Constructs an AST node for an addition expression.
103      *
104      * @param line line in which the addition expression occurs in the source file.
105      * @param lhs  the lhs operand.
106      * @param rhs  the rhs operand.
107      */
108     public JPlusOp(int line, JExpression lhs, JExpression rhs) {
109         super(line, "+", lhs, rhs);
110     }
111 
112     /**
113      * {@inheritDoc}
114      */
115     public JExpression analyze(Context context) {
116         lhs = (JExpression) lhs.analyze(context);
117         rhs = (JExpression) rhs.analyze(context);
118         if (lhs.type() == Type.STRING || rhs.type() == Type.STRING) {
119             return (new JStringConcatenationOp(line, lhs, rhs)).analyze(context);
120         } else if (lhs.type() == Type.INT && rhs.type() == Type.INT) {
121             type = Type.INT;
122         } else {
123             type = Type.ANY;
124             JAST.compilationUnit.reportSemanticError(line(), "Invalid operand types for +");
125         }
126         return this;
127     }
128 
129     /**
130      * {@inheritDoc}
131      */
132     public void codegen(CLEmitter output) {
133         lhs.codegen(output);
134         rhs.codegen(output);
135         output.addNoArgInstruction(IADD);
136     }
137 }
138 
139 /**
140  * The AST node for a subtraction (-) expression.
141  */
142 class JSubtractOp extends JBinaryExpression {
143     /**
144      * Constructs an AST node for a subtraction expression.
145      *
146      * @param line line in which the subtraction expression occurs in the source file.
147      * @param lhs  the lhs operand.
148      * @param rhs  the rhs operand.
149      */
150     public JSubtractOp(int line, JExpression lhs, JExpression rhs) {
151         super(line, "-", lhs, rhs);
152     }
153 
154     /**
155      * {@inheritDoc}
156      */
157     public JExpression analyze(Context context) {
158         lhs = (JExpression) lhs.analyze(context);
159         rhs = (JExpression) rhs.analyze(context);
160         lhs.type().mustMatchExpected(line(), Type.INT);
161         rhs.type().mustMatchExpected(line(), Type.INT);
162         type = Type.INT;
163         return this;
164     }
165 
166     /**
167      * {@inheritDoc}
168      */
169     public void codegen(CLEmitter output) {
170         lhs.codegen(output);
171         rhs.codegen(output);
172         output.addNoArgInstruction(ISUB);
173     }
174 }
175 
176 /**
177  * The AST node for a division (/) expression.
178  */
179 class JDivideOp extends JBinaryExpression {
180     /**
181      * Constructs an AST node for a division expression.
182      *
183      * @param line line in which the division expression occurs in the source file.
184      * @param lhs  the lhs operand.
185      * @param rhs  the rhs operand.
186      */
187     public JDivideOp(int line, JExpression lhs, JExpression rhs) {
188         super(line, "/", lhs, rhs);
189     }
190 
191     /**
192      * {@inheritDoc}
193      */
194     public JExpression analyze(Context context) {
195         // TODO
196         return this;
197     }
198 
199     /**
200      * {@inheritDoc}
201      */
202     public void codegen(CLEmitter output) {
203         // TODO
204     }
205 }
206 
207 /**
208  * The AST node for a remainder (%) expression.
209  */
210 class JRemainderOp extends JBinaryExpression {
211     /**
212      * Constructs an AST node for a remainder expression.
213      *
214      * @param line line in which the division expression occurs in the source file.
215      * @param lhs  the lhs operand.
216      * @param rhs  the rhs operand.
217      */
218     public JRemainderOp(int line, JExpression lhs, JExpression rhs) {
219         super(line, "%", lhs, rhs);
220     }
221 
222     /**
223      * {@inheritDoc}
224      */
225     public JExpression analyze(Context context) {
226         // TODO
227         return this;
228     }
229 
230     /**
231      * {@inheritDoc}
232      */
233     public void codegen(CLEmitter output) {
234         // TODO
235     }
236 }
237 
238 /**
239  * The AST node for an inclusive or (|) expression.
240  */
241 class JOrOp extends JBinaryExpression {
242     /**
243      * Constructs an AST node for an inclusive or expression.
244      *
245      * @param line line in which the inclusive or expression occurs in the source file.
246      * @param lhs  the lhs operand.
247      * @param rhs  the rhs operand.
248      */
249     public JOrOp(int line, JExpression lhs, JExpression rhs) {
250         super(line, "|", lhs, rhs);
251     }
252 
253     /**
254      * {@inheritDoc}
255      */
256     public JExpression analyze(Context context) {
257         // TODO
258         return this;
259     }
260 
261     /**
262      * {@inheritDoc}
263      */
264     public void codegen(CLEmitter output) {
265         // TODO
266     }
267 }
268 
269 /**
270  * The AST node for an exclusive or (^) expression.
271  */
272 class JXorOp extends JBinaryExpression {
273     /**
274      * Constructs an AST node for an exclusive or expression.
275      *
276      * @param line line in which the exclusive or expression occurs in the source file.
277      * @param lhs  the lhs operand.
278      * @param rhs  the rhs operand.
279      */
280     public JXorOp(int line, JExpression lhs, JExpression rhs) {
281         super(line, "^", lhs, rhs);
282     }
283 
284     /**
285      * {@inheritDoc}
286      */
287     public JExpression analyze(Context context) {
288         // TODO
289         return this;
290     }
291 
292     /**
293      * {@inheritDoc}
294      */
295     public void codegen(CLEmitter output) {
296         // TODO
297     }
298 }
299 
300 /**
301  * The AST node for an and (&) expression.
302  */
303 class JAndOp extends JBinaryExpression {
304     /**
305      * Constructs an AST node for an and expression.
306      *
307      * @param line line in which the and expression occurs in the source file.
308      * @param lhs  the lhs operand.
309      * @param rhs  the rhs operand.
310      */
311     public JAndOp(int line, JExpression lhs, JExpression rhs) {
312         super(line, "&", lhs, rhs);
313     }
314 
315     /**
316      * {@inheritDoc}
317      */
318     public JExpression analyze(Context context) {
319         // TODO
320         return this;
321     }
322 
323     /**
324      * {@inheritDoc}
325      */
326     public void codegen(CLEmitter output) {
327         // TODO
328     }
329 }
330 
331 /**
332  * The AST node for an arithmetic left shift (<<) expression.
333  */
334 class JALeftShiftOp extends JBinaryExpression {
335     /**
336      * Constructs an AST node for an arithmetic left shift expression.
337      *
338      * @param line line in which the arithmetic left shift expression occurs in the source file.
339      * @param lhs  the lhs operand.
340      * @param rhs  the rhs operand.
341      */
342     public JALeftShiftOp(int line, JExpression lhs, JExpression rhs) {
343         super(line, "<<", lhs, rhs);
344     }
345 
346     /**
347      * {@inheritDoc}
348      */
349     public JExpression analyze(Context context) {
350         // TODO
351         return this;
352     }
353 
354     /**
355      * {@inheritDoc}
356      */
357     public void codegen(CLEmitter output) {
358         // TODO
359     }
360 }
361 
362 /**
363  * The AST node for an arithmetic right shift (&rt;&rt;) expression.
364  */
365 class JARightShiftOp extends JBinaryExpression {
366     /**
367      * Constructs an AST node for an arithmetic right shift expression.
368      *
369      * @param line line in which the arithmetic right shift expression occurs in the source file.
370      * @param lhs  the lhs operand.
371      * @param rhs  the rhs operand.
372      */
373     public JARightShiftOp(int line, JExpression lhs, JExpression rhs) {
374         super(line, ">>", lhs, rhs);
375     }
376 
377     /**
378      * {@inheritDoc}
379      */
380     public JExpression analyze(Context context) {
381         // TODO
382         return this;
383     }
384 
385     /**
386      * {@inheritDoc}
387      */
388     public void codegen(CLEmitter output) {
389         // TODO
390     }
391 }
392 
393 /**
394  * The AST node for a logical right shift (&rt;&rt;&rt;) expression.
395  */
396 class JLRightShiftOp extends JBinaryExpression {
397     /**
398      * Constructs an AST node for a logical right shift expression.
399      *
400      * @param line line in which the logical right shift expression occurs in the source file.
401      * @param lhs  the lhs operand.
402      * @param rhs  the rhs operand.
403      */
404     public JLRightShiftOp(int line, JExpression lhs, JExpression rhs) {
405         super(line, ">>>", lhs, rhs);
406     }
407 
408     /**
409      * {@inheritDoc}
410      */
411     public JExpression analyze(Context context) {
412         // TODO
413         return this;
414     }
415 
416     /**
417      * {@inheritDoc}
418      */
419     public void codegen(CLEmitter output) {
420         // TODO
421     }
422 }
423