| JBinaryExpression.java |
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