{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module Futhark.MonadFreshNames
( MonadFreshNames (..)
, modifyNameSource
, newName
, newNameFromString
, newID
, newIDFromString
, newVName
, newVName'
, newIdent
, newIdent'
, newIdents
, newParam
, newParam'
, module Futhark.FreshNames
) where
import Control.Monad.Except
import qualified Control.Monad.State.Lazy
import qualified Control.Monad.State.Strict
import qualified Control.Monad.Writer.Lazy
import qualified Control.Monad.Writer.Strict
import qualified Control.Monad.RWS.Lazy
import qualified Control.Monad.RWS.Strict
import qualified Control.Monad.Trans.Maybe
import Control.Monad.Reader
import Futhark.Representation.AST.Syntax
import qualified Futhark.FreshNames as FreshNames
import Futhark.FreshNames hiding (newName, newVName)
class (Applicative m, Monad m) => MonadFreshNames m where
getNameSource :: m VNameSource
putNameSource :: VNameSource -> m ()
instance (Applicative im, Monad im) => MonadFreshNames (Control.Monad.State.Lazy.StateT VNameSource im) where
getNameSource = Control.Monad.State.Lazy.get
putNameSource = Control.Monad.State.Lazy.put
instance (Applicative im, Monad im) => MonadFreshNames (Control.Monad.State.Strict.StateT VNameSource im) where
getNameSource = Control.Monad.State.Strict.get
putNameSource = Control.Monad.State.Strict.put
instance (Applicative im, Monad im, Monoid w) =>
MonadFreshNames (Control.Monad.RWS.Lazy.RWST r w VNameSource im) where
getNameSource = Control.Monad.RWS.Lazy.get
putNameSource = Control.Monad.RWS.Lazy.put
instance (Applicative im, Monad im, Monoid w) =>
MonadFreshNames (Control.Monad.RWS.Strict.RWST r w VNameSource im) where
getNameSource = Control.Monad.RWS.Strict.get
putNameSource = Control.Monad.RWS.Strict.put
modifyNameSource :: MonadFreshNames m => (VNameSource -> (a, VNameSource)) -> m a
modifyNameSource m = do src <- getNameSource
let (x,src') = m src
putNameSource src'
return x
newName :: MonadFreshNames m => VName -> m VName
newName = modifyNameSource . flip FreshNames.newName
newNameFromString :: MonadFreshNames m => String -> m VName
newNameFromString s = newName $ VName (nameFromString s) 0
newID :: MonadFreshNames m => Name -> m VName
newID s = newName $ VName s 0
newIDFromString :: MonadFreshNames m => String -> m VName
newIDFromString = newID . nameFromString
newVName :: MonadFreshNames m => String -> m VName
newVName = newID . nameFromString
newVName' :: MonadFreshNames m => (String -> String) -> String -> m VName
newVName' f = newID . nameFromString . f
newIdent :: MonadFreshNames m =>
String -> Type -> m Ident
newIdent s t = do
s' <- newID $ nameFromString s
return $ Ident s' t
newIdent' :: MonadFreshNames m =>
(String -> String)
-> Ident -> m Ident
newIdent' f ident =
newIdent (f $ nameToString $ baseName $ identName ident)
(identType ident)
newIdents :: MonadFreshNames m =>
String -> [Type] -> m [Ident]
newIdents = mapM . newIdent
newParam :: MonadFreshNames m =>
String -> attr -> m (Param attr)
newParam s t = do
s' <- newID $ nameFromString s
return $ Param s' t
newParam' :: MonadFreshNames m =>
(String -> String)
-> Param attr -> m (Param attr)
newParam' f param =
newParam (f $ nameToString $ baseName $ paramName param)
(paramAttr param)
instance MonadFreshNames m => MonadFreshNames (ReaderT s m) where
getNameSource = lift getNameSource
putNameSource = lift . putNameSource
instance (MonadFreshNames m, Monoid s) =>
MonadFreshNames (Control.Monad.Writer.Lazy.WriterT s m) where
getNameSource = lift getNameSource
putNameSource = lift . putNameSource
instance (MonadFreshNames m, Monoid s) =>
MonadFreshNames (Control.Monad.Writer.Strict.WriterT s m) where
getNameSource = lift getNameSource
putNameSource = lift . putNameSource
instance MonadFreshNames m =>
MonadFreshNames (Control.Monad.Trans.Maybe.MaybeT m) where
getNameSource = lift getNameSource
putNameSource = lift . putNameSource
instance MonadFreshNames m =>
MonadFreshNames (ExceptT e m) where
getNameSource = lift getNameSource
putNameSource = lift . putNameSource