\begin{code}
module MkCore (
        
        mkCoreLet, mkCoreLets,
        mkCoreApp, mkCoreApps, mkCoreConApps,
        mkCoreLams, mkWildCase, mkIfThenElse,
        mkWildValBinder, mkWildEvBinder,
        sortQuantVars, castBottomExpr,
        
        
        mkWordExpr, mkWordExprWord,
        mkIntExpr, mkIntExprInt,
        mkIntegerExpr,
        mkFloatExpr, mkDoubleExpr,
        mkCharExpr, mkStringExpr, mkStringExprFS,
        
        FloatBind(..), wrapFloat,
        
        mkEqBox,
        
        
        
        mkChunkified,
        
        
        mkCoreVarTup, mkCoreVarTupTy, mkCoreTup, 
        
        
        mkBigCoreVarTup, mkBigCoreVarTupTy,
        mkBigCoreTup, mkBigCoreTupTy,
        
        
        mkSmallTupleSelector, mkSmallTupleCase,
        
        
        mkTupleSelector, mkTupleCase,
        
        
        mkNilExpr, mkConsExpr, mkListExpr, 
        mkFoldrExpr, mkBuildExpr,
    	
    	mkRuntimeErrorApp, mkImpossibleExpr, errorIds,
    	rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID,
    	nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,
    	pAT_ERROR_ID, eRROR_ID, rEC_SEL_ERROR_ID, aBSENT_ERROR_ID,
        uNDEFINED_ID, undefinedName
    ) where
#include "HsVersions.h"
import Id
import Var      ( EvVar, setTyVarUnique )
import CoreSyn
import CoreUtils        ( exprType, needsCaseBinding, bindNonRec )
import Literal
import HscTypes
import TysWiredIn
import PrelNames
import TcType		( mkSigmaTy )
import Type
import Coercion
import TysPrim
import DataCon          ( DataCon, dataConWorkId )
import IdInfo		( vanillaIdInfo, setStrictnessInfo, 
                          setArityInfo )
import Demand 
import Name      hiding ( varName )
import Outputable
import FastString
import UniqSupply
import BasicTypes
import Util
import Pair
import Constants
import DynFlags
import Data.Char        ( ord )
import Data.List
import Data.Ord
import Data.Word
infixl 4 `mkCoreApp`, `mkCoreApps`
\end{code}
%************************************************************************
%*                                                                      *
\subsection{Basic CoreSyn construction}
%*                                                                      *
%************************************************************************
\begin{code}
sortQuantVars :: [Var] -> [Var]
sortQuantVars = sortBy (comparing withCategory)
  where
    withCategory v = (category v, v)
    category :: Var -> Int
    category v
     | isKindVar v = 1
     | isTyVar   v = 2
     | otherwise   = 3
mkCoreLet :: CoreBind -> CoreExpr -> CoreExpr
mkCoreLet (NonRec bndr rhs) body        
  | needsCaseBinding (idType bndr) rhs
  = Case rhs bndr (exprType body) [(DEFAULT,[],body)]
mkCoreLet bind body
  = Let bind body
mkCoreLets :: [CoreBind] -> CoreExpr -> CoreExpr
mkCoreLets binds body = foldr mkCoreLet body binds
mkCoreApp :: CoreExpr -> CoreExpr -> CoreExpr
mkCoreApp fun (Type ty) = App fun (Type ty)
mkCoreApp fun (Coercion co) = App fun (Coercion co)
mkCoreApp fun arg       = ASSERT2( isFunTy fun_ty, ppr fun $$ ppr arg )
                          mk_val_app fun arg arg_ty res_ty
                      where
                        fun_ty = exprType fun
                        (arg_ty, res_ty) = splitFunTy fun_ty
