--- /dev/null
+
+module Vectorise.Monad.Global (
+ readGEnv,
+ setGEnv,
+ updGEnv,
+
+ -- * Vars
+ defGlobalVar,
+
+ -- * Scalars
+ globalScalars,
+
+ -- * TyCons
+ lookupTyCon,
+ lookupBoxedTyCon,
+ defTyCon,
+
+ -- * Datacons
+ lookupDataCon,
+ defDataCon,
+
+ -- * PA Dictionaries
+ lookupTyConPA,
+ defTyConPA,
+ defTyConPAs,
+
+ -- * PR Dictionaries
+ lookupTyConPR
+) where
+import Vectorise.Monad.Base
+import Vectorise.Env
+import TyCon
+import DataCon
+import NameEnv
+import Var
+import VarEnv
+import VarSet
+
+
+-- Global Environment ---------------------------------------------------------
+-- | Project something from the global environment.
+readGEnv :: (GlobalEnv -> a) -> VM a
+readGEnv f = VM $ \_ genv lenv -> return (Yes genv lenv (f genv))
+
+
+-- | Set the value of the global environment.
+setGEnv :: GlobalEnv -> VM ()
+setGEnv genv = VM $ \_ _ lenv -> return (Yes genv lenv ())
+
+
+-- | Update the global environment using the provided function.
+updGEnv :: (GlobalEnv -> GlobalEnv) -> VM ()
+updGEnv f = VM $ \_ genv lenv -> return (Yes (f genv) lenv ())
+
+
+-- Vars -----------------------------------------------------------------------
+-- | Add a mapping between a global var and its vectorised version to the state.
+defGlobalVar :: Var -> Var -> VM ()
+defGlobalVar v v' = updGEnv $ \env ->
+ env { global_vars = extendVarEnv (global_vars env) v v'
+ , global_exported_vars = upd (global_exported_vars env)
+ }
+ where
+ upd env | isExportedId v = extendVarEnv env v (v, v')
+ | otherwise = env
+
+
+-- Scalars --------------------------------------------------------------------
+-- | Get the set of global scalar variables.
+globalScalars :: VM VarSet
+globalScalars
+ = readGEnv global_scalars
+
+
+-- TyCons ---------------------------------------------------------------------
+-- | Lookup the vectorised version of a `TyCon` from the global environment.
+lookupTyCon :: TyCon -> VM (Maybe TyCon)
+lookupTyCon tc
+ | isUnLiftedTyCon tc || isTupleTyCon tc
+ = return (Just tc)
+
+ | otherwise
+ = readGEnv $ \env -> lookupNameEnv (global_tycons env) (tyConName tc)
+
+
+-- | Lookup the vectorised version of a boxed `TyCon` from the global environment.
+lookupBoxedTyCon :: TyCon -> VM (Maybe TyCon)
+lookupBoxedTyCon tc
+ = readGEnv $ \env -> lookupNameEnv (global_boxed_tycons env)
+ (tyConName tc)
+
+
+-- | Add a mapping between plain and vectorised `TyCon`s to the global environment.
+defTyCon :: TyCon -> TyCon -> VM ()
+defTyCon tc tc' = updGEnv $ \env ->
+ env { global_tycons = extendNameEnv (global_tycons env) (tyConName tc) tc' }
+
+
+-- DataCons -------------------------------------------------------------------
+-- | Lookup the vectorised version of a `DataCon` from the global environment.
+lookupDataCon :: DataCon -> VM (Maybe DataCon)
+lookupDataCon dc
+ | isTupleTyCon (dataConTyCon dc)
+ = return (Just dc)
+
+ | otherwise
+ = readGEnv $ \env -> lookupNameEnv (global_datacons env) (dataConName dc)
+
+
+-- | Add the mapping between plain and vectorised `DataCon`s to the global environment.
+defDataCon :: DataCon -> DataCon -> VM ()
+defDataCon dc dc' = updGEnv $ \env ->
+ env { global_datacons = extendNameEnv (global_datacons env) (dataConName dc) dc' }
+
+
+-- PA dictionaries ------------------------------------------------------------
+-- | Lookup a PA `TyCon` from the global environment.
+lookupTyConPA :: TyCon -> VM (Maybe Var)
+lookupTyConPA tc
+ = readGEnv $ \env -> lookupNameEnv (global_pa_funs env) (tyConName tc)
+
+
+-- | Add a mapping between a PA TyCon and is vectorised version to the global environment.
+defTyConPA :: TyCon -> Var -> VM ()
+defTyConPA tc pa = updGEnv $ \env ->
+ env { global_pa_funs = extendNameEnv (global_pa_funs env) (tyConName tc) pa }
+
+
+-- | Add several mapping between PA TyCons and their vectorised versions to the global environment.
+defTyConPAs :: [(TyCon, Var)] -> VM ()
+defTyConPAs ps = updGEnv $ \env ->
+ env { global_pa_funs = extendNameEnvList (global_pa_funs env)
+ [(tyConName tc, pa) | (tc, pa) <- ps] }
+
+
+-- PR Dictionaries ------------------------------------------------------------
+lookupTyConPR :: TyCon -> VM (Maybe Var)
+lookupTyConPR tc = readGEnv $ \env -> lookupNameEnv (global_pr_funs env) (tyConName tc)
+
+