/** * 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))); } }
/** Given generalized if expression, desugar into __cond calls (binding) where required. */ @Override public Node forIf(If i) { List<IfClause> clauses = i.getClauses(); int n = clauses.size(); if (n <= 0) bug(i, "if with no clauses!"); for (IfClause c : clauses) { if (c.getTestClause().getBind().size() == 0) continue; // If we get here we have a generalized if. // Desugar it into nested ifs and calls. // Then return the desugared result. Expr result = null; if (i.getElseClause().isSome()) { result = i.getElseClause().unwrap(); } // Traverse each clause and desugar it into an if or a __cond as appropriate. for (--n; n >= 0; --n) { result = addIfClause(clauses.get(n), result); } return result; } // If we get here, it's not a generalized if. Just recur. return super.forIf(i); }