public class Reduce implements ExprVisitor { public Object visitMultiply(Multiply m) { Expr l = (Expr)m.walkLeft(this); Expr r = (Expr)m.walkRight(this); if((l instanceof Number) && (r instanceof Number)) return new Number(((Number)l).getValue() * ((Number)r).getValue()); else return new Multiply(l, r); } public Object visitDivide(Divide d) { Expr l = (Expr)d.walkLeft(this); Expr r = (Expr)d.walkRight(this); if((l instanceof Number) && (r instanceof Number)) return new Number(((Number)l).getValue() / ((Number)r).getValue()); else return new Divide(l, r); } public Object visitSubtract(Subtract s) { Expr l = (Expr)s.walkLeft(this); Expr r = (Expr)s.walkRight(this); if((l instanceof Number) && (r instanceof Number)) return new Number(((Number)l).getValue() - ((Number)r).getValue()); else return new Subtract(l, r); } public Object visitAdd(Add a) { Expr l = (Expr)a.walkLeft(this); Expr r = (Expr)a.walkRight(this); if((l instanceof Number) && (r instanceof Number)) return new Number(((Number)l).getValue() + ((Number)r).getValue()); else return new Add(l, r); } public Object visitPlus(Plus p) { return p.walkOperand(this); } public Object visitMinus(Minus m) { Expr o = (Expr)m.walkOperand(this); if(o instanceof Number) return new Number(- ((Number)o).getValue()); else return new Minus(o); } public Object visitExp(Exp e) { Expr o = (Expr)e.walkOperand(this); if(o instanceof Number) return new Number(Math.exp(((Number)o).getValue())); else return new Exp(o); } public Object visitNumber(Number n) { return n; } public Object visitVariable(Variable v) { return v; } }