module DependencyGenerator ( DepGenM , DepGenM' , evalDepGenM , inject , runFunction , runFunctionIO , mapDepGenM , mapDepGenM_ , filterDepGenM , joinPaths , isImageFilename , convertedImageFilename , applyTemplate , listDirectory , readTemplate , convertImage , saveFile , makeDir , runPandoc ) where import Types.Token (Token(..)) import Types.Values import Types.Value (Valuable(..)) import Types.Function (Function(..)) import Types.FunctionIO (FunctionIO(..)) import Types.Dependency (Action(..), Dependency, makeDependency) import Control.Monad.State (MonadState, State, runState, put, get) import Control.Monad.Writer (MonadWriter, WriterT, execWriterT, tell) newtype DepGenM' a = DepGenM { unDepGenM :: WriterT [Dependency] (State Int) a } deriving (Functor, Applicative, Monad, MonadState Int, MonadWriter [Dependency]) type DepGenM a = DepGenM' (Token a) evalDepGenM' :: Int -> DepGenM' () -> ([Dependency], Int) evalDepGenM' top m = runState (execWriterT (unDepGenM m)) top evalDepGenM :: DepGenM' () -> [Dependency] evalDepGenM m = fst (evalDepGenM' 0 m) tellDep :: Dependency -> DepGenM' () tellDep dep = tell [dep] genDependencyM :: (Token a -> DepGenM' Dependency) -> DepGenM a genDependencyM f = do top <- get let top' = top + 1 target = Token top' put top' result <- f target tellDep result pure target genDependency :: (Token a -> Dependency) -> DepGenM a genDependency f = genDependencyM (pure . f) inject :: Valuable a => a -> DepGenM a inject x = genDependency (makeDependency NoToken (Inject (toValue x))) getListElem :: Token [a] -> DepGenM a getListElem outer = genDependency (makeDependency outer GetListElem) setListElem :: Token a -> Token [a] -> DepGenM' () setListElem a outer = do tellDep (makeDependency a SetListElem outer) runFunction :: Function -> Token a -> DepGenM b runFunction f input = genDependency (makeDependency input (Function f)) runFunctionIO :: FunctionIO -> Token a -> DepGenM b runFunctionIO f input = genDependency (makeDependency input (FunctionIO f)) mapDepGenM :: (Token a -> DepGenM b) -> Token [a] -> DepGenM [b] mapDepGenM f input = genDependencyM $ \target -> do top <- get let (res, top') = evalDepGenM' top $ do inp <- getListElem input outp <- f inp setListElem outp target put top' pure (makeDependency input (MapComp res) target) mapDepGenM_ :: (Token a -> DepGenM' ()) -> Token [a] -> DepGenM' () mapDepGenM_ f input = do _ <- mapDepGenM (\x -> f x >> pure NoToken) input pure () filterDepGenM :: (Token a -> DepGenM Bool) -> Token [a] -> DepGenM [a] filterDepGenM f input = do conds <- mapDepGenM f input genDependency (makeDependency (TupleToken input conds) FilterComp) joinPaths :: Token (FilePath, FilePath) -> DepGenM FilePath joinPaths = runFunction JoinPaths isImageFilename :: Token FilePath -> DepGenM Bool isImageFilename = runFunction IsImageFilename convertedImageFilename :: Token FilePath -> DepGenM FilePath convertedImageFilename = runFunction ConvertedImageFilename applyTemplate :: Token (Template, String) -> DepGenM String applyTemplate = runFunction ApplyTemplate listDirectory :: Token FilePath -> DepGenM [FilePath] listDirectory = runFunctionIO ListDirectory readTemplate :: Token FilePath -> DepGenM Template readTemplate = runFunctionIO ReadTemplate convertImage :: Token ((FilePath, FilePath), ImageConversionSettings) -> DepGenM' () convertImage input = do _ <- runFunctionIO ConvertImage input pure () saveFile :: Token (String, FilePath) -> DepGenM' () saveFile input = do _ <- runFunctionIO SaveFile input pure () makeDir :: Token FilePath -> DepGenM' () makeDir input = do _ <- runFunctionIO MakeDir input pure () runPandoc :: Token FilePath -> DepGenM String runPandoc = runFunctionIO RunPandoc