📄 evaluator.java
字号:
* short and long Long is returned.
*/
private static Object processMinus(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 modulo of both input values.
*
* @param leftValue Any integer value.
* @param rightValue Any integer value.
* @return The result is a Long value.
*/
private static Object processMod(Object leftValue, Object rightValue)
{
checkInteger(leftValue);
checkInteger(rightValue);
// Integer values.
return new Long(((Number)leftValue).longValue() % ((Number)rightValue).longValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the multiplication 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 processMultiply(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 sum or concatenation of both input values.
*
* @param leftValue Any number or string/char value.
* @param rightValue Any number or string/char value.
* @return The result is a double value if any of the values is a float value (but the other must
* not be a string). For byte, int, short and long Long is returned and for string
* and character input a string output is genererated.
*/
private static Object processPlus(Object leftValue, Object rightValue)
{
// Start with string concatenation. No automatic conversion takes place. Both values must be
// strings or characters.
if (isString(leftValue) || isString(rightValue))
{
checkString(leftValue);
checkString(rightValue);
String left = (leftValue instanceof String) ? (String)leftValue : ((Character)leftValue).toString();
String right = (rightValue instanceof String) ? (String)rightValue : ((Character)rightValue).toString();
return (left + right);
}
else
{
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());
}
}
//------------------------------------------------------------------------------------------------
/**
* Evaluates both values with regard to the given logical operation. String types cannot be compared.
*
* @param leftValue Any number value.
* @param rightValue Any number value.
* @param operation The logical operation to perform.
* @return <b>true</b> if the relation turns out to be true, otherwise <b>false</b>.
*/
private static Object processRelation(Object leftValue, Object rightValue, int operation)
{
checkNumber(leftValue);
checkNumber(rightValue);
boolean useDouble = (leftValue instanceof Float) || (leftValue instanceof Double) ||
(rightValue instanceof Float) || (rightValue instanceof Double);
if (useDouble)
{
switch (operation)
{
case ExpressionLexerTokenTypes.EQUAL:
return new Boolean(((Number)leftValue).doubleValue() == ((Number)rightValue).doubleValue());
case ExpressionLexerTokenTypes.UNEQUAL:
return new Boolean(((Number)leftValue).doubleValue() != ((Number)rightValue).doubleValue());
case ExpressionLexerTokenTypes.LESS_THAN:
return new Boolean(((Number)leftValue).doubleValue() < ((Number)rightValue).doubleValue());
case ExpressionLexerTokenTypes.GREATER_THAN:
return new Boolean(((Number)leftValue).doubleValue() > ((Number)rightValue).doubleValue());
case ExpressionLexerTokenTypes.LESS_THAN_EQUAL:
return new Boolean(((Number)leftValue).doubleValue() <= ((Number)rightValue).doubleValue());
case ExpressionLexerTokenTypes.GREATER_THAN_EQUAL:
return new Boolean(((Number)leftValue).doubleValue() >= ((Number)rightValue).doubleValue());
default:
return new Boolean(false);
}
}
else
{
switch (operation)
{
case ExpressionLexerTokenTypes.EQUAL:
return new Boolean(((Number)leftValue).intValue() == ((Number)rightValue).intValue());
case ExpressionLexerTokenTypes.UNEQUAL:
return new Boolean(((Number)leftValue).intValue() != ((Number)rightValue).intValue());
case ExpressionLexerTokenTypes.LESS_THAN:
return new Boolean(((Number)leftValue).intValue() < ((Number)rightValue).intValue());
case ExpressionLexerTokenTypes.GREATER_THAN:
return new Boolean(((Number)leftValue).intValue() > ((Number)rightValue).intValue());
case ExpressionLexerTokenTypes.LESS_THAN_EQUAL:
return new Boolean(((Number)leftValue).intValue() <= ((Number)rightValue).intValue());
case ExpressionLexerTokenTypes.GREATER_THAN_EQUAL:
return new Boolean(((Number)leftValue).intValue() >= ((Number)rightValue).intValue());
default:
return new Boolean(false);
}
}
}
//------------------------------------------------------------------------------------------------
/**
* Shifts the left value by the number of digits given by the right value to the left.
*
* @param leftValue Any integer value.
* @param rightValue Any integer value.
* @return The result is a Long value.
*/
private static Object processShiftLeft(Object leftValue, Object rightValue)
{
checkInteger(leftValue);
checkInteger(rightValue);
// Integer values.
return new Long(((Number)leftValue).longValue() << ((Number)rightValue).longValue());
}
//------------------------------------------------------------------------------------------------
/**
* Shifts the left value by the number of digits given by the right value to the right.
*
* @param leftValue Any integer value.
* @param rightValue Any integer value.
* @return The result is a Long value.
*/
private static Object processShiftRight(Object leftValue, Object rightValue)
{
checkInteger(leftValue);
checkInteger(rightValue);
// Integer values.
return new Long(((Number)leftValue).longValue() >> ((Number)rightValue).longValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the negation of the input value.
*
* @param leftValue An numerical value.
* @return -leftValue.
*/
private static Object processUnaryMinus(Object leftValue)
{
checkNumber(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
if (value instanceof Short)
return new Short((short)(-value.shortValue()));
else
if (value instanceof Float)
return new Float(-value.floatValue());
else
return new Double(-value.doubleValue());
}
//------------------------------------------------------------------------------------------------
/**
* Computes the eclusive 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 processXor(Object leftValue, Object rightValue)
{
checkInteger(leftValue);
checkInteger(rightValue);
Number leftNumber = (Number)leftValue;
Number rightNumber = (Number)rightValue;
return new Integer(leftNumber.intValue() ^ rightNumber.intValue());
}
//------------------------------------------------------------------------------------------------
/**
* Throws an exception with the given message.
*
* @param message The message.
*/
private static void showError(String message)
{
throw new EvaluationException(message);
}
//------------------------------------------------------------------------------------------------
/**
* Takes the given abstract syntax tree and tries to evaluate it to one single value.
* The result will be a scalar type (Integer, String, Float etc.) or null if either expression
* is null or an error occured. Evaluation order is left to right.
*
* @param expression The abstract syntax tree into which the expression must be parsed.
* @param resolver An interface able to provide support for macro substitution.
* @param useImplicitSymbols When <b>true</b> then unresolvable symbols are considered as integers
* with a value of 0.
*
* @return An object, which encapsulates a scalar value.
*/
public static Object evaluate(AST expression, ISymbolTable symbolTable, boolean useImplicitSymbols)
{
symbols = symbolTable;
implicitSymbols = useImplicitSymbols;
Object result = null;
// The root node (the expression itself) is always a simple node without sibling and must be
// of type EXPR.
if (expression != null)
if (expression.getType() == ExpressionLexerTokenTypes.EXPR)
result = process(expression.getFirstChild());
else
result = process(expression);
return result;
}
//------------------------------------------------------------------------------------------------
/**
* Takes the given abstract syntax tree and tries to evaluate it to a boolean value.
*
* @param expression The abstract syntax tree into which the expression must be parsed.
* @param resolver An interface able to provide support for macro substitution.
* @param useImplicitSymbols When <b>true</b> then unresolvable symbols are considered as integers
* with a value of 0.
*
* @return <b>true</b>, if the expression either itself evaluates to true or to a non-zero
* numerical value, otherwise <b>false</b>. <b>false</b> is also returned if
* <b>expression</b> is null or an error occured.
*/
public static boolean evaluateToBoolean(AST expression, ISymbolTable symbolTable,
boolean useImplicitSymbols)
{
boolean evaluation = false;
if (expression != null)
{
Object result = evaluate(expression, symbolTable, useImplicitSymbols);
if (result instanceof Boolean)
evaluation = ((Boolean)result).booleanValue();
else
if (result instanceof Number)
evaluation = ((Number)result).floatValue() != 0;
}
return evaluation;
}
//------------------------------------------------------------------------------------------------
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -