/** * This method produces a new Abstraction which is the result of adding captured variables as new * arguments and bind it in current ns. It returns the name of the bound funciton. * * @param a * @param captured * @return a String object denoting the name given to this function * @throws SymbolException */ private String lift(Abstraction a, Set captured) throws SymbolException { Abstraction abs = a; if (!captured.isEmpty()) { /* recreate abstraction adding captured variables */ abs = new Abstraction(); /* bind captured variables */ Iterator it = captured.iterator(); while (it.hasNext()) { LocalBinding lb = (LocalBinding) it.next(); LocalBinding nlb = new LocalBinding(lb.getName()); abs.bind(nlb); } /* rebind old variables */ it = a.getBindings().values().iterator(); while (it.hasNext()) { LocalBinding lb = (LocalBinding) it.next(); LocalBinding nlb = new LocalBinding(lb.getName()); abs.bind(nlb); } /* restore body */ abs.setBody(a.getBody()); } /* * bind new abstraction in ns if a is an anonymous abstraction - no class * name - then it is renamed lambdaXXX and bound in namespace. Else, it is * given a new name and a reference to this new name is stored in substMap. */ String newname = "lambda" + counter++; ns.bind(newname, abs); abs.setClassName(ns.getName() + "." + newname); return newname; }
/* * (non-Javadoc) * * @see jaskell.compiler.JaskellVisitor#visit(jaskell.compiler.core.Module) */ public Object visit(Namespace a) { /* set current namespace */ ns = a; /* * visit definitions We set an infinite loop to cope with modifications * introduced by visiting sub expressions. When something is modified - * through lift - we restart the whole process. TODO : change this to defer * registering new bindings at end */ while (true) { try { Iterator it = a.getAllBindings().entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String functionName = (String) entry.getKey(); Expression def = (Expression) entry.getValue(); if (def instanceof Abstraction) ((Abstraction) def).setClassName(ns.getName() + "." + functionName); log.finest("Analyzing lifting for " + functionName); lift = false; entry.setValue((Expression) def.visit(this)); } break; } catch (ConcurrentModificationException cmex) { /* restart the process */ } } return a; }