@Override public int exprSize() { int sz = 1; for (final Let lt : copies) sz += lt.exprSize(); for (final Expr e : expr) sz += e.exprSize(); return sz; }
@Override public void checkUp() throws QueryException { for (final Let c : copies) c.checkUp(); final Expr m = expr[0]; m.checkUp(); if (!m.isVacuous() && !m.has(Flag.UPD)) throw UPMODIFY.get(info); checkNoUp(expr[1]); }
/* * Definitions in the let block are lifted to top-level and the corresponding * references in the body are replaced by new definitions. * * @see jaskell.compiler.JaskellVisitor#visit(jaskell.compiler.core.Let) */ public Object visit(Let let) { HashMap subst = new HashMap(); /* substitution map */ Set lambdas = new HashSet(); /* newly created toplevels ? */ Iterator it = let.getBindings().entrySet().iterator(); /* first lift all definitions in this let */ while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String name = (String) entry.getKey(); Expression e = (Expression) entry.getValue(); /* reset lift flag */ lift = false; Expression ndef = (Expression) e.visit(this); ndef.setParent(let); /* lift new definition */ Set captured = new HashSet(); CaptureCollector cc = new CaptureCollector(captured); ndef.visit(cc); String vname; try { vname = lift(ndef, captured); lambdas.add(vname); /* * store new application spine in a map for later substitution */ subst.put(name, applyLifted(vname, captured)); } catch (SymbolException e1) { e1.printStackTrace(); } } /* second, replace old occurences in new definitions */ it = lambdas.iterator(); while (it.hasNext()) { String n = (String) it.next(); Expression e; try { e = (Expression) ns.resolve(n); ns.rebind(n, (Expression) e.visit(new Substitution(subst))); } catch (SymbolException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } /* thirs, replace occurences in body of let and return it */ return let.getBody().visit(new Substitution(subst)); }
/** @see jaskell.compiler.JaskellVisitor#visit(Let) */ public Object visit(Let a) { Type ret = a.getType(); if (ret != null) return ret; // visit definitions Iterator it = a.getBindings().entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String name = (String) entry.getKey(); Expression def = (Expression) entry.getValue(); log.finer("Visiting " + name); def.setType((Type) def.visit(this)); } // visit body ret = (Type) a.getBody().visit(this); a.setType(ret); // return type of body return ret; }
@Override public boolean removable(final Var v) { for (final Let c : copies) if (!c.removable(v)) return false; return super.removable(v); }
@Override public Expr compile(final QueryContext ctx, final VarScope scp) throws QueryException { for (final Let c : copies) c.expr = c.expr.compile(ctx, scp); super.compile(ctx, scp); return this; }