1
3 package jminusminus;
4
5 import java.util.ArrayList;
6 import static jminusminus.CLConstants.*;
7
8
12
13 class JNewOp extends JExpression {
14
15
16 private Constructor constructor;
17
18
19 private ArrayList<JExpression> arguments;
20
21
22 private Type[] argTypes;
23
24
35
36 public JNewOp(int line, Type type, ArrayList<JExpression> arguments) {
37 super(line);
38 this.type = type;
39 this.arguments = arguments;
40 }
41
42
51
52 public JExpression analyze(Context context) {
53 type = type.resolve(context);
55
56 argTypes = new Type[arguments.size()];
59 for (int i = 0; i < arguments.size(); i++) {
60 arguments.set(i, (JExpression) arguments.get(i).analyze(context));
61 argTypes[i] = arguments.get(i).type();
62 }
63
64 if (type.isAbstract()) {
66 JAST.compilationUnit.reportSemanticError(line(),
67 "Cannot instantiate an abstract type:" + type.toString());
68 }
69
70
76 constructor = type.constructorFor(argTypes);
78
79 if (constructor == null) {
80 JAST.compilationUnit.reportSemanticError(line(),
81 "Cannot find constructor: "
82 + Type.signatureFor(type.toString(), argTypes));
83 }
84 return this;
85 }
86
87
97
98 public void codegen(CLEmitter output) {
99 output.addReferenceInstruction(NEW, type.jvmName());
100 output.addNoArgInstruction(DUP);
101 for (JExpression argument : arguments) {
102 argument.codegen(output);
103 }
104 output.addMemberAccessInstruction(INVOKESPECIAL, type.jvmName(),
105 "<init>", constructor.toDescriptor());
106 }
107
108
111
112 public void writeToStdOut(PrettyPrinter p) {
113 p.printf("<JNewOp line=\"%d\" type=\"%s\"/>\n", line(),
114 ((type == null) ? "" : type.toString()));
115 p.indentRight();
116 if (arguments != null) {
117 p.println("<Arguments>");
118 for (JExpression argument : arguments) {
119 p.indentRight();
120 p.println("<Argument>");
121 p.indentRight();
122 argument.writeToStdOut(p);
123 p.indentLeft();
124 p.println("</Argument>");
125 p.indentLeft();
126 }
127 p.println("</Arguments>");
128 }
129 p.indentLeft();
130 p.println("</JNewOp>");
131 }
132
133 }
134