1
3 package jminusminus;
4
5 import static jminusminus.CLConstants.*;
6
7
12 class JStringConcatenationOp extends JBinaryExpression {
13
20 public JStringConcatenationOp(int line, JExpression lhs, JExpression rhs) {
21 super(line, "+", lhs, rhs);
22 }
23
24
27 public JExpression analyze(Context context) {
28 type = Type.STRING;
29 return this;
30 }
31
32
35 public void codegen(CLEmitter output) {
36 output.addReferenceInstruction(NEW, "java/lang/StringBuilder");
38 output.addNoArgInstruction(DUP);
39 output.addMemberAccessInstruction(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
40 "()V");
41
42 nestedCodegen(output);
44
45 output.addMemberAccessInstruction(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
47 "()Ljava/lang/String;");
48 }
49
50 private void nestedCodegen(CLEmitter output) {
53 if (lhs instanceof JStringConcatenationOp) {
55 ((JStringConcatenationOp) lhs).nestedCodegen(output);
57 } else {
58 lhs.codegen(output);
59 output.addMemberAccessInstruction(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
60 "(" + lhs.type().argumentTypeForAppend() + ")Ljava/lang/StringBuilder;");
61 }
62
63 if (rhs instanceof JStringConcatenationOp) {
65 ((JStringConcatenationOp) rhs).nestedCodegen(output);
67 } else {
68 rhs.codegen(output);
69 output.addMemberAccessInstruction(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
70 "(" + rhs.type().argumentTypeForAppend() + ")Ljava/lang/StringBuilder;");
71 }
72 }
73 }
74