/* * If we visit a nested abstraction, we just launch a new lift operation on * this abstraction using current context as namespace and returns an * Application object * * @see jaskell.compiler.JaskellVisitor#visit(jaskell.compiler.core.Abstraction) */ public Object visit(Abstraction a) { if (!lift) { /* top level abstractions */ lift = true; a.setBody((Expression) a.getBody().visit(this)); return a; } /* first visit body */ a.setBody((Expression) a.getBody().visit(this)); /* retrieve outer LocalBindings */ Set captured = new HashSet(); CaptureCollector cc = new CaptureCollector(captured); a.visit(cc); /* return the newly computed abstraction as an application spine */ String vname; try { vname = lift(a, captured); Expression ex = applyLifted(vname, captured); ex.setParent(a.getParent()); return ex; } catch (SymbolException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } }
/* * 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)); }