-- | This module contains the data type that is used to model individual -- passes of the compiler's pipeline (see also "FreeC.Pipeline"). module FreeC.Pass where import Control.Monad ( (>=>) ) import FreeC.Monad.Converter -- | Compiler passes are transformations of AST nodes of type @a@ to AST nodes -- of type @b@. -- -- The 'Converter' monad is used to preserve state across passes and -- to report messages. type Pass a b = a -> Converter b -- | Runs the given compiler pass. runPass :: Pass a b -> a -> Converter b runPass = id -- | Runs the given compiler passes consecutively. -- -- The given initial value is passed to the first pass. The result is -- passed to the subsequent pass. The result of the final pass is returned. runPasses :: [Pass a a] -> a -> Converter a runPasses = foldr (>=>) return -- | Creates a pass that runs the given sub-pipeline on each component of its -- input (which are extracted using first given function) and recombines the -- results of the sub-pipeline into the result of the entire pass (using the -- second given function). subPipelinePass :: (a -> [b]) -- ^ The helper function extracting the components of the input. -> (a -> [c] -> d) -- ^ The helper function recombining the results of the sub passes. -> Pass b c -- ^ The sub passes running on each component of the input. -> Pass a d subPipelinePass getComponents updateComponents childPass input = do let components = getComponents input components' <- mapM (runPass childPass) components return (updateComponents input components')