{-# Language CPP #-}
-- | Dependency tracking
module Csound.Dynamic.Types.Dep(
    DepT(..), LocalHistory(..), runDepT, execDepT, evalDepT,
    -- * Dependencies
    depT, depT_, mdepT, stripDepT, stmtOnlyT, toBlock, depends,

    -- * Variables
    newLocalVar, newLocalVars,
    writeVar, readVar, readOnlyVar, initVar, appendVarBy,

    -- * Arrays
    newLocalArrVar, newTmpArrVar,
    readArr, readOnlyArr, writeArr, writeInitArr, initArr, appendArrBy,

    -- * Read macros
    readMacrosDouble, readMacrosInt, readMacrosString,
    initMacrosDouble, initMacrosString, initMacrosInt
) where

#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
#endif

import Control.Monad.Trans.Class
import Control.Monad.Trans.State.Strict
import Control.Monad(ap, liftM, zipWithM_)
import Data.Default

import Data.Fix(Fix(..))
import Data.Text (Text)
import Data.Text qualified as Text

import Csound.Dynamic.Types.Exp

-- | Csound's synonym for 'IO'-monad. 'Dep' means Side Effect.
-- You will bump into 'Dep' trying to read and write to delay lines,
-- making random signals or trying to save your audio to file.
-- Instrument is expected to return a value of @Dep [Sig]@.
-- So it's okay to do some side effects when playing a note.
newtype DepT m a = DepT { forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT :: StateT LocalHistory m a }

data LocalHistory = LocalHistory
    { LocalHistory -> E
expDependency :: !E
    , LocalHistory -> Int
newLineNum    :: !Int
    , LocalHistory -> Int
newLocalVarId :: !Int }

instance Default LocalHistory where
    def :: LocalHistory
def = E -> Int -> Int -> LocalHistory
LocalHistory (Exp E -> E
noRate Exp E
forall a. MainExp a
Starts) Int
0 Int
0

instance Monad m => Functor (DepT m) where
    fmap :: forall a b. (a -> b) -> DepT m a -> DepT m b
fmap = (a -> b) -> DepT m a -> DepT m b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM

instance Monad m => Applicative (DepT m) where
    pure :: forall a. a -> DepT m a
pure = StateT LocalHistory m a -> DepT m a
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m a -> DepT m a)
-> (a -> StateT LocalHistory m a) -> a -> DepT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> StateT LocalHistory m a
forall a. a -> StateT LocalHistory m a
forall (m :: * -> *) a. Monad m => a -> m a
return
    <*> :: forall a b. DepT m (a -> b) -> DepT m a -> DepT m b
(<*>) = DepT m (a -> b) -> DepT m a -> DepT m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad m => Monad (DepT m) where
    DepT m a
ma >>= :: forall a b. DepT m a -> (a -> DepT m b) -> DepT m b
>>= a -> DepT m b
mf = -- DepT $ unDepT ma >>= unDepT . mf
      StateT LocalHistory m b -> DepT m b
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m b -> DepT m b)
-> StateT LocalHistory m b -> DepT m b
forall a b. (a -> b) -> a -> b
$ (LocalHistory -> m (b, LocalHistory)) -> StateT LocalHistory m b
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((LocalHistory -> m (b, LocalHistory)) -> StateT LocalHistory m b)
-> (LocalHistory -> m (b, LocalHistory)) -> StateT LocalHistory m b
forall a b. (a -> b) -> a -> b
$ \LocalHistory
s -> do
        (a
aE, LocalHistory
aS) <- StateT LocalHistory m a -> LocalHistory -> m (a, LocalHistory)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (DepT m a -> StateT LocalHistory m a
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT DepT m a
ma) (LocalHistory -> LocalHistory
startSt LocalHistory
s)
        (b
bE, LocalHistory
bS) <- StateT LocalHistory m b -> LocalHistory -> m (b, LocalHistory)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (DepT m b -> StateT LocalHistory m b
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT (a -> DepT m b
mf a
aE)) (LocalHistory -> LocalHistory
startSt LocalHistory
aS)
        (b, LocalHistory) -> m (b, LocalHistory)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
