module Vectorise.Monad.Naming
  ( mkLocalisedName
  , mkDerivedName
  , mkVectId
  , cloneVar
  , newExportedVar
  , newLocalVar
  , newLocalVars
  , newDummyVar
  , newTyVar
  , newCoVar
  )
where
import GhcPrelude
import Vectorise.Monad.Base
import DsMonad
import TcType
import Type
import Var
import Module
import Name
import SrcLoc
import MkId
import Id
import IdInfo( IdDetails(VanillaId) )
import FastString
import Control.Monad
mkLocalisedName :: (Maybe String -> OccName -> OccName) -> Name -> VM Name
mkLocalisedName mk_occ name
  = do { mod <- liftDs getModule
       ; u   <- liftDs newUnique
       ; let occ_name = mkLocalisedOccName mod mk_occ name
             new_name | isExternalName name = mkExternalName u mod occ_name (nameSrcSpan name)
                      | otherwise           = mkSystemName   u     occ_name
       ; return new_name }
mkDerivedName :: (OccName -> OccName) -> Name -> VM Name
mkDerivedName mk_occ name
  = do { u   <- liftDs newUnique
       ; return (mkExternalName u (nameModule name)
                                  (mk_occ (nameOccName name))
                                  (nameSrcSpan name)) }
mkVectId :: Id -> Type -> VM Id
mkVectId id ty
  = do { name <- mkLocalisedName mkVectOcc (getName id)
       ; let id' | isDFunId id     = MkId.mkDictFunId name tvs theta cls tys
                 | isExportedId id = Id.mkExportedLocalId VanillaId name ty
                 | otherwise       = Id.mkLocalIdOrCoVar name ty
       ; return id'
       }
  where
    
    
    
    (tvs, theta, pty) = tcSplitSigmaTy  ty
    (cls, tys)        = tcSplitDFunHead pty
cloneVar :: Var -> VM Var
cloneVar var = liftM (setIdUnique var) (liftDs newUnique)
newExportedVar :: OccName -> Type -> VM Var
newExportedVar occ_name ty
 = do mod <- liftDs getModule
      u   <- liftDs newUnique
      let name = mkExternalName u mod occ_name noSrcSpan
      return $ Id.mkExportedLocalId VanillaId name ty
newLocalVar :: FastString -> Type -> VM Var
newLocalVar fs ty
 = do u <- liftDs newUnique
      return $ mkSysLocalOrCoVar fs u ty
newLocalVars :: FastString -> [Type] -> VM [Var]
newLocalVars fs = mapM (newLocalVar fs)
newDummyVar :: Type -> VM Var
newDummyVar = newLocalVar (fsLit "vv")
newTyVar :: FastString -> Kind -> VM Var
newTyVar fs k
 = do u <- liftDs newUnique
      return $ mkTyVar (mkSysTvName u fs) k
newCoVar :: FastString -> Kind -> VM Var
newCoVar fs k
  = do u <- liftDs newUnique
       return $ mkCoVar (mkSystemVarName u fs) k