1
3 package jminusminus;
4
5 import static jminusminus.CLConstants.*;
6
7
11 class JReturnStatement extends JStatement {
12 private JExpression expr;
14
15
21 public JReturnStatement(int line, JExpression expr) {
22 super(line);
23 this.expr = expr;
24 }
25
26
29 public JStatement analyze(Context context) {
30 MethodContext methodContext = context.methodContext();
31
32 if (methodContext.methodReturnType() == Type.CONSTRUCTOR) {
37 if (expr != null) {
38 JAST.compilationUnit.reportSemanticError(line(),
40 "Cannot return a value from a constructor");
41 }
42 } else {
43 Type returnType = methodContext.methodReturnType();
45 methodContext.confirmMethodHasReturn();
46 if (expr != null) {
47 if (returnType == Type.VOID) {
48 JAST.compilationUnit.reportSemanticError(line(),
50 "Cannot return a value from a void method");
51 } else {
52 expr = expr.analyze(context);
55 expr.type().mustMatchExpected(line(), returnType);
56 }
57 } else {
58 if (returnType != Type.VOID) {
60 JAST.compilationUnit.reportSemanticError(line(), "Missing return value");
61 }
62 }
63 }
64 return this;
65 }
66
67
70 public void codegen(CLEmitter output) {
71 if (expr == null) {
72 output.addNoArgInstruction(RETURN);
73 } else {
74 expr.codegen(output);
75 if (expr.type() == Type.INT || expr.type() == Type.BOOLEAN ||
76 expr.type() == Type.CHAR) {
77 output.addNoArgInstruction(IRETURN);
78 } else {
79 output.addNoArgInstruction(ARETURN);
80 }
81 }
82 }
83
84
87 public void toJSON(JSONElement json) {
88 JSONElement e = new JSONElement();
89 json.addChild("JReturnStatement:" + line, e);
90 if (expr != null) {
91 JSONElement e1 = new JSONElement();
92 e.addChild("Expression", e1);
93 expr.toJSON(e1);
94 }
95 }
96 }
97