bE, LocalHistory -> LocalHistory -> LocalHistory
setDeps LocalHistory
bS LocalHistory
aS)
      where
        startSt :: LocalHistory -> LocalHistory
startSt LocalHistory
s = LocalHistory
s
          { expDependency = rehashE $ Fix $ (unFix $ noRate Starts) { ratedExpDepends = Just (newLineNum s) }
          , newLineNum = succ $ newLineNum s
          }

        setDeps :: LocalHistory -> LocalHistory -> LocalHistory
setDeps LocalHistory
bS LocalHistory
aS = LocalHistory
bS
          { expDependency = depends (expDependency aS) (expDependency bS)
          , newLineNum = succ $ newLineNum bS
          }


{-
ifT1 :: Monad m => IfRate -> E -> DepT m (CodeBlock E) -> DepT m E
ifT1 ifRate check (DepT th) = DepT $ StateT $ \s -> do
  (_thE, thS)  <- runStateT th s
  let thDeps = expDependency thS
      a  = noRate $ IfBlock ifRate (condInfo $ setIfRate ifRate check) (CodeBlock $ PrimOr $ Right thDeps)
      a1 = rehashE $ Fix $ (unFix a) { ratedExpDepends = Just (newLineNum thS) }
      s1 = thS
            { newLineNum = succ $ newLineNum thS
            , expDependency = a1
            -- depends (expDependency thS) (depends (expDependency elS) a1)
            }
  pure (a1, s1)
-}
instance MonadTrans DepT where
    lift :: forall (m :: * -> *) a. Monad m => m a -> DepT m a
lift m a
ma = StateT LocalHistory m a -> DepT m a
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m a -> DepT m a)
-> StateT LocalHistory m a -> DepT m a
forall a b. (a -> b) -> a -> b
$ m a -> StateT LocalHistory m a
forall (m :: * -> *) a. Monad m => m a -> StateT LocalHistory m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
ma

runDepT :: (Functor m, Monad m) => DepT m a -> m (a, LocalHistory)
runDepT :: forall (m :: * -> *) a.
(Functor m, Monad m) =>
DepT m a -> m (a, LocalHistory)
runDepT DepT m a
a = StateT LocalHistory m a -> LocalHistory -> m (a, LocalHistory)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (DepT m a -> StateT LocalHistory m a
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT (DepT m a -> StateT LocalHistory m a)
-> DepT m a -> StateT LocalHistory m a
forall a b. (a -> b) -> a -> b
$ DepT m a
a) LocalHistory
forall a. Default a => a
def

evalDepT :: (Functor m, Monad m) => DepT m a -> m a
evalDepT :: forall (m :: * -> *) a. (Functor m, Monad m) => DepT m a -> m a
evalDepT DepT m a
a = StateT LocalHistory m a -> LocalHistory -> m a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (DepT m a -> StateT LocalHistory m a
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT (DepT m a -> StateT LocalHistory m a)
-> DepT m a -> StateT LocalHistory m a
forall a b. (a -> b) -> a -> b
$ DepT m a
a) LocalHistory
forall a. Default a => a
def

execDepT :: (Functor m, Monad m) => DepT m () -> m E
execDepT :: forall (m :: * -> *). (Functor m, Monad m) => DepT m () -> m E
execDepT DepT m ()
a = (LocalHistory -> E) -> m LocalHistory -> m E
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LocalHistory -> E
expDependency (m LocalHistory -> m E) -> m LocalHistory -> m E
forall a b. (a -> b) -> a -> b
$ StateT LocalHistory m () -> LocalHistory -> m LocalHistory
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT (DepT m () -> StateT LocalHistory m ()
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT (DepT m () -> StateT LocalHistory m ())
-> DepT m () -> StateT LocalHistory m ()
forall a b. (a -> b) -> a -> b
$ DepT m ()
a) LocalHistory
forall a. Default a => a
def

