/* * 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; }