-- ==========================================================-- -- === Add parameters to supercombinators which ===-- -- === otherwise return functions EtaAbstract.hs ===-- -- ==========================================================-- module EtaAbstract where import BaseDefs import Utils import MyUtils -- ==========================================================-- -- Doesn't assume that the tree has been lambda-lifted. -- It does however assume that all lambda-terms are -- directly attached to a let-binding. -- eaEtaAbstract :: AnnExpr Naam TExpr -> AnnExpr Naam TExpr eaEtaAbstract ae@(tau, AVar v) = ae eaEtaAbstract ae@(tau, ANum n) = ae eaEtaAbstract ae@(tau, AConstr c) = ae eaEtaAbstract ae@(tau, AAp e1 e2) = (tau, AAp (eaEtaAbstract e1) (eaEtaAbstract e2)) eaEtaAbstract ae@(tau, ACase sw alts) = (tau, ACase (eaEtaAbstract sw) [(n, (ps, eaEtaAbstract rhs)) | (n, (ps, rhs)) <- alts]) eaEtaAbstract ae@(tau, ALam vs e) = (tau, ALam vs (eaEtaAbstract e)) eaEtaAbstract ae@(tau, ALet rf defs body) = let typeInfo = [eaUncurry ty | (n, (ty, rhs)) <- defs] mergedDefs = map2nd mergeLams defs fixedDefs = myZipWith2 fixOne mergedDefs typeInfo fixOne sc@(n, (tau, ALam vs e)) (argTs, resT) | length vs == length argTs = sc | length vs > length argTs = panic "eaEtaAbstract" | length vs < length argTs = eaMain sc argTs resT fixOne sc@(n, (tau, non_lam_b)) (argTs, resT) | null argTs = sc | otherwise = eaMain (n, (tau, ALam [] (tau, non_lam_b))) argTs resT mergeLams ae@(tau, ALam vs (tau2, ALam vs2 e)) = mergeLams (tau, ALam (vs++vs2) e) mergeLams anyThingElse = anyThingElse in (tau, ALet rf fixedDefs (eaEtaAbstract body)) -- ==========================================================-- -- eaMain :: (Naam, AnnExpr Naam TExpr) -> [TExpr] -> TExpr -> (Naam, AnnExpr Naam TExpr) eaMain (scname, (tau, ALam vs (tau2, rhs))) argTs resT = let actualArity = length vs reqdArity = length argTs newArgsReqd = reqdArity - actualArity newArgs = eaMakeNewArgs newArgsReqd vs newArgsTypes = myZip2 newArgs (drop actualArity argTs) appArgTLists = map ((flip drop) argTs) (actualArity `myIntsFromTo` (reqdArity-1)) appTypes = map (eaCurry resT) appArgTLists newBody = eaMakeApChain (myZip2 newArgsTypes appTypes) (tau2, rhs) in (scname, (tau, ALam (vs++newArgs) newBody)) -- ==========================================================-- -- eaMakeApChain :: [((Naam, TExpr), TExpr)] -> AnnExpr Naam TExpr -> AnnExpr Naam TExpr eaMakeApChain [] app = app eaMakeApChain (((v, vtype), vaptype):rest) app = eaMakeApChain rest (vaptype, AAp app (vtype, AVar v)) -- ==========================================================-- -- eaMakeNewArgs :: Int -> [Naam] -> [Naam] eaMakeNewArgs n vs = let leadingvs = filter (not.null) (map (takeWhile (== 'v')) vs) root = last (sort ("":leadingvs)) ++ "v" newNames = map f (1 `myIntsFromTo` n) f n = root ++ show (n :: Int) in newNames -- ==========================================================-- -- eaCurry :: TExpr -> [TExpr] -> TExpr eaCurry resT [] = resT eaCurry resT (argT:argTs) = TArr argT (eaCurry resT argTs) -- ==========================================================-- -- eaUncurry :: TExpr -> ([TExpr], TExpr) eaUncurry (TVar tv) = ([], TVar tv) eaUncurry (TArr t1 t2) = let (rest, final) = eaUncurry t2 in (t1:rest, final) eaUncurry (TCons tcon targs) = ([], TCons tcon targs) -- ==========================================================-- -- === end EtaAbstract.hs ===-- -- ==========================================================--