function ExprConst(value) {
  this.value = value;
}
ExprConst.prototype = {
  eval: function (env) {
    return this.value;
  }
}

function ExprVar(varName) {
  this.varName = varName;
}
ExprVar.prototype = {
  eval: function (env) {
    var value = env.get(this.varName);
    if (!value) {
      throw "undefined variable: " + this.varName;
    }
    return value;
  }
}

function ExprAbs(varName, expr) {
  this.varName = varName;
  this.expr = expr;
}
ExprAbs.prototype = {
  eval: function (env) {
    return new ValueClosure(this.varName, this.expr);
  }
}

function ExprAdd(lhs, rhs) {
  this.lhs = lhs;
  this.rhs = rhs;
}
ExprAdd.prototype = {
  eval: function (env) {
    return this.lhs.eval() + this.rhs.eval();
  }
}

function ExprSub(lhs, rhs) {
  this.lhs = lhs;
  this.rhs = rhs;
}
ExprSub.prototype = {
  eval: function (env) {
    return this.lhs.eval() - this.rhs.eval();
  }
}

function ExprMul(lhs, rhs) {
  this.lhs = lhs;
  this.rhs = rhs;
}
ExprMul.prototype = {
  eval: function (env) {
    return this.lhs.eval() * this.rhs.eval();
  }
}

function ExprDiv(lhs, rhs) {
  this.lhs = lhs;
  this.rhs = rhs;
}
ExprDiv.prototype = {
  eval: function (env) {
    return this.lhs.eval() / this.rhs.eval();
  }
}

@@ -548,32 +548,363 @@
 s.expr);%0A  %7D%0A%7D%0A%0A
+function ExprApp(funcExpr, argExpr) %7B%0A  this.funcExpr = funcExpr;%0A  this.argExpr = argExpr;%0A%7D%0AExprApp.prototype = %7B%0A  eval: function (env) %7B%0A    var func = this.funcExpr.eval();%0A    var arg = this.argExpr.eval();%0A    if (!func.call) %7B%0A      throw %22function required, but got: %22 + func;%0A    %7D%0A    return func.call(arg, env);%0A  %7D%0A%7D%0A%0A
 function ExprAdd

Add ExprApp