return sbuf.toString();
}
+ protected static int jvmTypeNameToExprType(char type) {
+ switch(type) {
+ case 'Z' :
+ return BOOLEAN;
+ case 'B' :
+ return BYTE;
+ case 'C' :
+ return CHAR;
+ case 'S' :
+ return SHORT;
+ case 'I' :
+ return INT;
+ case 'J' :
+ return LONG;
+ case 'F' :
+ return FLOAT;
+ case 'D' :
+ return DOUBLE;
+ case 'V' :
+ return VOID;
+ default :
+ return CLASS;
+ }
+ }
public void atASTList(ASTList n) throws CompileError { fatal(); }
*/
protected void atCastToRtype(CastExpr expr) throws CompileError {
expr.getOprand().accept(this);
- if (!isRefType(exprType) || arrayDim > 0)
- throw new CompileError("invalid type for " + returnCastName);
-
- compileUnwrapValue(returnType, bytecode);
+ if (exprType == VOID || isRefType(exprType) || arrayDim > 0)
+ compileUnwrapValue(returnType, bytecode);
+ else if (returnType instanceof CtPrimitiveType) {
+ CtPrimitiveType pt = (CtPrimitiveType)returnType;
+ int destType = jvmTypeNameToExprType(pt.getDescriptor());
+ atNumCastExpr(exprType, destType);
+ exprType = destType;
+ arrayDim = 0;
+ className = null;
+ }
+ else
+ throw new CompileError("invalid cast");
}
protected void atCastToWrapper(CastExpr expr) throws CompileError {
protected void compileUnwrapValue(CtClass type, Bytecode code)
throws CompileError
{
+ if (type == CtClass.voidType) {
+ addNullIfVoid();
+ return;
+ }
+
+ if (exprType == VOID)
+ throw new CompileError("invalid type for " + returnCastName);
+
if (type instanceof CtPrimitiveType) {
CtPrimitiveType pt = (CtPrimitiveType)type;
- if (pt != CtClass.voidType) {
- String wrapper = pt.getWrapperName();
- code.addCheckcast(wrapper);
- code.addInvokevirtual(wrapper, pt.getGetMethodName(),
- pt.getGetMethodDescriptor());
- setType(type);
- }
+ // pt is not voidType.
+ String wrapper = pt.getWrapperName();
+ code.addCheckcast(wrapper);
+ code.addInvokevirtual(wrapper, pt.getGetMethodName(),
+ pt.getGetMethodDescriptor());
+ setType(type);
}
else {
code.addCheckcast(type);
$_ = ($r)result;</pre></ul>
<p>If the result type is a primitive type, then <code>($r)</code>
-converts from the wrapper type to the primitive type.
+follows special semantics. First, if the operand type of the cast
+expression is a primitive type, <code>($r)</code> works as a normal
+cast operator to the result type.
+On the other hand, if the operand type is a wrapper type,
+<code>($r)</code> converts from the wrapper type to the result type.
For example, if the result type is <code>int</code>, then
<code>($r)</code> converts from <code>java.lang.Integer</code> to
<code>int</code>.
<p>If the result type is <code>void</code>, then
<code>($r)</code> does not convert a type; it does nothing.
-Moreover, the soruce text can include a <code>return</code>
-statement with a resulting value:
+However, if the operand is a call to a <code>void</code> method,
+then <code>($r)</code> results in <code>null</code>. For example,
+
+<ul><pre>$_ = ($r)foo();</pre></ul>
+
+<p>is a valid statement if the result type is <code>void</code>.
+Here, <code>foo()</code> is a <code>void</code> method.
+
+<p>The cast operator <code>($r)</code> is also useful in a
+<code>return</code> statement. Even if the result type is
+<code>void</code>, the following <code>return</code> statement is valid:
<ul><pre>return ($r)result;</pre></ul>