001: /*****************************************************************************
002: * *
003: * This file is part of the BeanShell Java Scripting distribution. *
004: * Documentation and updates may be found at http://www.beanshell.org/ *
005: * *
006: * Sun Public License Notice: *
007: * *
008: * The contents of this file are subject to the Sun Public License Version *
009: * 1.0 (the "License"); you may not use this file except in compliance with *
010: * the License. A copy of the License is available at http://www.sun.com *
011: * *
012: * The Original Code is BeanShell. The Initial Developer of the Original *
013: * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
014: * (C) 2000. All Rights Reserved. *
015: * *
016: * GNU Public License Notice: *
017: * *
018: * Alternatively, the contents of this file may be used under the terms of *
019: * the GNU Lesser General Public License (the "LGPL"), in which case the *
020: * provisions of LGPL are applicable instead of those above. If you wish to *
021: * allow use of your version of this file only under the terms of the LGPL *
022: * and not to allow others to use your version of this file under the SPL, *
023: * indicate your decision by deleting the provisions above and replace *
024: * them with the notice and other provisions required by the LGPL. If you *
025: * do not delete the provisions above, a recipient may use your version of *
026: * this file under either the SPL or the LGPL. *
027: * *
028: * Patrick Niemeyer (pat@pat.net) *
029: * Author of Learning Java, O'Reilly & Associates *
030: * http://www.pat.net/~pat/ *
031: * *
032: *****************************************************************************/package bsh;
033:
034: class BSHUnaryExpression extends SimpleNode implements ParserConstants {
035: public int kind;
036: public boolean postfix = false;
037:
038: BSHUnaryExpression(int id) {
039: super (id);
040: }
041:
042: public Object eval(CallStack callstack, Interpreter interpreter)
043: throws EvalError {
044: SimpleNode node = (SimpleNode) jjtGetChild(0);
045:
046: // If this is a unary increment of decrement (either pre or postfix)
047: // then we need an LHS to which to assign the result. Otherwise
048: // just do the unary operation for the value.
049: try {
050: if (kind == INCR || kind == DECR) {
051: LHS lhs = ((BSHPrimaryExpression) node).toLHS(
052: callstack, interpreter);
053: return lhsUnaryOperation(lhs, interpreter
054: .getStrictJava());
055: } else
056: return unaryOperation(
057: node.eval(callstack, interpreter), kind);
058: } catch (UtilEvalError e) {
059: throw e.toEvalError(this , callstack);
060: }
061: }
062:
063: private Object lhsUnaryOperation(LHS lhs, boolean strictJava)
064: throws UtilEvalError {
065: if (Interpreter.DEBUG)
066: Interpreter.debug("lhsUnaryOperation");
067: Object prevalue, postvalue;
068: prevalue = lhs.getValue();
069: postvalue = unaryOperation(prevalue, kind);
070:
071: Object retVal;
072: if (postfix)
073: retVal = prevalue;
074: else
075: retVal = postvalue;
076:
077: lhs.assign(postvalue, strictJava);
078: return retVal;
079: }
080:
081: private Object unaryOperation(Object op, int kind)
082: throws UtilEvalError {
083: if (op instanceof Boolean || op instanceof Character
084: || op instanceof Number)
085: return primitiveWrapperUnaryOperation(op, kind);
086:
087: if (!(op instanceof Primitive))
088: throw new UtilEvalError("Unary operation "
089: + tokenImage[kind] + " inappropriate for object");
090:
091: return Primitive.unaryOperation((Primitive) op, kind);
092: }
093:
094: private Object primitiveWrapperUnaryOperation(Object val, int kind)
095: throws UtilEvalError {
096: Class operandType = val.getClass();
097: Object operand = Primitive.promoteToInteger(val);
098:
099: if (operand instanceof Boolean)
100: return Primitive.booleanUnaryOperation((Boolean) operand,
101: kind) ? Boolean.TRUE : Boolean.FALSE;
102: else if (operand instanceof Integer) {
103: int result = Primitive.intUnaryOperation((Integer) operand,
104: kind);
105:
106: // ++ and -- must be cast back the original type
107: if (kind == INCR || kind == DECR) {
108: if (operandType == Byte.TYPE)
109: return new Byte((byte) result);
110: if (operandType == Short.TYPE)
111: return new Short((short) result);
112: if (operandType == Character.TYPE)
113: return new Character((char) result);
114: }
115:
116: return new Integer(result);
117: } else if (operand instanceof Long)
118: return new Long(Primitive.longUnaryOperation(
119: (Long) operand, kind));
120: else if (operand instanceof Float)
121: return new Float(Primitive.floatUnaryOperation(
122: (Float) operand, kind));
123: else if (operand instanceof Double)
124: return new Double(Primitive.doubleUnaryOperation(
125: (Double) operand, kind));
126: else
127: throw new InterpreterError(
128: "An error occurred. Please call technical support.");
129: }
130: }
|