module DDC.Core.Flow.Transform.Extract.Intersperse
(intersperseStmts)
where
import DDC.Core.Flow.Compounds
import DDC.Core.Flow.Prim
import DDC.Core.Flow.Exp
import DDC.Core.Collect
import DDC.Core.Transform.Annotate
import DDC.Type.Env
import Data.List (partition, (\\))
import qualified Data.Set as Set
intersperseStmts :: [LetsF] -> [LetsF] -> [LetsF]
intersperseStmts ls rs
= let bls = nubbish $ map takeSubstBoundsOfBinds $ map valwitBindsOfLets ls
brs = nubbish $ map takeSubstBoundsOfBinds $ map valwitBindsOfLets rs
in intersperse' (ls `zip` bls ++ rs `zip` brs)
nubbish :: [[Bound Name]] -> [[Bound Name]]
nubbish bs' = go bs' []
where go [] _ = []
go (b:bs) accs = (b \\ accs) : go bs (accs ++ b)
intersperse'
:: [(Lets () Name, [Bound Name])]
-> [Lets () Name]
intersperse' [] = []
intersperse' ((x,b):bxs)
| f <- freeXLets x
, (r:rs,os) <- partition (any (flip Set.member f) . snd) bxs
, (x', _) <- r
= x' : intersperse' (rs ++ (x, b) : os)
| otherwise
= x : intersperse' bxs
freeXLets :: LetsF -> Set.Set (Bound Name)
freeXLets ll
= freeX empty $ annotate () (XLet ll (XCon (dcBool True)))