1
3 package jminusminus;
4
5 import static jminusminus.CLConstants.*;
6
7
11
12 class JInstanceOfOp
13 extends JExpression {
14
15
16 private JExpression expr;
17
18
19 private Type typeSpec;
20
21
35
36 public JInstanceOfOp(int line, JExpression expr, Type typeSpec) {
37 super(line);
38 this.expr = expr;
39 this.typeSpec = typeSpec;
40 }
41
42
52
53 public JInstanceOfOp analyze(Context context) {
54 expr = (JExpression) expr.analyze(context);
55 typeSpec = typeSpec.resolve(context);
56 if (!typeSpec.isReference()) {
57 JAST.compilationUnit.reportSemanticError(line(),
58 "Type argument to instanceof "
59 + "operator must be a reference type");
60 } else if (!(expr.type() == Type.NULLTYPE
61 || expr.type() == Type.ANY || expr.type().isReference())) {
62 JAST.compilationUnit.reportSemanticError(line(),
63 "operand to instanceof "
64 + "operator must be a reference type");
65 } else if (expr.type().isReference()
66 && !typeSpec.isJavaAssignableFrom(expr.type())) {
67 JAST.compilationUnit.reportSemanticError(line(),
68 "It is impossible for the expression "
69 + "to be an instance of this type");
70 }
71 type = Type.BOOLEAN;
72 return this;
73 }
74
75
82
83 public void codegen(CLEmitter output) {
84 expr.codegen(output);
85 output.addReferenceInstruction(INSTANCEOF, typeSpec
86 .toDescriptor());
87 }
88
89
99
100 public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
101 codegen(output);
102 if (onTrue) {
103 output.addBranchInstruction(IFNE, targetLabel);
105 } else {
106 output.addBranchInstruction(IFEQ, targetLabel);
108 }
109 }
110
111
114
115 public void writeToStdOut(PrettyPrinter p) {
116 p.printf("<JInstanceOfOp line=\"%d\" type=\"%s\">\n", line(),
117 ((type == null) ? "" : type.toString()));
118 p.indentRight();
119 p.printf("<RelationalExpression>\n");
120 p.indentRight();
121 expr.writeToStdOut(p);
122 p.indentLeft();
123 p.printf("</RelationalExpression>\n");
124 p.printf("<ReferenceType value=\"%s\"/>\n",
125 ((typeSpec == null) ? "" : typeSpec.toString()));
126 p.indentLeft();
127 p.printf("</JInstanceOfOp>\n");
128 }
129 }
130