package calculator.interpreter.ast.logic; import calculator.interpreter.Environment; import calculator.interpreter.EvalException; import calculator.interpreter.ast.Expression; import calculator.interpreter.ast.InfixOp; /** * Base class for comparison operators */ public abstract class ComparisonOp extends InfixOp { @SuppressWarnings("unchecked") @Override public Object eval(Environment env) { Comparable f = checkComparable(env, first); Comparable s = checkComparable(env, second); if (f.getClass() != s.getClass()) { throw new EvalException(this, "Only values of the same type could be compared: " + f.getClass().getName() + " != " + s.getClass().getName()); } return compared(f.compareTo(s)); } /** * Check if the value is comparable * * @param env the evaluation environment * @param e the expression to evaluate * @return the result of expression */ private Comparable<?> checkComparable(Environment env, Expression e) { Object o = e.eval(env); if (o == null || !(o instanceof Comparable)) { throw new EvalException(this, "The expression at " + e.location.toShortString() + " has evaluated to " + o + " : " + (o == null ? null : o.getClass().getName()) + " which is not comparable."); } return (Comparable<?>) o; } /** * Convert result of comparison operation to boolean * * @param result the result of {@link Comparable#compareTo(Object)}. * @return a boolean value */ protected abstract boolean compared(int result); }