-- | Builtin types and functions used by the vectoriser.
--   The source program uses functions from GHC.PArr, which the vectoriser rewrites
--   to use equivalent vectorised versions in the DPH backend packages.
--
--   The `Builtins` structure holds the name of all the things in the DPH packages
--   we will need. We can get specific things using the selectors, which print a
--   civilized panic message if the specified thing cannot be found.
--
module Vectorise.Builtins (
	-- * Builtins
	Builtins(..),
	indexBuiltin,
	
	-- * Wrapped selectors
	selTy,
	selReplicate,
	selPick,
	selTags,
	selElements,
	sumTyCon,
	prodTyCon,
	prodDataCon,
	combinePDVar,
	scalarZip,
	closureCtrFun,

	-- * Initialisation
	initBuiltins, initBuiltinVars, initBuiltinTyCons, initBuiltinDataCons,
	initBuiltinPAs, initBuiltinPRs,
	initBuiltinBoxedTyCons, initBuiltinScalars,
	
	-- * Lookup
	primMethod,
	primPArray
) where
import Vectorise.Builtins.Base
import Vectorise.Builtins.Modules
import Vectorise.Builtins.Initialise

import TysPrim
import IfaceEnv
import TyCon
import DsMonad
import NameEnv
import Name
import Var
import Control.Monad


-- | Lookup a method function given its name and instance type.
primMethod :: TyCon -> String -> Builtins -> DsM (Maybe Var)
primMethod  tycon method (Builtins { dphModules = mods })
  | Just suffix <- lookupNameEnv prim_ty_cons (tyConName tycon)
  = liftM Just
  $ dsLookupGlobalId =<< lookupOrig (dph_Unboxed mods)
                                    (mkVarOcc $ method ++ suffix)

  | otherwise = return Nothing

-- | Lookup the representation type we use for PArrays that contain a given element type.
primPArray :: TyCon -> Builtins -> DsM (Maybe TyCon)
primPArray tycon (Builtins { dphModules = mods })
  | Just suffix <- lookupNameEnv prim_ty_cons (tyConName tycon)
  = liftM Just
  $ dsLookupTyCon =<< lookupOrig (dph_Unboxed mods)
                                 (mkTcOcc $ "PArray" ++ suffix)

  | otherwise = return Nothing

prim_ty_cons :: NameEnv String
prim_ty_cons = mkNameEnv [mk_prim intPrimTyCon]
  where
    mk_prim tycon = (tyConName tycon, '_' : getOccString tycon)