mkCoreApps :: CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps orig_fun orig_args
  = go orig_fun (exprType orig_fun) orig_args
  where
    go fun _      []               = fun
    go fun fun_ty (Type ty : args) = go (App fun (Type ty)) (applyTy fun_ty ty) args
    go fun fun_ty (Coercion co : args) = go (App fun (Coercion co)) (applyCo fun_ty co) args
    go fun fun_ty (arg     : args) = ASSERT2( isFunTy fun_ty, ppr fun_ty $$ ppr orig_fun $$ ppr orig_args )
                                     go (mk_val_app fun arg arg_ty res_ty) res_ty args
                                   where
                                     (arg_ty, res_ty) = splitFunTy fun_ty
mkCoreConApps :: DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps con args = mkCoreApps (Var (dataConWorkId con)) args
mk_val_app :: CoreExpr -> CoreExpr -> Type -> Type -> CoreExpr
mk_val_app fun arg arg_ty _        
  | not (needsCaseBinding arg_ty arg)
  = App fun arg                
mk_val_app fun arg arg_ty res_ty
  = Case arg arg_id res_ty [(DEFAULT,[],App fun (Var arg_id))]
  where
    arg_id = mkWildValBinder arg_ty    
	
        
	
	
	
	
	
	
mkWildEvBinder :: PredType -> EvVar
mkWildEvBinder pred = mkWildValBinder pred
mkWildValBinder :: Type -> Id
mkWildValBinder ty = mkLocalId wildCardName ty
mkWildCase :: CoreExpr -> Type -> Type -> [CoreAlt] -> CoreExpr
mkWildCase scrut scrut_ty res_ty alts 
  = Case scrut (mkWildValBinder scrut_ty) res_ty alts
mkIfThenElse :: CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr
mkIfThenElse guard then_expr else_expr
  = mkWildCase guard boolTy (exprType then_expr) 
	 [ (DataAlt falseDataCon, [], else_expr),	
    	   (DataAlt trueDataCon,  [], then_expr) ]
castBottomExpr :: CoreExpr -> Type -> CoreExpr
castBottomExpr e res_ty
  | e_ty `eqType` res_ty = e
  | otherwise            = Case e (mkWildValBinder e_ty) res_ty []
  where
    e_ty = exprType e
\end{code}
The functions from this point don't really do anything cleverer than
their counterparts in CoreSyn, but they are here for consistency
\begin{code}
mkCoreLams :: [CoreBndr] -> CoreExpr -> CoreExpr
mkCoreLams = mkLams
\end{code}
%************************************************************************
%*                                                                      *
\subsection{Making literals}
%*                                                                      *
%************************************************************************
\begin{code}
mkIntExpr :: DynFlags -> Integer -> CoreExpr        
mkIntExpr dflags i = mkConApp intDataCon  [mkIntLit dflags i]
mkIntExprInt :: DynFlags -> Int -> CoreExpr         
mkIntExprInt dflags i = mkConApp intDataCon  [mkIntLitInt dflags i]
mkWordExpr :: DynFlags -> Integer -> CoreExpr
mkWordExpr dflags w = mkConApp wordDataCon [mkWordLit dflags w]
mkWordExprWord :: DynFlags -> Word -> CoreExpr
mkWordExprWord dflags w = mkConApp wordDataCon [mkWordLitWord dflags w]
mkIntegerExpr  :: MonadThings m => Integer -> m CoreExpr  
mkIntegerExpr i = do t <- lookupTyCon integerTyConName
                     return (Lit (mkLitInteger i (mkTyConTy t)))