-- dependency tracking

depends :: E -> E -> E
depends :: E -> E -> E
depends E
a1 E
a2 =
  case RatedExp E -> Exp E
forall a. RatedExp a -> Exp a
ratedExpExp (E -> RatedExp E
forall (f :: * -> *). Fix f -> f (Fix f)
unFix E
a2) of
    Exp E
Starts -> E
a1
    Exp E
_ ->
      case RatedExp E -> Exp E
forall a. RatedExp a -> Exp a
ratedExpExp (E -> RatedExp E
forall (f :: * -> *). Fix f -> f (Fix f)
unFix E
a1) of
        Exp E
Starts -> E
a2
        Exp E
_      -> Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ PrimOr E -> PrimOr E -> Exp E
forall a. a -> a -> MainExp a
Seq (E -> PrimOr E
toPrimOr E
a1) (E -> PrimOr E
toPrimOr E
a2)

depT :: Monad m => E -> DepT m E
depT :: forall (m :: * -> *). Monad m => E -> DepT m E
depT E
a = StateT LocalHistory m E -> DepT m E
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m E -> DepT m E)
-> StateT LocalHistory m E -> DepT m E
forall a b. (a -> b) -> a -> b
$ do
    LocalHistory
s <- StateT LocalHistory m LocalHistory
forall (m :: * -> *) s. Monad m => StateT s m s
get
    let a1 :: E
a1 = E -> E
rehashE (E -> E) -> E -> E
forall a b. (a -> b) -> a -> b
$ RatedExp E -> E
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (RatedExp E -> E) -> RatedExp E -> E
forall a b. (a -> b) -> a -> b
$ (E -> RatedExp E
forall (f :: * -> *). Fix f -> f (Fix f)
unFix E
a) { ratedExpDepends = Just (newLineNum s) }
    LocalHistory -> StateT LocalHistory m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put (LocalHistory -> StateT LocalHistory m ())
-> LocalHistory -> StateT LocalHistory m ()
forall a b. (a -> b) -> a -> b
$ LocalHistory
s {
        newLineNum = succ $ newLineNum s -- ,
        -- expDependency = depends (expDependency s) a1
        }
    E -> StateT LocalHistory m E
forall a. a -> StateT LocalHistory m a
forall (m :: * -> *) a. Monad m => a -> m a
return E
a1

depT_ :: (Monad m) => E -> DepT m ()
depT_ :: forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ E
a = -- fmap (const ()) . depT
  StateT LocalHistory m () -> DepT m ()
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m () -> DepT m ())
-> StateT LocalHistory m () -> DepT m ()
forall a b. (a -> b) -> a -> b
$ do
    LocalHistory
s <- StateT LocalHistory m LocalHistory
forall (m :: * -> *) s. Monad m => StateT s m s
get
    let a1 :: E
a1 = E -> E
rehashE (E -> E) -> E -> E
forall a b. (a -> b) -> a -> b
$ RatedExp E -> E
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (RatedExp E -> E) -> RatedExp E -> E
forall a b. (a -> b) -> a -> b
$ (E -> RatedExp E
forall (f :: * -> *). Fix f -> f (Fix f)
unFix E
a) { ratedExpDepends = Just (newLineNum s) }
    LocalHistory -> StateT LocalHistory m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put (LocalHistory -> StateT LocalHistory m ())
-> LocalHistory -> StateT LocalHistory m ()
forall a b. (a -> b) -> a -> b
$ LocalHistory
s {
        newLineNum = succ $ newLineNum s,
        expDependency = depends (expDependency s) a1
        }
    () -> StateT LocalHistory m ()
forall a. a -> StateT LocalHistory m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()


