mad/byg/src/DependencyGenerator.hs

178 lines
5.3 KiB
Haskell
Raw Normal View History

{-# LANGUAGE FunctionalDependencies #-}
2024-09-23 22:11:54 +02:00
module DependencyGenerator
( DepGenM
2024-09-24 23:01:07 +02:00
, DepGenM'
2024-09-23 22:11:54 +02:00
, evalDepGenM
, inject
, runFunction
, runFunctionIO
, mapDepGenM
, mapDepGenM_
, filterDepGenM
2024-09-25 23:06:53 +02:00
, unzipFstDepGenM
, unzipSndDepGenM
, unzipDepGenM
2024-09-23 22:11:54 +02:00
2024-09-24 23:01:07 +02:00
, joinPaths
2024-09-25 23:06:53 +02:00
, fileComponents
2024-09-25 23:12:32 +02:00
, isImageExtension
2024-09-23 22:11:54 +02:00
, convertedImageFilename
2024-09-24 23:01:07 +02:00
, applyTemplate
2024-09-23 22:11:54 +02:00
, listDirectory
, readTemplate
, convertImage
, saveFile
2024-09-24 22:38:52 +02:00
, makeDir
2024-09-23 22:11:54 +02:00
, runPandoc
) where
import Types.Token (Token(..))
import Types.Values
import Types.Value (Valuable(..))
import Types.Function (Function(..))
import Types.FunctionIO (FunctionIO(..))
2024-09-24 21:21:49 +02:00
import Types.Dependency (Action(..), Dependency, makeDependency)
2024-09-23 22:11:54 +02:00
import Control.Monad.State (MonadState, State, runState, put, get)
import Control.Monad.Writer (MonadWriter, WriterT, execWriterT, tell)
2024-09-24 23:09:35 +02:00
newtype DepGenM a = DepGenM { unDepGenM :: WriterT [Dependency] (State Int) a }
2024-09-23 22:11:54 +02:00
deriving (Functor, Applicative, Monad, MonadState Int, MonadWriter [Dependency])
2024-09-24 23:09:35 +02:00
type DepGenM' a = DepGenM (Token a)
2024-09-23 22:11:54 +02:00
2024-09-24 23:09:35 +02:00
evalDepGenM' :: Int -> DepGenM () -> ([Dependency], Int)
2024-09-23 22:11:54 +02:00
evalDepGenM' top m = runState (execWriterT (unDepGenM m)) top
2024-09-24 23:09:35 +02:00
evalDepGenM :: DepGenM () -> [Dependency]
2024-09-23 22:11:54 +02:00
evalDepGenM m = fst (evalDepGenM' 0 m)
2024-09-24 23:09:35 +02:00
tellDep :: Dependency -> DepGenM ()
2024-09-23 22:11:54 +02:00
tellDep dep = tell [dep]
2024-09-24 23:09:35 +02:00
genDependencyM :: (Token a -> DepGenM Dependency) -> DepGenM' a
2024-09-23 22:11:54 +02:00
genDependencyM f = do
top <- get
let top' = top + 1
target = Token top'
put top'
result <- f target
tellDep result
pure target
2024-09-24 23:09:35 +02:00
genDependency :: (Token a -> Dependency) -> DepGenM' a
2024-09-23 22:11:54 +02:00
genDependency f = genDependencyM (pure . f)
2024-09-24 23:09:35 +02:00
inject :: Valuable a => a -> DepGenM' a
2024-09-23 22:11:54 +02:00
inject x = genDependency (makeDependency NoToken (Inject (toValue x)))
2024-09-24 23:09:35 +02:00
getListElem :: Token [a] -> DepGenM' a
2024-09-23 22:11:54 +02:00
getListElem outer = genDependency (makeDependency outer GetListElem)
2024-09-24 23:09:35 +02:00
setListElem :: Token a -> Token [a] -> DepGenM ()
2024-09-23 22:11:54 +02:00
setListElem a outer = do
tellDep (makeDependency a SetListElem outer)
2024-09-24 23:09:35 +02:00
runFunction :: Function -> Token a -> DepGenM' b
2024-09-23 22:11:54 +02:00
runFunction f input = genDependency (makeDependency input (Function f))
2024-09-24 23:09:35 +02:00
runFunctionIO :: FunctionIO -> Token a -> DepGenM' b
2024-09-23 22:11:54 +02:00
runFunctionIO f input = genDependency (makeDependency input (FunctionIO f))
2024-09-25 19:45:10 +02:00
runFunctionIO' :: FunctionIO -> Token a -> DepGenM ()
2024-09-25 22:12:38 +02:00
runFunctionIO' f input = tellDep $ makeDependency input (FunctionIO f) NoToken
2024-09-25 19:45:10 +02:00
2024-09-24 23:09:35 +02:00
mapDepGenM :: (Token a -> DepGenM' b) -> Token [a] -> DepGenM' [b]
2024-09-23 22:11:54 +02:00
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)
2024-09-24 23:09:35 +02:00
mapDepGenM_ :: (Token a -> DepGenM ()) -> Token [a] -> DepGenM ()
2024-09-23 22:11:54 +02:00
mapDepGenM_ f input = do
2024-09-24 23:01:07 +02:00
_ <- mapDepGenM (\x -> f x >> pure NoToken) input
2024-09-24 22:23:43 +02:00
pure ()
2024-09-23 22:11:54 +02:00
2024-09-25 23:12:32 +02:00
filterDepGenM :: Token [Bool] -> Token [a] -> DepGenM' [a]
filterDepGenM mask input = do
genDependency (makeDependency (TupleToken (input, mask)) FilterComp)
2024-09-23 22:11:54 +02:00
2024-09-25 23:06:53 +02:00
unzipFstDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [a])
unzipFstDepGenM t = do
t' <- toToken t
case t' of
ZipToken (a, _) -> pure a
Token _ -> genDependency (makeDependency t' UnzipFst)
unzipSndDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [b])
unzipSndDepGenM t = do
t' <- toToken t
case t' of
ZipToken (_, b) -> pure b
Token _ -> genDependency (makeDependency t' UnzipSnd)
unzipDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [a], Token [b])
unzipDepGenM t = do
t' <- toToken t
a <- unzipFstDepGenM t'
b <- unzipSndDepGenM t'
pure (a, b)
class TokenableTo t s | s -> t where
toToken :: s -> DepGenM' t
2024-09-23 22:11:54 +02:00
instance TokenableTo a (Token a) where
toToken = pure
2024-09-24 23:01:07 +02:00
instance TokenableTo a (DepGenM' a) where
toToken = id
2024-09-23 22:11:54 +02:00
joinPaths :: (TokenableTo FilePath a, TokenableTo FilePath b) => (a, b) -> DepGenM' FilePath
joinPaths (a, b) = do
a' <- toToken a
b' <- toToken b
runFunction JoinPaths $ TupleToken (a', b')
2024-09-23 22:11:54 +02:00
2024-09-25 23:06:53 +02:00
fileComponents :: TokenableTo FilePath a => a -> DepGenM' (String, String)
fileComponents a = runFunction FileComponents =<< toToken a
2024-09-25 23:12:32 +02:00
isImageExtension :: TokenableTo FilePath a => a -> DepGenM' Bool
isImageExtension a = runFunction IsImageExtension =<< toToken a
2024-09-24 23:01:07 +02:00
convertedImageFilename :: TokenableTo FilePath a => a -> DepGenM' FilePath
convertedImageFilename a = runFunction ConvertedImageFilename =<< toToken a
2024-09-23 22:11:54 +02:00
applyTemplate :: (TokenableTo Template a, TokenableTo String b) => (a, b) -> DepGenM' String
applyTemplate (a, b) = do
a' <- toToken a
b' <- toToken b
runFunction ApplyTemplate $ TupleToken (a', b')
2024-09-23 22:11:54 +02:00
listDirectory :: TokenableTo FilePath a => a -> DepGenM' [FilePath]
listDirectory a = runFunctionIO ListDirectory =<< toToken a
2024-09-23 22:11:54 +02:00
readTemplate :: TokenableTo FilePath a => a -> DepGenM' Template
readTemplate a = runFunctionIO ReadTemplate =<< toToken a
2024-09-23 22:11:54 +02:00
convertImage :: (TokenableTo (FilePath, FilePath) a, TokenableTo ImageConversionSettings b) => (a, b) -> DepGenM ()
convertImage (a, b) = do
a' <- toToken a
b' <- toToken b
runFunctionIO' ConvertImage $ TupleToken (a', b')
2024-09-24 22:38:52 +02:00
saveFile :: (TokenableTo String a, TokenableTo FilePath b) => (a, b) -> DepGenM ()
saveFile (a, b) = do
a' <- toToken a
b' <- toToken b
runFunctionIO' SaveFile $ TupleToken (a', b')
makeDir :: TokenableTo FilePath a => a -> DepGenM ()
makeDir a = runFunctionIO' MakeDir =<< toToken a
runPandoc :: TokenableTo FilePath a => a -> DepGenM' String
runPandoc a = runFunctionIO RunPandoc =<< toToken a