mkFloatExpr :: Float -> CoreExpr
mkFloatExpr f = mkConApp floatDataCon [mkFloatLitFloat f]
mkDoubleExpr :: Double -> CoreExpr
mkDoubleExpr d = mkConApp doubleDataCon [mkDoubleLitDouble d]
mkCharExpr     :: Char             -> CoreExpr      
mkCharExpr c = mkConApp charDataCon [mkCharLit c]
mkStringExpr   :: MonadThings m => String     -> m CoreExpr  
mkStringExprFS :: MonadThings m => FastString -> m CoreExpr  
mkStringExpr str = mkStringExprFS (mkFastString str)
mkStringExprFS str
  | nullFS str
  = return (mkNilExpr charTy)
  | lengthFS str == 1
  = do let the_char = mkCharExpr (headFS str)
       return (mkConsExpr charTy the_char (mkNilExpr charTy))
  | all safeChar chars
  = do unpack_id <- lookupId unpackCStringName
       return (App (Var unpack_id) (Lit (MachStr (fastStringToByteString str))))
  | otherwise
  = do unpack_id <- lookupId unpackCStringUtf8Name
       return (App (Var unpack_id) (Lit (MachStr (fastStringToByteString str))))
  where
    chars = unpackFS str
    safeChar c = ord c >= 1 && ord c <= 0x7F
\end{code}
\begin{code}
mkEqBox :: Coercion -> CoreExpr
mkEqBox co = ASSERT2( typeKind ty2 `eqKind` k, ppr co $$ ppr ty1 $$ ppr ty2 $$ ppr (typeKind ty1) $$ ppr (typeKind ty2) )
             Var (dataConWorkId eqBoxDataCon) `mkTyApps` [k, ty1, ty2] `App` Coercion co
  where Pair ty1 ty2 = coercionKind co
        k = typeKind ty1
\end{code}
%************************************************************************
%*                                                                      *
\subsection{Tuple constructors}
%*                                                                      *
%************************************************************************
\begin{code}
mkChunkified :: ([a] -> a)      
             -> [a]             
             -> a               
mkChunkified small_tuple as = mk_big_tuple (chunkify as)
  where
	
    mk_big_tuple [as] = small_tuple as
    mk_big_tuple as_s = mk_big_tuple (chunkify (map small_tuple as_s))
chunkify :: [a] -> [[a]]
chunkify xs
  | n_xs <= mAX_TUPLE_SIZE = [xs] 
  | otherwise		   = split xs
  where
    n_xs     = length xs
    split [] = []
    split xs = take mAX_TUPLE_SIZE xs : split (drop mAX_TUPLE_SIZE xs)
    
\end{code}
Creating tuples and their types for Core expressions 
@mkBigCoreVarTup@ builds a tuple; the inverse to @mkTupleSelector@.  
* If it has only one element, it is the identity function.
* If there are more elements than a big tuple can have, it nests 
  the tuples.  
\begin{code}
mkCoreVarTup :: [Id] -> CoreExpr
mkCoreVarTup ids = mkCoreTup (map Var ids)
mkCoreVarTupTy :: [Id] -> Type
mkCoreVarTupTy ids = mkBoxedTupleTy (map idType ids)
mkCoreTup :: [CoreExpr] -> CoreExpr
mkCoreTup []  = Var unitDataConId
mkCoreTup [c] = c
mkCoreTup cs  = mkConApp (tupleCon BoxedTuple (length cs))
                         (map (Type . exprType) cs ++ cs)
mkBigCoreVarTup :: [Id] -> CoreExpr
mkBigCoreVarTup ids = mkBigCoreTup (map Var ids)
mkBigCoreVarTupTy :: [Id] -> Type
mkBigCoreVarTupTy ids = mkBigCoreTupTy (map idType ids)
mkBigCoreTup :: [CoreExpr] -> CoreExpr
mkBigCoreTup = mkChunkified mkCoreTup
mkBigCoreTupTy :: [Type] -> Type
mkBigCoreTupTy = mkChunkified mkBoxedTupleTy
\end{code}
%************************************************************************
%*                                                                      *
                Floats
%*                                                                      *
%************************************************************************
\begin{code}
data FloatBind 
  = FloatLet  CoreBind
  | FloatCase CoreExpr Id AltCon [Var]       
      
      
wrapFloat :: FloatBind -> CoreExpr -> CoreExpr
wrapFloat (FloatLet defns)       body = Let defns body
wrapFloat (FloatCase e b con bs) body = Case e b (exprType body) [(con, bs, body)]
\end{code}
%************************************************************************
%*                                                                      *
\subsection{Tuple destructors}
%*                                                                      *
%************************************************************************
\begin{code}
mkTupleSelector :: [Id]         
                -> Id           
                -> Id           
                -> CoreExpr     
                -> CoreExpr     
