2024-10-14 20:41:42 +02:00
|
|
|
{-# LANGUAGE MonoLocalBinds #-}
|
2024-09-27 20:39:27 +02:00
|
|
|
module DependencyRunner
|
2024-09-27 21:13:16 +02:00
|
|
|
( DepRunM
|
|
|
|
, runDeps
|
2024-09-27 21:18:29 +02:00
|
|
|
, runDepRunMIO
|
2024-09-27 20:39:27 +02:00
|
|
|
) where
|
|
|
|
|
2024-10-14 23:18:21 +02:00
|
|
|
import Types (evalFunctionIO)
|
2024-10-14 20:41:42 +02:00
|
|
|
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
|
2024-10-10 23:53:54 +02:00
|
|
|
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
|
|
|
|
|
2024-09-27 21:18:29 +02:00
|
|
|
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-14 20:41:42 +02:00
|
|
|
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
|
2024-10-14 20:41:42 +02:00
|
|
|
TupleToken a b -> do
|
2024-10-14 22:48:58 +02:00
|
|
|
(,) <$> getTokenValueRaw a <*> getTokenValueRaw b
|
2024-10-14 20:41:42 +02:00
|
|
|
ZipToken a b -> do
|
2024-10-14 22:48:58 +02:00
|
|
|
zip <$> getTokenValueRaw a <*> getTokenValueRaw b
|
2024-10-14 20:41:42 +02:00
|
|
|
ListToken ts -> do
|
2024-10-14 22:48:58 +02:00
|
|
|
mapM getTokenValueRaw ts
|
2024-10-14 20:41:42 +02:00
|
|
|
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
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
putTokenValue :: Token a -> ValueExistence -> DepRunM ()
|
2024-10-06 00:40:54 +02:00
|
|
|
putTokenValue t e = case t of
|
2024-10-14 20:41:42 +02:00
|
|
|
Token i ->
|
2024-10-06 00:40:54 +02:00
|
|
|
modify $ M.insert i e
|
2024-10-14 20:41:42 +02:00
|
|
|
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
|
2024-10-14 23:18:21 +02:00
|
|
|
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
|
2024-10-10 23:53:54 +02:00
|
|
|
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)
|