-- ==========================================================-- -- === Dependancy analyser dependancy.m (1) ===-- -- ==========================================================-- module Dependancy where import BaseDefs import Utils -- ==========================================================-- -- deBindersOf :: [(a,b)] -> [a] deBindersOf defns = [name | (name, rhs) <- defns] -- ==========================================================-- -- deValuesOf :: [(a,b)] -> [b] deValuesOf defns = [rhs | (name, rhs) <- defns] -- ==========================================================-- -- deFreeVars :: CExpr -> AnnExpr Naam (Set Naam) deFreeVars (ENum k) = (utSetEmpty, ANum k) deFreeVars (EVar v) = (utSetSingleton v, AVar v) deFreeVars (EConstr n) = (utSetEmpty, AConstr n) deFreeVars (EAp e1 e2) = (utSetUnion (deFreeVarsOf e1') (deFreeVarsOf e2'), AAp e1' e2') where e1' = deFreeVars e1 e2' = deFreeVars e2 deFreeVars (ECase e alts) = (utSetUnion (deFreeVarsOf e') free, ACase e' alts') where e' = deFreeVars e alts' = [(t, (ns, deFreeVars e)) | (t, (ns, e)) <- alts] free = utSetUnionList (map f alts') f (t, (ns, e)) = utSetSubtraction (deFreeVarsOf e) (utSetFromList ns) deFreeVars (ELam args body) = (utSetSubtraction (deFreeVarsOf body') (utSetFromList args), ALam args body') where body' = deFreeVars body deFreeVars (ELet isRec defns body) = (utSetUnion defnsFree bodyFree, ALet isRec defns' body') where binders = deBindersOf defns binderSet = utSetFromList binders values' = map deFreeVars (deValuesOf defns) defns' = zip binders values' freeInValues = utSetUnionList (map deFreeVarsOf values') defnsFree | isRec = utSetSubtraction freeInValues binderSet | otherwise = freeInValues body' = deFreeVars body bodyFree = utSetSubtraction (deFreeVarsOf body') binderSet -- ==========================================================-- -- deFreeVarsOf :: AnnExpr Naam (Set Naam) -> Set Naam deFreeVarsOf (free_vars, expr) = free_vars -- ==========================================================-- -- deDepthFirstSearch :: (Ord a) => (a -> [a]) -> -- The map, (Set a, [a]) -> -- state: visited set, -- current sequence of vertices [a] -> -- input vertices sequence (Set a, [a]) -- final state deDepthFirstSearch = foldl . search where search relation (visited, sequence) vertex | utSetElementOf vertex visited = (visited, sequence ) | otherwise = (visited', vertex: sequence') where (visited', sequence') = deDepthFirstSearch relation (utSetUnion visited (utSetSingleton vertex), sequence) (relation vertex) -- ==========================================================-- -- deSpanningSearch :: (Ord a) => (a -> [a]) -> -- The map (Set a, [Set a]) -> -- Current state: visited set, -- current sequence of vertice sets [a] -> -- Input sequence of vertices (Set a, [Set a]) -- Final state deSpanningSearch = foldl . search where search relation (visited, utSetSequence) vertex | utSetElementOf vertex visited = (visited, utSetSequence ) | otherwise = (visited', utSetFromList (vertex: sequence): utSetSequence) where (visited', sequence) = deDepthFirstSearch relation (utSetUnion visited (utSetSingleton vertex), []) (relation vertex) -- ==========================================================-- -- deScc :: (Ord a) => (a -> [a]) -> -- The "ins" map (a -> [a]) -> -- The "outs" map [a] -> -- The root vertices [Set a] -- The topologically sorted components deScc ins outs = spanning . depthFirst where depthFirst = second . deDepthFirstSearch outs (utSetEmpty, []) spanning = second . deSpanningSearch ins (utSetEmpty, []) -- ==========================================================-- -- deDependancy :: CExprP Naam -> CExprP Naam deDependancy = deDepends . deFreeVars -- ==========================================================-- -- deDepends (free, ANum n) = ENum n deDepends (free, AConstr n) = EConstr n deDepends (free, AVar v) = EVar v deDepends (free, AAp e1 e2) = EAp (deDepends e1) (deDepends e2) deDepends (free, ACase body alts) = ECase (deDepends body) [(t, (ns, deDepends e)) | (t, (ns, e)) <- alts] deDepends (free, ALam ns body) = ELam ns (deDepends body) deDepends (free, ALet isRec defns body) = foldr (deElet isRec) (deDepends body) defnGroups where binders = deBindersOf defns binderSet | isRec = utSetFromList binders | otherwise = utSetEmpty edges = [(n, f) | (n, (free, e)) <- defns, f <- utSetToList (utSetIntersection free binderSet)] ins v = [u | (u,w) <- edges, v==w] outs v = [w | (u,w) <- edges, v==u] components = map utSetToList (deScc ins outs binders) defnGroups = [[(n, utSureLookup defns "depends`defnGroups" n) | n <- ns] | ns <- components] -- ==========================================================-- -- deElet isRec dfs e = if not isRec || nonRec dfs then ELet False dfs' e else ELet True dfs' e where dfs' = [(n, deDepends e) | (n,e) <- dfs] nonRec [(n, (free, e))] = not (utSetElementOf n free) nonRec dfs = False -- ==========================================================-- -- === End dependancy.m (1) ===-- -- ==========================================================--