mkTupleSelector vars the_var scrut_var scrut
  = mk_tup_sel (chunkify vars) the_var
  where
    mk_tup_sel [vars] the_var = mkSmallTupleSelector vars the_var scrut_var scrut
    mk_tup_sel vars_s the_var = mkSmallTupleSelector group the_var tpl_v $
                                mk_tup_sel (chunkify tpl_vs) tpl_v
        where
          tpl_tys = [mkBoxedTupleTy (map idType gp) | gp <- vars_s]
          tpl_vs  = mkTemplateLocals tpl_tys
          [(tpl_v, group)] = [(tpl,gp) | (tpl,gp) <- zipEqual "mkTupleSelector" tpl_vs vars_s,
                                         the_var `elem` gp ]
\end{code}
\begin{code}
mkSmallTupleSelector :: [Id]        
          -> Id         
          -> Id         
          -> CoreExpr        
          -> CoreExpr
mkSmallTupleSelector [var] should_be_the_same_var _ scrut
  = ASSERT(var == should_be_the_same_var)
    scrut
mkSmallTupleSelector vars the_var scrut_var scrut
  = ASSERT( notNull vars )
    Case scrut scrut_var (idType the_var)
         [(DataAlt (tupleCon BoxedTuple (length vars)), vars, Var the_var)]
\end{code}
\begin{code}
mkTupleCase :: UniqSupply       
            -> [Id]             
            -> CoreExpr         
            -> Id               
            -> CoreExpr         
            -> CoreExpr
