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

    -- * 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

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
    , LocalHistory -> Int
newTmpVarNum  :: !Int
    }

instance Default LocalHistory where
    def :: LocalHistory
def = E -> Int -> Int -> Int -> LocalHistory
LocalHistory (Exp E -> E
noRate Exp E
forall a. MainExp a
Starts) Int
0 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 = 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
$ DepT m a -> StateT LocalHistory m a
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT DepT m a
ma StateT LocalHistory m a
-> (a -> StateT LocalHistory m b) -> StateT LocalHistory m b
forall a b.
StateT LocalHistory m a
-> (a -> StateT LocalHistory m b) -> StateT LocalHistory m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DepT m b -> StateT LocalHistory m b
forall (m :: * -> *) a. DepT m a -> StateT LocalHistory m a
unDepT (DepT m b -> StateT LocalHistory m b)
-> (a -> DepT m b) -> a -> StateT LocalHistory m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> DepT m b
mf

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 a -> m E
execDepT :: forall (m :: * -> *) a. (Functor m, Monad m) => DepT m a -> m E
execDepT DepT m a
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 a -> LocalHistory -> m LocalHistory
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT (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

-- 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)

tfmDep :: Monad m => Info -> [E] -> DepT m E
tfmDep :: forall (m :: * -> *). Monad m => Info -> [E] -> DepT m E
tfmDep Info
info [E]
args = (TmpVar -> E) -> DepT m TmpVar -> DepT m E
forall a b. (a -> b) -> DepT m a -> DepT m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TmpVar -> E
fromTmpVar (DepT m TmpVar -> DepT m E) -> DepT m TmpVar -> DepT m E
forall a b. (a -> b) -> a -> b
$ Info -> [E] -> DepT m TmpVar
forall (m :: * -> *). Monad m => Info -> [E] -> DepT m TmpVar
tfmDepVar Info
info [E]
args

tfmDepVar :: Monad m => Info -> [E] -> DepT m TmpVar
tfmDepVar :: forall (m :: * -> *). Monad m => Info -> [E] -> DepT m TmpVar
tfmDepVar Info
info [E]
args = do
  TmpVar
v <- Maybe Info -> DepT m TmpVar
forall (m :: * -> *). Monad m => Maybe Info -> DepT m TmpVar
getNewTmpVar (Info -> Maybe Info
forall a. a -> Maybe a
Just Info
info)
  E -> DepT m ()
forall (m :: * -> *). Monad m => E -> DepT m ()
depT_ (E -> DepT m ()) -> E -> DepT m ()
forall a b. (a -> b) -> a -> b
$ TmpVar -> Info -> [E] -> E
tfmInit TmpVar
v Info
info [E]
args
  TmpVar -> DepT m TmpVar
forall a. a -> DepT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TmpVar
v

tfmInit:: TmpVar -> Info -> [E] -> E
tfmInit :: TmpVar -> Info -> [E] -> E
tfmInit TmpVar
v Info
info [E]
args = Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ TmpVar -> Info -> [PrimOr E] -> Exp E
forall a. TmpVar -> Info -> [a] -> MainExp a
TfmInit TmpVar
v Info
info ([PrimOr E] -> Exp E) -> [PrimOr E] -> Exp E
forall a b. (a -> b) -> a -> b
$ [Rate] -> [E] -> [PrimOr E]
toArgs (Info -> [Rate]
getInfoRates Info
info) [E]
args

toArgs :: [Rate] -> [E] -> [PrimOr E]
toArgs :: [Rate] -> [E] -> [PrimOr E]
toArgs = (Rate -> E -> PrimOr E) -> [Rate] -> [E] -> [PrimOr E]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Rate -> E -> PrimOr E
toPrimOrTfm

getNewTmpVar :: Monad m => Maybe Info -> DepT m TmpVar
getNewTmpVar :: forall (m :: * -> *). Monad m => Maybe Info -> DepT m TmpVar
getNewTmpVar Maybe Info
mInfo = StateT LocalHistory m TmpVar -> DepT m TmpVar
forall (m :: * -> *) a. StateT LocalHistory m a -> DepT m a
DepT (StateT LocalHistory m TmpVar -> DepT m TmpVar)
-> StateT LocalHistory m TmpVar -> DepT m TmpVar
forall a b. (a -> b) -> a -> b
$ do
  Int
