mad/byg/src/DependencyRunner.hs

124 lines
3.4 KiB
Haskell
Raw Normal View History

{-# LANGUAGE MonoLocalBinds #-}
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 (evalFunctionIO)
import Types.Value
import Types.Token
2024-09-27 20:39:27 +02:00
import Types.Dependency
2024-10-14 22:48:58 +02:00
import Type.Reflection (Typeable)
2024-09-27 20:39:27 +02:00
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 ()
runDep (Dependency _ a action _ b) =
2024-10-21 22:17:23 +02:00
if actionWritesAny action
2024-10-06 00:40:54 +02:00
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
2024-10-14 22:48:58 +02:00
getTokenValueByIndex :: Int -> DepRunM Value
getTokenValueByIndex i = do
m <- get
evaluate (m M.! i)
getTokenValueRaw :: Token a -> DepRunM a
getTokenValueRaw token = case token of
Token i ->
fromValue <$> getTokenValueByIndex i
TupleToken a b -> do
2024-10-14 22:48:58 +02:00
(,) <$> getTokenValueRaw a <*> getTokenValueRaw b
ZipToken a b -> do
2024-10-14 22:48:58 +02:00
zip <$> getTokenValueRaw a <*> getTokenValueRaw b
ListToken ts -> do
2024-10-14 22:48:58 +02:00
mapM getTokenValueRaw ts
NoToken ->
2024-10-14 22:48:58 +02:00
pure ()
getTokenValue :: Token a -> DepRunM Value
getTokenValue token = case token of
Token i ->
getTokenValueByIndex i
TupleToken _ _ ->
fromRaw token
ZipToken _ _ ->
fromRaw token
ListToken _ ->
fromRaw token
NoToken ->
fromRaw token
where fromRaw :: (Typeable a, Show a) => Token a -> DepRunM Value
fromRaw = fmap toValue . getTokenValueRaw
2024-09-27 20:39:27 +02:00
putTokenValue :: Token a -> ValueExistence -> DepRunM ()
2024-10-06 00:40:54 +02:00
putTokenValue t e = case t of
Token i ->
2024-10-06 00:40:54 +02:00
modify $ M.insert i e
NoToken ->
2024-09-27 20:39:27 +02:00
pure ()
_ ->
error "unexpected"
2024-10-14 22:48:58 +02:00
runAction :: forall a b. Action a b -> Value -> DepRunM Value
2024-09-27 20:39:27 +02:00
runAction action input = case action of
Function (F f) ->
2024-10-14 22:48:58 +02:00
calc f
2024-09-27 20:39:27 +02:00
FunctionIO f ->
2024-10-14 22:48:58 +02:00
calcM (liftIO . evalFunctionIO f)
2024-10-14 22:15:27 +02:00
Inject x ->
pure $ toValue x
FilterComp ->
2024-10-14 22:48:58 +02:00
calc (\(vs, mask) -> map fst $ filter snd $ zip vs mask)
2024-10-14 22:15:27 +02:00
UntupleFst ->
2024-10-14 22:48:58 +02:00
calc fst
2024-10-14 22:15:27 +02:00
UntupleSnd ->
2024-10-14 22:48:58 +02:00
calc snd
2024-10-14 22:15:27 +02:00
UnzipFst ->
2024-10-14 22:48:58 +02:00
calc (map fst)
2024-10-14 22:15:27 +02:00
UnzipSnd ->
2024-10-14 22:48:58 +02:00
calc (map snd)
2024-10-14 22:15:27 +02:00
MapComp subDeps innerInput innerOutput ->
2024-10-14 22:48:58 +02:00
(toValueRep (actionTargetType action) <$>)
$ forM (fromValueRep (actionSourceType action) input) $ \x -> do
2024-10-14 22:15:27 +02:00
putTokenValue innerInput $ Evaluated $ toValue x
runDeps subDeps
2024-10-14 22:15:27 +02:00
fromValue <$> getTokenValue innerOutput
2024-10-14 22:48:58 +02:00
where calcM :: (Typeable a, Typeable b, Show b) => (a -> DepRunM b) -> DepRunM Value
calcM f = toValue <$> (f $ fromValueRep (actionSourceType action) input)
calc :: (Typeable a, Typeable b, Show b) => (a -> b) -> DepRunM Value
calc f = calcM (pure . f)