📄 evaluator.java
字号:
break;
case ExpressionLexerTokenTypes.UNARY_MINUS:
result = processUnaryMinus(leftValue);
break;
case ExpressionLexerTokenTypes.UNARY_PLUS:
result = leftValue;
break;
// Binary operations.
// We can optimize some boolean operations.
case ExpressionLexerTokenTypes.LOGICAL_AND:
result = processLogicalAnd(leftValue, right);
break;
case ExpressionLexerTokenTypes.LOGICAL_OR:
result = processLogicalOr(leftValue, right);
break;
default:
{
Object rightValue = process(right);
switch (node.getType())
{
case ExpressionLexerTokenTypes.BITWISE_AND:
result = processBitwiseAnd(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.BITWISE_OR:
result = processBitwiseOr(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.BITWISE_XOR:
result = processXor(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.PLUS:
result = processPlus(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.MINUS:
result = processMinus(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.STAR:
result = processMultiply(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.DIV:
result = processDivide(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.MOD:
result = processMod(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.SHIFT_LEFT:
result = processShiftLeft(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.SHIFT_RIGHT:
result = processShiftRight(leftValue, rightValue);
break;
case ExpressionLexerTokenTypes.EQUAL:
case ExpressionLexerTokenTypes.UNEQUAL:
case ExpressionLexerTokenTypes.LESS_THAN:
case ExpressionLexerTokenTypes.GREATER_THAN:
case ExpressionLexerTokenTypes.LESS_THAN_EQUAL:
case ExpressionLexerTokenTypes.GREATER_THAN_EQUAL:
result = processRelation(leftValue, rightValue, node.getType());
break;
default:
throw EvaluationException.create(node);
}
}
}
}
}
}
catch (NumberFormatException e)
{
throw new EvaluationException(e.getMessage());
}
return result;
}
}
//------------------------------------------------------------------------------------------------
/**
* Converts a string literal, which can be a composition of one or more string parts each
* enclosed in double quotes and separated by zero or more space or tabulator characters.
*
* @param literal The string literal to process.
* @return A single string without quotes with all literal parts concatenated.
*/
private static String processStringLiteral(String literal)
{
StringBuffer result = new StringBuffer();
int subStringEnd = -1;
do
{
int subStringStart = literal.indexOf('"', subStringEnd + 1);
subStringEnd = literal.indexOf('"', subStringStart + 1);
result.append(literal.substring(subStringStart + 1, subStringEnd));
}
while (subStringEnd < literal.length() - 1);
return result.toString();
}
//------------------------------------------------------------------------------------------------
/**
* Computes the bitwise and between both values.
*
* @param leftValue An integer value.
* @param rightValue A second integer value.
* @return The result of the computation. It is always of type Integer.
*/
private static Object processBitwiseAnd(Object leftValue, Object rightValue)
{
checkInteger(leftValue);
checkInteger(rightValue);
Number leftNumber = (Number)leftValue;
Number rightNumber = (Number)rightValue;
return new Integer(leftNumber.intValue() & rightNumber.intValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the bitwise negation of the input value.
*
* @param leftValue An integer value.
*
* @return The bitwise negation of the input.
*/
private static Object processBitwiseNot(Object leftValue)
{
checkInteger(leftValue);
Number value = (Number)leftValue;
if (value instanceof Byte)
return new Byte((byte)~value.byteValue());
else
if (value instanceof Integer)
return new Integer(~value.intValue());
else
if (value instanceof Long)
return new Long(~value.longValue());
else
return new Short((short)(~value.shortValue()));
}
//------------------------------------------------------------------------------------------------
/**
* Computes the bitwise or between both values.
*
* @param leftValue An integer value.
* @param rightValue A second integer value.
* @return The result of the computation. It is always of type Integer.
*/
private static Object processBitwiseOr(Object leftValue, Object rightValue)
{
checkInteger(leftValue);
checkInteger(rightValue);
Number leftNumber = (Number)leftValue;
Number rightNumber = (Number)rightValue;
return new Integer(leftNumber.intValue() | rightNumber.intValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the decrement of the input value.
*
* @param leftValue An integer value.
* @return The input value - 1.
*/
private static Object processDec(Object leftValue)
{
checkInteger(leftValue);
Number value = (Number)leftValue;
if (value instanceof Byte)
return new Byte((byte)(value.byteValue() - 1));
else
if (value instanceof Integer)
return new Integer(value.intValue() - 1);
else
if (value instanceof Long)
return new Long(value.longValue() - 1);
else
return new Short((short)(value.shortValue() - 1));
}
//------------------------------------------------------------------------------------------------
/**
* Computes the division of both input values.
*
* @param leftValue Any number value.
* @param rightValue Any number value.
* @return The result is a double value if any of the values is a float value. For byte, int,
* short and long Long is returned.
*/
private static Object processDivide(Object leftValue, Object rightValue)
{
checkNumber(leftValue);
checkNumber(rightValue);
// Float types.
if (isFloat(leftValue) || isFloat(rightValue))
return new Double(((Number)leftValue).doubleValue() / ((Number)rightValue).doubleValue());
else
// Integer values.
return new Long(((Number)leftValue).longValue() / ((Number)rightValue).longValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the increment of the input value.
*
* @param leftValue An integer value.
* @return The input value + 1.
*/
private static Object processInc(Object leftValue)
{
checkInteger(leftValue);
Number value = (Number)leftValue;
if (value instanceof Byte)
return new Byte((byte)(value.byteValue() + 1));
else
if (value instanceof Integer)
return new Integer(value.intValue() + 1);
else
if (value instanceof Long)
return new Long(value.longValue() + 1);
else
return new Short((short)(value.shortValue() + 1));
}
//------------------------------------------------------------------------------------------------
/**
* Computes the result of doing leftValue && rightValue.
*
* @param leftValue A boolean value.
* @param right The AST node of the second value. It has not yet been processed in case we can
* take the short path (if leftValue is false).
* @return The result of the computation.
*/
private static Object processLogicalAnd(Object leftValue, AST right)
{
checkBoolean(leftValue);
// Optimize evaluation here. Return immediately if leftValue is already false, otherwise
// evaluate also right to a value and do the and'ing.
if (!((Boolean)leftValue).booleanValue())
return new Boolean(false);
Object rightValue = process(right);
checkBoolean(rightValue);
return new Boolean(((Boolean)leftValue).booleanValue() && ((Boolean)rightValue).booleanValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the logical negation of the input value.
*
* @param leftValue A boolean value.
*
* @return The logical negation of the input.
*/
private static Object processLogicalNot(Object leftValue)
{
if (isInteger(leftValue))
{
return new Boolean(((Number) leftValue).intValue() == 0);
}
else
{
checkType(leftValue, Boolean.class);
return new Boolean(!((Boolean)leftValue).booleanValue());
}
}
//------------------------------------------------------------------------------------------------
/**
* Computes the result of doing leftValue || rightValue.
*
* @param leftValue A boolean value.
* @param right The AST node of the second value. It has not yet been processed in case we can
* take the short path (if leftValue is true).
* @return The result of the computation.
*/
private static Object processLogicalOr(Object leftValue, AST right)
{
checkBoolean(leftValue);
// Optimize evaluation here. Return immediately if leftValue is already true, otherwise
// evaluate also right to a value and do the or'ing.
if (((Boolean)leftValue).booleanValue())
return new Boolean(true);
Object rightValue = process(right);
checkBoolean(rightValue);
return new Boolean(((Boolean)leftValue).booleanValue() || ((Boolean)rightValue).booleanValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the difference of both input values.
*
* @param leftValue Any number value.
* @param rightValue Any number value.
* @return The result is a double value if any of the values is a float value. For byte, int,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -