docs: function evaluate(expr) {
                  switch (expr[0]) {
                      case "string":
                      case "num":
                          return expr[1];
                      case "name":
                      case "atom":
                          switch (expr[1]) {
                              case "true": return true;
                              case "false": return false;
                              case "null": return null;
                          }
                          break;
                      case "unary-prefix":
                          switch (expr[1]) {
                              case "!": return !evaluate(expr[2]);
                              case "typeof": return typeof evaluate(expr[2]);
                              case "~": return ~evaluate(expr[2]);
                              case "-": return -evaluate(expr[2]);
                              case "+": return +evaluate(expr[2]);
                          }
                          break;
                      case "binary":
                          var left = expr[2], right = expr[3];
                          switch (expr[1]) {
                              case "&&"         : return evaluate(left) &&         evaluate(right);
                              case "||"         : return evaluate(left) ||         evaluate(right);
                              case "|"          : return evaluate(left) |          evaluate(right);
                              case "&"          : return evaluate(left) &          evaluate(right);
                              case "^"          : return evaluate(left) ^          evaluate(right);
                              case "+"          : return evaluate(left) +          evaluate(right);
                              case "*"          : return evaluate(left) *          evaluate(right);
                              case "/"          : return evaluate(left) /          evaluate(right);
                              case "%"          : return evaluate(left) %          evaluate(right);
                              case "-"          : return evaluate(left) -          evaluate(right);
                              case "<<"         : return evaluate(left) <<         evaluate(right);
                              case ">>"         : return evaluate(left) >>         evaluate(right);
                              case ">>>"        : return evaluate(left) >>>        evaluate(right);
                              case "=="         : return evaluate(left) ==         evaluate(right);
                              case "==="        : return evaluate(left) ===        evaluate(right);
                              case "!="         : return evaluate(left) !=         evaluate(right);
                              case "!=="        : return evaluate(left) !==        evaluate(right);
                              case "<"          : return evaluate(left) <          evaluate(right);
                              case "<="         : return evaluate(left) <=         evaluate(right);
                              case ">"          : return evaluate(left) >          evaluate(right);
                              case ">="         : return evaluate(left) >=         evaluate(right);
                              case "in"         : return evaluate(left) in         evaluate(right);
                              case "instanceof" : return evaluate(left) instanceof evaluate(right);
                          }
                  }
                  throw $NOT_CONSTANT;
          }