{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Rank2Types #-}
module LLVM.DSL.Render.Run (
T(Cons, decons),
postmapPlain,
premapDSL,
Creator,
run,
(*->),
) where
import qualified LLVM.DSL.Render.Argument as Arg
import qualified LLVM.DSL.Expression as Expr
import LLVM.DSL.Render.Argument (Creator)
import LLVM.DSL.Expression (Exp)
import qualified LLVM.Extra.Multi.Value.Marshal as Marshal
import Prelude2010
import Prelude ()
newtype T m p fdsl f =
Cons {decons :: (Exp p -> fdsl) -> m (Creator p -> f)}
postmapPlain :: Functor m => (f -> g) -> T m p fdsl f -> T m p fdsl g
postmapPlain f build = Cons $ fmap (f .) . decons build
premapDSL :: (gdsl -> fdsl) -> T m p fdsl f -> T m p gdsl f
premapDSL f build = Cons $ decons build . fmap f
primitiveCreator :: a -> Creator a
primitiveCreator a = return (a, return ())
run :: (Functor m) => T m () fdsl f -> fdsl -> m f
run (Cons build) f = fmap ($ primitiveCreator ()) $ build $ const f
infixr 4 *->
(*->) ::
(Functor m) =>
Arg.T a adsl ->
(forall al. Marshal.C al => T m (p, al) fdsl f) ->
T m p (adsl -> fdsl) (a -> f)
(*->) arg build = Cons $ \f ->
case arg of
Arg.Cons pass createA ->
fmap
(\g createP av ->
g (do (p,finalP) <- createP
(pa,finalA) <- createA av
return ((p,pa), finalA >> finalP)))
(decons build (Expr.uncurry $ \p -> f p . pass))