1
3 package jminusminus;
4
5 import static jminusminus.CLConstants.*;
6
7
11 class JInstanceOfOp extends JExpression {
12 private JExpression expr;
14
15 private Type typeSpec;
17
18
25 public JInstanceOfOp(int line, JExpression expr, Type typeSpec) {
26 super(line);
27 this.expr = expr;
28 this.typeSpec = typeSpec;
29 }
30
31
34 public JInstanceOfOp analyze(Context context) {
35 expr = (JExpression) expr.analyze(context);
36 typeSpec = typeSpec.resolve(context);
37 if (!typeSpec.isReference()) {
38 JAST.compilationUnit.reportSemanticError(line(),
39 "RHS of instanceof must be a reference type");
40 } else if (!(expr.type() == Type.NULLTYPE || expr.type() == Type.ANY ||
41 expr.type().isReference())) {
42 JAST.compilationUnit.reportSemanticError(line(),
43 "LHS of instanceof must be a reference type");
44 } else if (expr.type().isReference() && !typeSpec.isJavaAssignableFrom(expr.type()) &&
45 !expr.type().isJavaAssignableFrom(typeSpec)) {
46 JAST.compilationUnit.reportSemanticError(line(),
47 "It is impossible for the expression to be an instance of " +
48 typeSpec.toString());
49 }
50 type = Type.BOOLEAN;
51 return this;
52 }
53
54
57 public void codegen(CLEmitter output) {
58 expr.codegen(output);
59 output.addReferenceInstruction(INSTANCEOF, typeSpec.jvmName());
60 }
61
62
65 public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
66 codegen(output);
67 if (onTrue) {
68 output.addBranchInstruction(IFNE, targetLabel);
69 } else {
70 output.addBranchInstruction(IFEQ, targetLabel);
71 }
72 }
73
74
77 public void toJSON(JSONElement json) {
78 JSONElement e = new JSONElement();
79 json.addChild("JInstanceOfOp:" + line, e);
80 e.addAttribute("type", type == null ? "" : type.toString());
81 e.addAttribute("referenceType", typeSpec == null ? "" : typeSpec.toString());
82 JSONElement e1 = new JSONElement();
83 e.addChild("Expression", e1);
84 expr.toJSON(e1);
85 }
86 }
87