abstract class ArithExpr { abstract double eval(Env enf); abstract String exprString(); } class Const extends ArithExpr { double value; double eval(Env env) { /* . . . */ } String exprString() { return Double.toString(value); } } class Var extends ArithExpr { String name; double eval(Env env) { /* . . . */ } String exprString() { return name; } } class Sum extends ArithExpr { ArithExpr left, right; double eval(Env env) { /*. . . left.eval(env) . . . right.eval(env) . . . */ } String exprString() { return "(" + left.exprString() + " + " + right.exprString() + ")"; } } class Diff extends ArithExpr { ArithExpr left, right; double eval(Env env) { /* . . . left.eval(env) . . . right.eval(env) . . . */ } String exprString() { return "(" + left.exprString() + " - " + right.exprString() + ")"; } } class Prod extends ArithExpr { ArithExpr left, right; double eval(Env env) { /*. . . left.eval(env) . . . right.eval(env) . . . */ } String exprString() { return "(" + left.exprString() + " * " + right.exprString() + ")"; } } class Quot extends ArithExpr { ArithExpr left, right; double eval(Env env) { /* . . . left.eval(env) . . . right.eval(env) . . . */ } String exprString() { return "(" + left.exprString() + " / " + right.exprString() + ")"; } } abstract class Env { abstract Double lookup(String name); }