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