/** Desugar a generalized While clause. */
 @Override
 public Node forWhile(While w) {
   GeneratorClause g = w.getTestExpr();
   if (g.getBind().size() > 0) {
     // while binds <- expr  do body end
     // desugars to
     // while __whileCond(expr, fn (binds) => body) do end
     ArrayList<Expr> args = new ArrayList<Expr>(2);
     args.add(g.getInit());
     args.add(bindsAndBody(g, w.getBody()));
     Expr cond =
         ExprFactory.make_RewriteFnApp(
             NodeUtil.getSpan(g),
             WHILECOND_NAME,
             ExprFactory.makeTupleExpr(NodeUtil.getSpan(w), args));
     w = ExprFactory.makeWhile(NodeUtil.getSpan(w), cond);
   }
   return (Expr) super.forWhile(w);
 }
 /**
  * Add an if clause to a (potentially) pre-existing else clause. The else clase can be null, or
  * can be an if expression.
  */
 private Expr addIfClause(IfClause c, Expr elsePart) {
   GeneratorClause g = c.getTestClause();
   if (g.getBind().size() > 0) {
     // if binds <- expr then body else elsePart end desugars to
     // __cond(expr, fn (binds) => body, elsePart)
     ArrayList<Expr> args = new ArrayList<Expr>(3);
     args.add(g.getInit());
     args.add(bindsAndBody(g, c.getBody()));
     if (elsePart != null) args.add(thunk(elsePart));
     return (Expr)
         recur(
             ExprFactory.make_RewriteFnApp(
                 NodeUtil.getSpan(c),
                 COND_NAME,
                 ExprFactory.makeTupleExpr(NodeUtil.getSpan(c), args)));
   }
   // if expr then body else elsePart end is preserved
   // (but we replace elif chains by nesting).
   if (elsePart == null) {
     return (Expr) super.forIf(ExprFactory.makeIf(NodeUtil.getSpan(c), c));
   } else {
     return (Expr)
         super.forIf(ExprFactory.makeIf(NodeUtil.getSpan(c), c, ExprFactory.makeBlock(elsePart)));
   }
 }
 /**
  * @param loc Containing context
  * @param gens Generators in generator list
  * @return single generator equivalent to the generator list Desugars as follows: body, empty =>
  *     body body, x <- exp, gs => exp.loop(fn x => body, gs)
  */
 Expr visitLoop(Span span, List<GeneratorClause> gens, Expr body) {
   for (int i = gens.size() - 1; i >= 0; i--) {
     GeneratorClause g = gens.get(i);
     Expr loopBody = bindsAndBody(g, body);
     body =
         ExprFactory.makeMethodInvocation(NodeUtil.getSpan(g), g.getInit(), LOOP_NAME, loopBody);
   }
   // System.out.println("Desugared to "+body.toStringVerbose());
   return (Expr) recur(body);
 }