n <- (LocalHistory -> Int) -> StateT LocalHistory m Int
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets LocalHistory -> Int
newTmpVarNum
  (LocalHistory -> LocalHistory) -> StateT LocalHistory m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify' ((LocalHistory -> LocalHistory) -> StateT LocalHistory m ())
-> (LocalHistory -> LocalHistory) -> StateT LocalHistory m ()
forall a b. (a -> b) -> a -> b
$ \LocalHistory
s -> LocalHistory
s { newTmpVarNum = n + 1 }
  TmpVar -> StateT LocalHistory m TmpVar
forall a. a -> StateT LocalHistory m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe TmpVarRate -> Maybe Info -> Int -> TmpVar
TmpVar Maybe TmpVarRate
forall a. Maybe a
Nothing Maybe Info
mInfo Int
n)

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
      }

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 => IfRate -> Var -> E -> DepT m ()
writeVar :: forall (m :: * -> *). Monad m => IfRate -> Var -> E -> DepT m ()
writeVar IfRate
ifRate 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
$ IfRate -> Var -> PrimOr E -> Exp E
forall a. IfRate -> Var -> a -> MainExp a
WriteVar IfRate
ifRate 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 => IfRate -> Var -> DepT m E
readVar :: forall (m :: * -> *). Monad m => IfRate -> Var -> DepT m E
readVar IfRate
ifRate Var
v = do
  TmpVar
tmp <- Maybe Info -> DepT m TmpVar
forall (m :: * -> *). Monad m => Maybe Info -> DepT m TmpVar
getNewTmpVar Maybe Info
forall a. Maybe a
Nothing
  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
$ IfRate -> TmpVar -> Var -> Exp E
forall a. IfRate -> TmpVar -> Var -> MainExp a
ReadVarTmp IfRate
ifRate TmpVar
tmp Var
v
  E -> DepT m E
forall a. a -> DepT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (E -> DepT m E) -> E -> DepT m E
forall a b. (a -> b) -> a -> b
$ TmpVar -> E
fromTmpVar TmpVar
tmp

fromTmpVar :: TmpVar -> E
fromTmpVar :: TmpVar -> E
fromTmpVar TmpVar
v = Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ Prim -> Exp E
forall a. Prim -> MainExp a
ExpPrim (Prim -> Exp E) -> Prim -> Exp E
forall a b. (a -> b) -> a -> b
$ TmpVar -> Prim
PrimTmpVar TmpVar
v

readOnlyVar :: IfRate -> Var -> E
readOnlyVar :: IfRate -> Var -> E
readOnlyVar IfRate
ifRate Var
v = Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ IfRate -> Var -> Exp E
forall a. IfRate -> Var -> MainExp a
ReadVar IfRate
ifRate 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) -> IfRate -> Var -> E -> DepT m ()
appendVarBy :: forall (m :: * -> *).
Monad m =>
(E -> E -> E) -> IfRate -> Var -> E -> DepT m ()
appendVarBy E -> E -> E
op IfRate
ifRate Var
v E
x = IfRate -> Var -> E -> DepT m ()
forall (m :: * -> *). Monad m => IfRate -> Var -> E -> DepT m ()
writeVar IfRate
ifRate 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
=<< IfRate -> Var -> DepT m E
forall (m :: * -> *). Monad m => IfRate -> Var -> DepT m E
readVar IfRate
ifRate Var
v

{-
setRateDep :: Monad m => Rate -> E -> DepT m E
setRateDep rate a = do
  case ratedExpExp $ unFix a of
    ExpPrim (PrimTmpVar _) ->
      setLastDepRate rate
    _ -> pure ()
  pure (setRate rate a)

setLastDepRate :: Monad m => Rate -> DepT m ()
setLastDepRate rate = DepT $
  modify' $ \st -> st { expDependency = setOpcodeRate (expDependency st) }
  where
    setOpcodeRate arg@(Fix expr) =
      case ratedExpExp expr of
        Seq prevExpr (PrimOr (Right (Fix lastExpr))) ->
          case ratedExpExp lastExpr of
            TfmInit _ _ _ ->
              let
                wrapLast a = rehashE $ Fix $ expr { ratedExpExp = Seq prevExpr (PrimOr (Right (rehashE $ Fix a))) }
              in
                wrapLast $ lastExpr { ratedExpRate = Just rate }
            _ -> arg
        _ -> arg
-}