mkTupleCase uniqs vars body scrut_var scrut
  = mk_tuple_case uniqs (chunkify vars) body
  where
    
    mk_tuple_case _ [vars] body
      = mkSmallTupleCase vars body scrut_var scrut
      
    
    mk_tuple_case us vars_s body
      = let (us', vars', body') = foldr one_tuple_case (us, [], body) vars_s
            in mk_tuple_case us' (chunkify vars') body'
    
    one_tuple_case chunk_vars (us, vs, body)
      = let (uniq, us') = takeUniqFromSupply us
            scrut_var = mkSysLocal (fsLit "ds") uniq
              (mkBoxedTupleTy (map idType chunk_vars))
            body' = mkSmallTupleCase chunk_vars body scrut_var (Var scrut_var)
        in (us', scrut_var:vs, body')
\end{code}
\begin{code}
mkSmallTupleCase
        :: [Id]         
        -> CoreExpr     
        -> Id           
        -> CoreExpr     
        -> CoreExpr
mkSmallTupleCase [var] body _scrut_var scrut
  = bindNonRec var scrut body
mkSmallTupleCase vars body scrut_var scrut
  = Case scrut scrut_var (exprType body) [(DataAlt (tupleCon BoxedTuple (length vars)), vars, body)]
\end{code}
%************************************************************************
%*                                                                      *
\subsection{Common list manipulation expressions}
%*                                                                      *
%************************************************************************
Call the constructor Ids when building explicit lists, so that they
interact well with rules.
\begin{code}
mkNilExpr :: Type -> CoreExpr
mkNilExpr ty = mkConApp nilDataCon [Type ty]
mkConsExpr :: Type -> CoreExpr -> CoreExpr -> CoreExpr
mkConsExpr ty hd tl = mkConApp consDataCon [Type ty, hd, tl]
mkListExpr :: Type -> [CoreExpr] -> CoreExpr
mkListExpr ty xs = foldr (mkConsExpr ty) (mkNilExpr ty) xs
mkFoldrExpr :: MonadThings m
            => Type             
            -> Type             
            -> CoreExpr         
            -> CoreExpr         
            -> CoreExpr         
            -> m CoreExpr
mkFoldrExpr elt_ty result_ty c n list = do
    foldr_id <- lookupId foldrName
    return (Var foldr_id `App` Type elt_ty 
           `App` Type result_ty
           `App` c
           `App` n
           `App` list)
mkBuildExpr :: (MonadThings m, MonadUnique m)
            => Type                                     
            -> ((Id, Type) -> (Id, Type) -> m CoreExpr) 
                                                        
                                                        
            -> m CoreExpr
mkBuildExpr elt_ty mk_build_inside = do
    [n_tyvar] <- newTyVars [alphaTyVar]
    let n_ty = mkTyVarTy n_tyvar
        c_ty = mkFunTys [elt_ty, n_ty] n_ty
    [c, n] <- sequence [mkSysLocalM (fsLit "c") c_ty, mkSysLocalM (fsLit "n") n_ty]
    
    build_inside <- mk_build_inside (c, c_ty) (n, n_ty)
    
    build_id <- lookupId buildName
    return $ Var build_id `App` Type elt_ty `App` mkLams [n_tyvar, c, n] build_inside
  where
    newTyVars tyvar_tmpls = do
      uniqs <- getUniquesM
      return (zipWith setTyVarUnique tyvar_tmpls uniqs)
\end{code}
%************************************************************************
%*                                                                      *
                      Error expressions
%*                                                                      *
%************************************************************************
\begin{code}
mkRuntimeErrorApp 
        :: Id           
                        
        -> Type         
        -> String       
        -> CoreExpr
mkRuntimeErrorApp err_id res_ty err_msg 
  = mkApps (Var err_id) [Type res_ty, err_string]
  where
    err_string = Lit (mkMachString err_msg)
mkImpossibleExpr :: Type -> CoreExpr
mkImpossibleExpr res_ty
  = mkRuntimeErrorApp rUNTIME_ERROR_ID res_ty "Impossible case alternative"
\end{code}
%************************************************************************
%*                                                                      *
                     Error Ids
%*                                                                      *
%************************************************************************
GHC randomly injects these into the code.
@patError@ is just a version of @error@ for pattern-matching
failures.  It knows various ``codes'' which expand to longer
strings---this saves space!
@absentErr@ is a thing we put in for ``absent'' arguments.  They jolly
well shouldn't be yanked on, but if one is, then you will get a
friendly message from @absentErr@ (rather than a totally random
crash).
@parError@ is a special version of @error@ which the compiler does
not know to be a bottoming Id.  It is used in the @_par_@ and @_seq_@
templates, but we don't ever expect to generate code for it.
\begin{code}
errorIds :: [Id]
errorIds 
  = [ eRROR_ID,   
                  
                  
                  
                  
      uNDEFINED_ID,   
                      
      rUNTIME_ERROR_ID,
      iRREFUT_PAT_ERROR_ID,
      nON_EXHAUSTIVE_GUARDS_ERROR_ID,
      nO_METHOD_BINDING_ERROR_ID,
      pAT_ERROR_ID,
      rEC_CON_ERROR_ID,
      rEC_SEL_ERROR_ID,
      aBSENT_ERROR_ID ]
recSelErrorName, runtimeErrorName, absentErrorName :: Name
irrefutPatErrorName, recConErrorName, patErrorName :: Name
nonExhaustiveGuardsErrorName, noMethodBindingErrorName :: Name
recSelErrorName     = err_nm "recSelError"     recSelErrorIdKey     rEC_SEL_ERROR_ID
absentErrorName     = err_nm "absentError"     absentErrorIdKey     aBSENT_ERROR_ID
runtimeErrorName    = err_nm "runtimeError"    runtimeErrorIdKey    rUNTIME_ERROR_ID
irrefutPatErrorName = err_nm "irrefutPatError" irrefutPatErrorIdKey iRREFUT_PAT_ERROR_ID
recConErrorName     = err_nm "recConError"     recConErrorIdKey     rEC_CON_ERROR_ID
patErrorName        = err_nm "patError"        patErrorIdKey        pAT_ERROR_ID
noMethodBindingErrorName     = err_nm "noMethodBindingError"
                                  noMethodBindingErrorIdKey nO_METHOD_BINDING_ERROR_ID
nonExhaustiveGuardsErrorName = err_nm "nonExhaustiveGuardsError" 
                                  nonExhaustiveGuardsErrorIdKey nON_EXHAUSTIVE_GUARDS_ERROR_ID
err_nm :: String -> Unique -> Id -> Name
err_nm str uniq id = mkWiredInIdName cONTROL_EXCEPTION_BASE (fsLit str) uniq id
rEC_SEL_ERROR_ID, rUNTIME_ERROR_ID, iRREFUT_PAT_ERROR_ID, rEC_CON_ERROR_ID :: Id
pAT_ERROR_ID, nO_METHOD_BINDING_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID :: Id
aBSENT_ERROR_ID :: Id
rEC_SEL_ERROR_ID                = mkRuntimeErrorId recSelErrorName
rUNTIME_ERROR_ID                = mkRuntimeErrorId runtimeErrorName
iRREFUT_PAT_ERROR_ID            = mkRuntimeErrorId irrefutPatErrorName
rEC_CON_ERROR_ID                = mkRuntimeErrorId recConErrorName
pAT_ERROR_ID                    = mkRuntimeErrorId patErrorName
nO_METHOD_BINDING_ERROR_ID      = mkRuntimeErrorId noMethodBindingErrorName
nON_EXHAUSTIVE_GUARDS_ERROR_ID  = mkRuntimeErrorId nonExhaustiveGuardsErrorName
aBSENT_ERROR_ID                 = mkRuntimeErrorId absentErrorName
mkRuntimeErrorId :: Name -> Id
mkRuntimeErrorId name = pc_bottoming_Id1 name runtimeErrorTy
runtimeErrorTy :: Type
runtimeErrorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy)
\end{code}
\begin{code}
errorName :: Name
errorName = mkWiredInIdName gHC_ERR (fsLit "error") errorIdKey eRROR_ID
eRROR_ID :: Id
eRROR_ID = pc_bottoming_Id1 errorName errorTy
errorTy  :: Type   
errorTy  = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] openAlphaTy)
undefinedName :: Name
undefinedName = mkWiredInIdName gHC_ERR (fsLit "undefined") undefinedKey uNDEFINED_ID
uNDEFINED_ID :: Id
uNDEFINED_ID = pc_bottoming_Id0 undefinedName undefinedTy
undefinedTy  :: Type   
undefinedTy  = mkSigmaTy [openAlphaTyVar] [] openAlphaTy
\end{code}
Note [Error and friends have an "open-tyvar" forall]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'error' and 'undefined' have types 
        error     :: forall (a::OpenKind). String -> a
        undefined :: forall (a::OpenKind). a
Notice the 'OpenKind' (manifested as openAlphaTyVar in the code). This ensures that
"error" can be instantiated at 
  * unboxed as well as boxed types
  * polymorphic types
This is OK because it never returns, so the return type is irrelevant.
See Note [OpenTypeKind accepts foralls] in TcUnify.
%************************************************************************
%*                                                                      *
\subsection{Utilities}
%*                                                                      *
%************************************************************************
\begin{code}
pc_bottoming_Id1 :: Name -> Type -> Id
pc_bottoming_Id1 name ty
 = mkVanillaGlobalWithInfo name ty bottoming_info
 where
    bottoming_info = vanillaIdInfo `setStrictnessInfo`    strict_sig
				   `setArityInfo`         1
			
        
        
        
        
        
        
        
        
    strict_sig = mkStrictSig (mkTopDmdType [evalDmd] botRes)
    
pc_bottoming_Id0 :: Name -> Type -> Id
pc_bottoming_Id0 name ty
 = mkVanillaGlobalWithInfo name ty bottoming_info
 where
    bottoming_info = vanillaIdInfo `setStrictnessInfo` strict_sig
    strict_sig = mkStrictSig (mkTopDmdType [] botRes)
\end{code}