toBlock :: Monad m => DepT m () -> DepT m (CodeBlock E)
toBlock :: forall (m :: * -> *). Monad m => DepT m () -> DepT m (CodeBlock E)
toBlock (DepT StateT LocalHistory m ()
act) = StateT LocalHistory m (CodeBlock E) -> DepT m (CodeBlock E)
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m (CodeBlock E) -> DepT m (CodeBlock E))
-> StateT LocalHistory m (CodeBlock E) -> DepT m (CodeBlock E)
forall a b. (a -> b) -> a -> b
$ do
  StateT LocalHistory m ()
act
  E -> CodeBlock E
forall a. a -> CodeBlock a
CodeBlock (E -> CodeBlock E)
-> StateT LocalHistory m E -> StateT LocalHistory m (CodeBlock E)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LocalHistory -> E) -> StateT LocalHistory m E
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets LocalHistory -> E
expDependency

mdepT :: (Monad m) => MultiOut [E] -> MultiOut (DepT m [E])
mdepT :: forall (m :: * -> *).
Monad m =>
MultiOut [E] -> MultiOut (DepT m [E])
mdepT MultiOut [E]
mas = \Int
n -> (E -> DepT m E) -> [E] -> DepT m [E]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM E -> DepT m E
forall (m :: * -> *). Monad m => E -> DepT m E
depT ([E] -> DepT m [E]) -> [E] -> DepT m [E]
forall a b. (a -> b) -> a -> b
$ ( MultiOut [E] -> MultiOut [E]
forall a b. (a -> b) -> a -> b
$ Int
n) MultiOut [E]
mas

stripDepT :: Monad m => DepT m a -> m a
stripDepT :: forall (m :: * -> *) a. Monad m => DepT m a -> m a
stripDepT (DepT StateT LocalHistory m a
a) = StateT LocalHistory m a -> LocalHistory -> m a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT StateT LocalHistory m a
a LocalHistory
forall a. Default a => a
def

stmtOnlyT :: Monad m => Exp E -> DepT m ()
stmtOnlyT :: forall (m :: * -> *). Monad m => Exp E -> DepT m ()
stmtOnlyT Exp E
stmt = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate Exp E
stmt

-- local variables

newLocalVars :: Monad m => [Rate] -> m [E] -> DepT m [Var]
newLocalVars :: forall (m :: * -> *). Monad m => [Rate] -> m [E] -> DepT m [Var]
newLocalVars [Rate]
rs m [E]
vs = do
    [Var]
vars <- (Rate -> DepT m Var) -> [Rate] -> DepT m [Var]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Rate -> DepT m Var
forall (m :: * -> *). Monad m => Rate -> DepT m Var
newVar [Rate]
rs
    (Var -> E -> DepT m ()) -> [Var] -> [E] -> DepT m ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
zipWithM_ Var -> E -> DepT m ()
forall (m :: * -> *). Monad m => Var -> E -> DepT m ()
initVar [Var]
vars ([E] -> DepT m ()) -> DepT m [E] -> DepT m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m [E] -> DepT m [E]
forall (m :: * -> *) a. Monad m => m a -> DepT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m [E]
vs
    [Var] -> DepT m [Var]
forall a. a -> DepT m a
forall (m :: * -> *) a. Monad m => a -> m a
return [Var]
vars

newLocalVar :: Monad m => Rate -> m E -> DepT m Var
newLocalVar :: forall (m :: * -> *). Monad m => Rate -> m E -> DepT m Var
newLocalVar Rate
rate m E
val = do
    Var
var <- Rate -> DepT m Var
forall (m :: * -> *). Monad m => Rate -> DepT m Var
newVar Rate
rate
    Var -> E -> DepT m ()
forall (m :: * -> *). Monad m => Var -> E -> DepT m ()
initVar Var
var (E -> DepT m ()) -> DepT m E -> DepT m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m E -> DepT m E
forall (m :: * -> *) a. Monad m => m a -> DepT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m E
val
    Var -> DepT m Var
forall a. a -> DepT m a
forall (m :: * -> *) a. Monad m => a -> m a
return Var
var