--------------------------------------------------
-- 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 => IfRate -> Var -> [E] -> DepT m E
readArr :: forall (m :: * -> *). Monad m => IfRate -> Var -> [E] -> DepT m E
readArr IfRate
ifRate Var
v [E]
ixs = do
  TmpVar
tmp <- Maybe Info -> DepT m TmpVar
forall (m :: * -> *). Monad m => Maybe Info -> DepT m TmpVar
getNewTmpVar Maybe Info
forall a. Maybe a
Nothing
  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
$ IfRate -> TmpVar -> Var -> [PrimOr E] -> Exp E
forall a. IfRate -> TmpVar -> Var -> [a] -> MainExp a
ReadArrTmp IfRate
ifRate TmpVar
tmp Var
v ((E -> PrimOr E) -> [E] -> [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 -> DepT m E
forall a. a -> DepT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (E -> DepT m E) -> E -> DepT m E
forall a b. (a -> b) -> a -> b
$ TmpVar -> E
fromTmpVar TmpVar
tmp

readOnlyArr :: IfRate -> Var -> [E] -> E
readOnlyArr :: IfRate -> Var -> [E] -> E
readOnlyArr IfRate
ifRate Var
v [E]
ixs = Exp E -> E
noRate (Exp E -> E) -> Exp E -> E
forall a b. (a -> b) -> a -> b
$ IfRate -> Var -> [PrimOr E] -> Exp E
forall a. IfRate -> Var -> [a] -> MainExp a
ReadArr IfRate
ifRate Var
v ((E -> PrimOr E) -> [E] -> [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 => IfRate -> Var -> [E] -> E -> DepT m ()
writeArr :: forall (m :: * -> *).
Monad m =>
IfRate -> Var -> [E] -> E -> DepT m ()
writeArr IfRate
ifRate 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
$ IfRate -> Var -> [PrimOr E] -> PrimOr E -> Exp E
forall a. IfRate -> Var -> [a] -> a -> MainExp a
WriteArr IfRate
ifRate Var
v ((E -> PrimOr E) -> [E] -> [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 => IfRate -> Var -> [E] -> E -> DepT m ()
writeInitArr :: forall (m :: * -> *).
Monad m =>
IfRate -> Var -> [E] -> E -> DepT m ()
writeInitArr IfRate
ifRate 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
$ IfRate -> Var -> [PrimOr E] -> PrimOr E -> Exp E
forall a. IfRate -> Var -> [a] -> a -> MainExp a
WriteInitArr IfRate
ifRate Var
v ((E -> PrimOr E) -> [E] -> [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 -> [PrimOr E] -> Exp E
forall a. Var -> [a] -> MainExp a
InitArr Var
v ([PrimOr E] -> Exp E) -> [PrimOr E] -> Exp E
forall a b. (a -> b) -> a -> b
$ (E -> PrimOr E) -> [E] -> [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) -> IfRate -> Var -> [E] -> E -> DepT m ()
appendArrBy :: forall (m :: * -> *).
Monad m =>
(E -> E -> E) -> IfRate -> Var -> [E] -> E -> DepT m ()
appendArrBy E -> E -> E
op IfRate
ifRate Var
v [E]
ixs E
x = IfRate -> Var -> [E] -> E -> DepT m ()
forall (m :: * -> *).
Monad m =>
IfRate -> Var -> [E] -> E -> DepT m ()
writeArr IfRate
ifRate 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
=<< IfRate -> Var -> [E] -> DepT m E
forall (m :: * -> *). Monad m => IfRate -> Var -> [E] -> DepT m E
readArr IfRate
ifRate 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