mad/byg/src/DependencyRunner.hs

107 lines
3.0 KiB
Haskell
Raw Normal View History

2024-09-27 20:39:27 +02:00
module DependencyRunner
2024-09-27 21:13:16 +02:00
( DepRunM
, runDeps
, runDepRunMIO
2024-09-27 20:39:27 +02:00
) where
import Types (Value(..), fromValue, toValue, evalFunction, evalFunctionIO)
2024-09-27 20:39:27 +02:00
import Types.Dependency
import Data.Map (Map)
import qualified Data.Map as M
import Control.Monad (void, forM)
2024-09-27 21:13:16 +02:00
import Control.Monad.State (MonadState, MonadIO, StateT, evalStateT, get, modify, liftIO)
2024-09-27 20:39:27 +02:00
2024-10-06 00:40:54 +02:00
data ValueExistence = Evaluated Value
| NotEvaluated (DepRunM Value)
newtype DepRunM a = DepRunM { unDepRunM :: StateT (Map Int ValueExistence) IO a }
deriving (Functor, Applicative, Monad, MonadIO, MonadState (Map Int ValueExistence))
2024-09-27 20:39:27 +02:00
runDeps :: [Dependency] -> DepRunM ()
runDeps = mapM_ runDep
runDepRunMIO :: DepRunM a -> IO a
runDepRunMIO m = evalStateT (unDepRunM m) M.empty
2024-09-27 21:13:16 +02:00
2024-10-06 00:40:54 +02:00
evaluate :: ValueExistence -> DepRunM Value
evaluate = \case
Evaluated v -> pure v
NotEvaluated m -> m
2024-09-27 20:39:27 +02:00
runDep :: Dependency -> DepRunM ()
2024-10-06 00:40:54 +02:00
runDep (Dependency a action b) =
if actionTouchesFilesystem action
then void m
else putTokenValue b $ NotEvaluated m
where m :: DepRunM Value
m = do
input <- getTokenValue a
result <- runAction action input
putTokenValue b $ Evaluated result
liftIO $ do
putStrLn ("input: " ++ show input)
putStrLn ("action: " ++ show action)
putStrLn ("output: " ++ show result)
putStrLn "----------"
pure result
2024-09-27 20:39:27 +02:00
foo' :: [Value] -> [Value] -> [(Value, Value)]
foo' = zip
foo :: Value -> Value -> Value
foo va vb = toValue $ foo' (fromValue va) (fromValue vb)
2024-09-27 20:39:27 +02:00
getTokenValue :: UToken -> DepRunM Value
getTokenValue = \case
UToken i -> do
m <- get
2024-10-06 00:40:54 +02:00
evaluate (m M.! i)
2024-10-05 19:44:28 +02:00
UTupleToken a b -> do
2024-09-27 20:39:27 +02:00
va <- getTokenValue a
vb <- getTokenValue b
pure $ toValue (va, vb)
2024-10-05 19:44:28 +02:00
UZipToken a b -> do
2024-09-27 20:39:27 +02:00
va <- getTokenValue a
vb <- getTokenValue b
pure $ foo va vb
UListToken ts -> do
vs <- mapM getTokenValue ts
pure $ toValue vs
2024-09-27 20:39:27 +02:00
UNoToken ->
pure $ toValue ()
2024-09-27 20:39:27 +02:00
2024-10-06 00:40:54 +02:00
putTokenValue :: UToken -> ValueExistence -> DepRunM ()
putTokenValue t e = case t of
2024-09-27 20:39:27 +02:00
UToken i ->
2024-10-06 00:40:54 +02:00
modify $ M.insert i e
2024-09-27 20:39:27 +02:00
UNoToken ->
pure ()
_ ->
error "unexpected"
runAction :: Action -> Value -> DepRunM Value
runAction action input = case action of
Function f ->
2024-10-06 15:53:40 +02:00
pure $ toValue $ evalFunction f $ fromValue input
2024-09-27 20:39:27 +02:00
FunctionIO f ->
liftIO (toValue <$> evalFunctionIO f (fromValue input))
2024-09-27 20:39:27 +02:00
Inject v ->
pure v
FilterComp ->
let (vs, mask) = fromValue input :: ([Value], [Value])
in pure $ toValue $ map fst $ filter (fromValue . snd) $ zip vs mask
2024-09-27 20:39:27 +02:00
UntupleFst ->
pure $ fst (fromValue input :: (Value, Value))
2024-09-27 20:39:27 +02:00
UntupleSnd ->
pure $ snd (fromValue input :: (Value, Value))
2024-09-27 20:39:27 +02:00
UnzipFst ->
toValue <$> mapM (runAction UntupleFst) (fromValue input :: [Value])
2024-09-27 20:39:27 +02:00
UnzipSnd ->
toValue <$> mapM (runAction UntupleSnd) (fromValue input :: [Value])
MapComp subDeps innerInput innerOutput ->
(toValue <$>) $ forM (fromValue input :: [Value]) $ \v -> do
putTokenValue innerInput $ Evaluated v
runDeps subDeps
getTokenValue innerOutput