newVar :: Monad m => Rate -> DepT m Var
newVar :: forall (m :: * -> *). Monad m => Rate -> DepT m Var
newVar Rate
rate = StateT LocalHistory m Var -> DepT m Var
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m Var -> DepT m Var)
-> StateT LocalHistory m Var -> DepT m Var
forall a b. (a -> b) -> a -> b
$ do
    LocalHistory
s <- StateT LocalHistory m LocalHistory
forall (m :: * -> *) s. Monad m => StateT s m s
get
    let v :: Var
v = VarType -> Rate -> Name -> Var
Var VarType
LocalVar Rate
rate (String -> Name
Text.pack (String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ LocalHistory -> Int
newLocalVarId LocalHistory
s)
    LocalHistory -> StateT LocalHistory m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
put (LocalHistory -> StateT LocalHistory m ())
-> LocalHistory -> StateT LocalHistory m ()
forall a b. (a -> b) -> a -> b
$ LocalHistory
s { newLocalVarId = succ $ newLocalVarId s }
    Var -> StateT LocalHistory m Var
forall a. a -> StateT LocalHistory m a
forall (m :: * -> *) a. Monad m => a -> m a
return Var
v

--------------------------------------------------
-- variables

-- generic funs

writeVar :: Monad m => Var -> E -> DepT m ()
writeVar :: forall (m :: * -> *). Monad m => Var -> E -> DepT m ()
writeVar Var
v E
x = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> PrimOr E -> Exp E
forall a. Var -> a -> MainExp a
WriteVar Var
v (PrimOr E -> Exp E) -> PrimOr E -> Exp E
forall a b. (a -> b) -> a -> b
$ E -> PrimOr E
toPrimOr E
x

readVar :: Monad m => Var -> DepT m E
readVar :: forall (m :: * -> *). Monad m => Var -> DepT m E
readVar Var
v = E -> DepT m E
forall (m :: * -> *). Monad m => E -> DepT m E
depT (E -> DepT m E) -> E -> DepT m E
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> Exp E
forall a. Var -> MainExp a
ReadVar Var
v

readOnlyVar :: Var -> E
readOnlyVar :: Var -> E
readOnlyVar Var
v = Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> Exp E
forall a. Var -> MainExp a
ReadVar Var
v

initVar :: Monad m => Var -> E -> DepT m ()
initVar :: forall (m :: * -> *). Monad m => Var -> E -> DepT m ()
initVar Var
v E
x = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> PrimOr E -> Exp E
forall a. Var -> a -> MainExp a
InitVar Var
v (PrimOr E -> Exp E) -> PrimOr E -> Exp E
forall a b. (a -> b) -> a -> b
$ E -> PrimOr E
toPrimOr (E -> PrimOr E) -> E -> PrimOr E
forall a b. (a -> b) -> a -> b
$ Rate -> E -> E
setRate Rate
Ir E
x

appendVarBy :: Monad m => (E -> E -> E) -> Var -> E -> DepT m ()
appendVarBy :: forall (m :: * -> *).
Monad m =>
(E -> E -> E) -> Var -> E -> DepT m ()
appendVarBy E -> E -> E
op Var
v E
x = Var -> E -> DepT m ()
forall (m :: * -> *). Monad m => Var -> E -> DepT m ()
writeVar Var
v (E -> DepT m ()) -> (E -> E) -> E -> DepT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. E -> E -> E
op E
x (E -> DepT m ()) -> DepT m E -> DepT m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Var -> DepT m E
forall (m :: * -> *). Monad m => Var -> DepT m E
readVar Var
v

--------------------------------------------------
-- arrays

-- init

newLocalArrVar :: Monad m => Rate -> m [E] -> DepT m Var
newLocalArrVar :: forall (m :: * -> *). Monad m => Rate -> m [E] -> DepT m Var
newLocalArrVar Rate
rate m [E]
val = do
    Var
var <- Rate -> DepT m Var
forall (m :: * -> *). Monad m => Rate -> DepT m Var
newVar Rate
rate
    Var -> [E] -> DepT m ()
forall (m :: * -> *). Monad m => Var -> [E] -> DepT m ()
initArr Var
var ([E] -> DepT m ()) -> DepT m [E] -> DepT m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m [E] -> DepT m [E]
forall (m :: * -> *) a. Monad m => m a -> DepT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m [E]
val
    Var -> DepT m Var
forall a. a -> DepT m a
forall (m :: * -> *) a. Monad m => a -> m a
return Var
var

newTmpArrVar :: Monad m => Rate -> DepT m Var
newTmpArrVar :: forall (m :: * -> *). Monad m => Rate -> DepT m Var
newTmpArrVar Rate
rate = Rate -> DepT m Var
forall (m :: * -> *). Monad m => Rate -> DepT m Var
newVar Rate
rate

-- ops

readArr :: Monad m => Var -> [E] -> DepT m E
readArr :: forall (m :: * -> *). Monad m => Var -> [E] -> DepT m E
readArr Var
v [E]
ixs = E -> DepT m E
forall (m :: * -> *). Monad m => E -> DepT m E
depT (E -> DepT m E) -> E -> DepT m E
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> ArrIndex (PrimOr E) -> Exp E
forall a. Var -> ArrIndex a -> MainExp a
ReadArr Var
v ((E -> PrimOr E) -> [E] -> ArrIndex (PrimOr E)
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap E -> PrimOr E
toPrimOr [E]
ixs)

readOnlyArr :: Var -> [E] -> E
readOnlyArr :: Var -> [E] -> E
readOnlyArr Var
v [E]
ixs = Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> ArrIndex (PrimOr E) -> Exp E
forall a. Var -> ArrIndex a -> MainExp a
ReadArr Var
v ((E -> PrimOr E) -> [E] -> ArrIndex (PrimOr E)
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap E -> PrimOr E
toPrimOr [E]
ixs)

writeArr :: Monad m => Var -> [E] -> E -> DepT m ()
writeArr :: forall (m :: * -> *). Monad m => Var -> [E] -> E -> DepT m ()
writeArr Var
v [E]
ixs E
a = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> ArrIndex (PrimOr E) -> PrimOr E -> Exp E
forall a. Var -> ArrIndex a -> a -> MainExp a
WriteArr Var
v ((E -> PrimOr E) -> [E] -> ArrIndex (PrimOr E)
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap E -> PrimOr E
toPrimOr [E]
ixs) (E -> PrimOr E
toPrimOr E
a)

writeInitArr :: Monad m => Var -> [E] -> E -> DepT m ()
writeInitArr :: forall (m :: * -> *). Monad m => Var -> [E] -> E -> DepT m ()
writeInitArr Var
v [E]
ixs E
a = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> ArrIndex (PrimOr E) -> PrimOr E -> Exp E
forall a. Var -> ArrIndex a -> a -> MainExp a
WriteInitArr Var
v ((E -> PrimOr E) -> [E] -> ArrIndex (PrimOr E)
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap E -> PrimOr E
toPrimOr [E]
ixs) (E -> PrimOr E
toPrimOr E
a)

initArr :: Monad m => Var -> [E] -> DepT m ()
initArr :: forall (m :: * -> *). Monad m => Var -> [E] -> DepT m ()
initArr Var
v [E]
xs = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Var -> ArrIndex (PrimOr E) -> Exp E
forall a. Var -> ArrIndex a -> MainExp a
InitArr Var
v (ArrIndex (PrimOr E) -> Exp E) -> ArrIndex (PrimOr E) -> Exp E
forall a b. (a -> b) -> a -> b
$ (E -> PrimOr E) -> [E] -> ArrIndex (PrimOr E)
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap E -> PrimOr E
toPrimOr [E]
xs

appendArrBy :: Monad m => (E -> E -> E) -> Var -> [E] -> E -> DepT m ()
appendArrBy :: forall (m :: * -> *).
Monad m =>
(E -> E -> E) -> Var -> [E] -> E -> DepT m ()
appendArrBy E -> E -> E
op Var
v [E]
ixs E
x = Var -> [E] -> E -> DepT m ()
forall (m :: * -> *). Monad m => Var -> [E] -> E -> DepT m ()
writeArr Var
v [E]
ixs (E -> DepT m ()) -> (E -> E) -> E -> DepT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. E -> E -> E
op E
x (E -> DepT m ()) -> DepT m E -> DepT m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Var -> [E] -> DepT m E
forall (m :: * -> *). Monad m => Var -> [E] -> DepT m E
readArr Var
v [E]
ixs

--------------------------------------------------
-- read global macros arguments

readMacrosDouble :: Text -> E
readMacrosDouble :: Name -> E
readMacrosDouble = (Name -> Exp E) -> Rate -> Name -> E
readMacrosBy Name -> Exp E
forall a. Name -> MainExp a
ReadMacrosDouble Rate
Ir

readMacrosInt :: Text -> E
readMacrosInt :: Name -> E
readMacrosInt = (Name -> Exp E) -> Rate -> Name -> E
readMacrosBy Name -> Exp E
forall a. Name -> MainExp a
ReadMacrosInt Rate
Ir

readMacrosString :: Text -> E
readMacrosString :: Name -> E
readMacrosString = (Name -> Exp E) -> Rate -> Name -> E
readMacrosBy Name -> Exp E
forall a. Name -> MainExp a
ReadMacrosString Rate
Sr

initMacrosDouble :: Monad m => Text -> Double -> DepT m ()
initMacrosDouble :: forall (m :: * -> *). Monad m => Name -> Double -> DepT m ()
initMacrosDouble = (Name -> Double -> Exp E) -> Name -> Double -> DepT m ()
forall (m :: * -> *) a.
Monad m =>
(Name -> a -> Exp E) -> Name -> a -> DepT m ()
initMacrosBy Name -> Double -> Exp E
forall a. Name -> Double -> MainExp a
InitMacrosDouble

initMacrosString :: Monad m => Text -> Text -> DepT m ()
initMacrosString :: forall (m :: * -> *). Monad m => Name -> Name -> DepT m ()
initMacrosString = (Name -> Name -> Exp E) -> Name -> Name -> DepT m ()
forall (m :: * -> *) a.
Monad m =>
(Name -> a -> Exp E) -> Name -> a -> DepT m ()
initMacrosBy Name -> Name -> Exp E
forall a. Name -> Name -> MainExp a
InitMacrosString

initMacrosInt :: Monad m => Text -> Int -> DepT m ()
initMacrosInt :: forall (m :: * -> *). Monad m => Name -> Int -> DepT m ()
initMacrosInt = (Name -> Int -> Exp E) -> Name -> Int -> DepT m ()
forall (m :: * -> *) a.
Monad m =>
(Name -> a -> Exp E) -> Name -> a -> DepT m ()
initMacrosBy Name -> Int -> Exp E
forall a. Name -> Int -> MainExp a
InitMacrosInt

readMacrosBy :: (Text -> Exp E) -> Rate -> Text -> E
readMacrosBy :: (Name -> Exp E) -> Rate -> Name -> E
readMacrosBy Name -> Exp E
readMacro Rate
rate Name
name = Rate -> Exp E -> E
withRate Rate
rate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Name -> Exp E
readMacro Name
name

initMacrosBy :: Monad m => (Text -> a -> Exp E) -> Text -> a -> DepT m ()
initMacrosBy :: forall (m :: * -> *) a.
Monad m =>
(Name -> a -> Exp E) -> Name -> a -> DepT m ()
initMacrosBy Name -> a -> Exp E
maker Name
name a
value = E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Name -> a -> Exp E
maker Name
name a
value