package operators; import parser.ExpressionNode; import parser.Value; import valueTypes.DecimalValue; import valueTypes.ErrorValue; /** * An abstract BinaryOperator which will deal exclusively with real numbers * (DecimalValue objects) as operands. It is indended to be subclassed easily to * generate custom operators. All the subclass needs to do is define a method * double evaluate(double l,double r) which performs the operation on two double * values. * * RealNumberBinaryOperator provides optimization for repeated evaluations by * having each instance hold a persistant Value which gets set to the result of * the operation and returned each time the operator is evaluated. * Alternatively, one could create new Value objects each time the operator is * evaluated, but this would put the garbage collector to work, resulting in * poor performance. * * @author Curran Kelleher * */ public abstract class RealNumberBinaryOperator extends BinaryOperator { /** * The persistant result, a memory optimization for repeated evaluations. */ DecimalValue persistantValue = new DecimalValue(0); /** * The persistant left and right values, a memory optimization for repeated evaluations. */ Value leftValue, rightValue; /** * Constructs a real number binary operator which operates on the specified left-child and right-child evaluation trees. * * @param symbol the symbol of the operator ('+' for the plus operator) This is necessary for generating informative error messages. * @param leftChild the left-child evaluation tree * @param rightChild the right-child evaluation tree */ protected RealNumberBinaryOperator(char symbol, ExpressionNode leftChild, ExpressionNode rightChild) { super(""+symbol,leftChild, rightChild); } /** * The method which evaluates the operator. * @return the resulting Value */ public Value evaluate() { leftValue = leftChild.evaluate(); rightValue = rightChild.evaluate(); try { persistantValue.value = evaluate(((DecimalValue) leftValue).value, ((DecimalValue) rightValue).value); return persistantValue; } catch (Exception e) { return new ErrorValue("'" + symbol + "' is not a valid operator for the types " + leftValue.getType() + " and " + rightValue.getType() + ", so " + leftValue + " " + symbol + " " + rightValue + " could not be evaluated"); } } /** * The method which performs the operation on two double values. * * @param l the value on the left of the operator (a in a+b) * @param r the value on the right of the operator (b in a+b) * @return the value resulting from the operation. */ abstract double evaluate(double l, double r); }