/*****************************************************************************
* *
* This file is part of the BeanShell Java Scripting distribution. *
* Documentation and updates may be found at http://www.beanshell.org/ *
* *
* Sun Public License Notice: *
* *
* The contents of this file are subject to the Sun Public License Version *
* 1.0 (the "License"); you may not use this file except in compliance with *
* the License. A copy of the License is available at http://www.sun.com *
* *
* The Original Code is BeanShell. The Initial Developer of the Original *
* Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
* (C) 2000. All Rights Reserved. *
* *
* GNU Public License Notice: *
* *
* Alternatively, the contents of this file may be used under the terms of *
* the GNU Lesser General Public License (the "LGPL"), in which case the *
* provisions of LGPL are applicable instead of those above. If you wish to *
* allow use of your version of this file only under the terms of the LGPL *
* and not to allow others to use your version of this file under the SPL, *
* indicate your decision by deleting the provisions above and replace *
* them with the notice and other provisions required by the LGPL. If you *
* do not delete the provisions above, a recipient may use your version of *
* this file under either the SPL or the LGPL. *
* *
* Patrick Niemeyer (pat@pat.net) *
* Author of Learning Java, O'Reilly & Associates *
* http://www.pat.net/~pat/ *
* *
*****************************************************************************/
package bsh;
class
BSHUnaryExpression extends
SimpleNode implements
ParserConstants
{
public int
kind;
public boolean
postfix = false;
BSHUnaryExpression(int
id) { super(
id); }
public
Object eval(
CallStack callstack,
Interpreter interpreter)
throws
EvalError
{
SimpleNode node = (
SimpleNode)
jjtGetChild(0);
// If this is a unary increment of decrement (either pre or postfix)
// then we need an LHS to which to assign the result. Otherwise
// just do the unary operation for the value.
try {
if (
kind ==
INCR ||
kind ==
DECR ) {
LHS lhs = ((
BSHPrimaryExpression)
node).
toLHS(
callstack,
interpreter );
return
lhsUnaryOperation(
lhs,
interpreter.
getStrictJava() );
} else
return
unaryOperation(
node.
eval(
callstack,
interpreter),
kind );
} catch (
UtilEvalError e ) {
throw
e.
toEvalError( this,
callstack );
}
}
private
Object lhsUnaryOperation(
LHS lhs, boolean
strictJava )
throws
UtilEvalError
{
if (
Interpreter.
DEBUG )
Interpreter.
debug("lhsUnaryOperation");
Object prevalue,
postvalue;
prevalue =
lhs.
getValue();
postvalue =
unaryOperation(
prevalue,
kind);
Object retVal;
if (
postfix )
retVal =
prevalue;
else
retVal =
postvalue;
lhs.
assign(
postvalue,
strictJava );
return
retVal;
}
private
Object unaryOperation(
Object op, int
kind ) throws
UtilEvalError
{
if (
op instanceof
Boolean ||
op instanceof
Character
||
op instanceof
Number)
return
primitiveWrapperUnaryOperation(
op,
kind );
if ( !(
op instanceof
Primitive) )
throw new
UtilEvalError( "Unary operation " +
tokenImage[
kind]
+ " inappropriate for object" );
return
Primitive.
unaryOperation((
Primitive)
op,
kind);
}
private
Object primitiveWrapperUnaryOperation(
Object val, int
kind)
throws
UtilEvalError
{
Class operandType =
val.
getClass();
Object operand =
Primitive.
promoteToInteger(
val);
if (
operand instanceof
Boolean )
return new
Boolean(
Primitive.
booleanUnaryOperation((
Boolean)
operand,
kind));
else
if (
operand instanceof
Integer )
{
int
result =
Primitive.
intUnaryOperation((
Integer)
operand,
kind);
// ++ and -- must be cast back the original type
if(
kind ==
INCR ||
kind ==
DECR)
{
if(
operandType ==
Byte.
TYPE)
return new
Byte((byte)
result);
if(
operandType ==
Short.
TYPE)
return new
Short((short)
result);
if(
operandType ==
Character.
TYPE)
return new
Character((char)
result);
}
return new
Integer(
result);
}
else if(
operand instanceof
Long)
return new
Long(
Primitive.
longUnaryOperation((
Long)
operand,
kind));
else if(
operand instanceof
Float)
return new
Float(
Primitive.
floatUnaryOperation((
Float)
operand,
kind));
else if(
operand instanceof
Double)
return new
Double(
Primitive.
doubleUnaryOperation((
Double)
operand,
kind));
else
throw new
InterpreterError("An error occurred. Please call technical support.");
}
}