1
3 package jminusminus;
4
5 import static jminusminus.CLConstants.*;
6
7
11 class JArrayExpression extends JExpression implements JLhs {
12 private JExpression theArray;
14
15 private JExpression indexExpr;
17
18
25 public JArrayExpression(int line, JExpression theArray, JExpression indexExpr) {
26 super(line);
27 this.theArray = theArray;
28 this.indexExpr = indexExpr;
29 }
30
31
34 public JExpression analyze(Context context) {
35 theArray = (JExpression) theArray.analyze(context);
36 indexExpr = (JExpression) indexExpr.analyze(context);
37 if (!(theArray.type().isArray())) {
38 JAST.compilationUnit.reportSemanticError(line(), "attempt to index a non-array object");
39 this.type = Type.ANY;
40 } else {
41 this.type = theArray.type().componentType();
42 }
43 indexExpr.type().mustMatchExpected(line(), Type.INT);
44 return this;
45 }
46
47
50 public JExpression analyzeLhs(Context context) {
51 analyze(context);
52 return this;
53 }
54
55
58 public void codegen(CLEmitter output) {
59 theArray.codegen(output);
60 indexExpr.codegen(output);
61 if (type == Type.INT) {
62 output.addNoArgInstruction(IALOAD);
63 } else if (type == Type.BOOLEAN) {
64 output.addNoArgInstruction(BALOAD);
65 } else if (type == Type.CHAR) {
66 output.addNoArgInstruction(CALOAD);
67 } else if (!type.isPrimitive()) {
68 output.addNoArgInstruction(AALOAD);
69 }
70 }
71
72
75 public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
76 codegen(output);
77 if (onTrue) {
78 output.addBranchInstruction(IFNE, targetLabel);
79 } else {
80 output.addBranchInstruction(IFEQ, targetLabel);
81 }
82 }
83
84
87 public void codegenLoadLhsLvalue(CLEmitter output) {
88 theArray.codegen(output);
89 indexExpr.codegen(output);
90 }
91
92
95 public void codegenLoadLhsRvalue(CLEmitter output) {
96 if (type == Type.STRING) {
97 output.addNoArgInstruction(DUP2_X1);
98 } else {
99 output.addNoArgInstruction(DUP2);
100 }
101 if (type == Type.INT) {
102 output.addNoArgInstruction(IALOAD);
103 } else if (type == Type.BOOLEAN) {
104 output.addNoArgInstruction(BALOAD);
105 } else if (type == Type.CHAR) {
106 output.addNoArgInstruction(CALOAD);
107 } else if (!type.isPrimitive()) {
108 output.addNoArgInstruction(AALOAD);
109 }
110 }
111
112
115 public void codegenDuplicateRvalue(CLEmitter output) {
116 output.addNoArgInstruction(DUP_X2);
117 }
118
119
122 public void codegenStore(CLEmitter output) {
123 if (type == Type.INT) {
124 output.addNoArgInstruction(IASTORE);
125 } else if (type == Type.BOOLEAN) {
126 output.addNoArgInstruction(BASTORE);
127 } else if (type == Type.CHAR) {
128 output.addNoArgInstruction(CASTORE);
129 } else if (!type.isPrimitive()) {
130 output.addNoArgInstruction(AASTORE);
131 }
132 }
133
134
137 public void toJSON(JSONElement json) {
138 JSONElement e = new JSONElement();
139 json.addChild("JArrayExpression:" + line, e);
140 JSONElement e1 = new JSONElement();
141 e.addChild("TheArray", e1);
142 theArray.toJSON(e1);
143 JSONElement e2 = new JSONElement();
144 e.addChild("TheIndex", e2);
145 indexExpr.toJSON(e2);
146 }
147 }
148