--- /dev/null
+-- $Id$
+--
+-- Copyright (c) [2001..2002] Manuel M T Chakravarty & Gabriele Keller
+--
+-- Auxiliary routines for NDP-related Core transformations.
+--
+--- DESCRIPTION ---------------------------------------------------------------
+--
+-- This module exports all functions to access and alter the `Type' data
+-- structure from modules `Type' and `CoreExpr' from `CoreSyn'. As it is part
+-- of the NDP flattening component, the functions provide access to all the
+-- fields that are important for the flattening and lifting transformation.
+--
+--- DOCU ----------------------------------------------------------------------
+--
+-- Language: Haskell 98
+--
+--- TODO ----------------------------------------------------------------------
+--
+
+module NDPCoreUtils (
+
+ -- type inspection functions
+ --
+ tupleTyArgs, -- :: Type -> [Type]
+ funTyArgs, -- :: Type -> (Type, Type)
+ parrElemTy, -- :: Type -> Type
+
+ -- Core generation functions
+ --
+ mkTuple, -- :: [Type] -> [CoreExpr] -> CoreExpr
+ mkInt, -- :: CoreExpr -> CoreExpr
+
+ -- query functions
+ --
+ isDefault, -- :: CoreAlt -> Bool
+ isLit, -- :: [CoreAlt] -> Bool
+ isSimpleExpr, -- :: CoreExpr -> Bool
+
+ -- re-exported functions
+ --
+ mkPArrTy, -- :: Type -> Type
+ boolTy, -- :: Type
+
+ -- substitution
+ --
+ substIdEnv
+) where
+
+-- GHC
+import Panic (panic)
+import Outputable (Outputable(ppr), pprPanic)
+import BasicTypes (Boxity(..))
+import Type (Type, splitTyConApp_maybe, splitFunTy)
+import TyCon (isTupleTyCon)
+import TysWiredIn (parrTyCon, unitDataConId, tupleCon, intDataCon, mkPArrTy,
+ boolTy)
+import CoreSyn (CoreExpr, CoreAlt, Expr(..), AltCon(..),
+ Bind(..), mkConApp)
+import PprCore ( {- instances -} )
+import Var (Id)
+import VarEnv (IdEnv, delVarEnv, delVarEnvList, lookupVarEnv)
+
+-- friends: don't import any to avoid cyclic imports
+--
+
+
+-- type inspection functions
+-- -------------------------
+
+-- determines the argument types of a tuple type (EXPORTED)
+--
+tupleTyArgs :: Type -> [Type]
+tupleTyArgs ty =
+ case splitTyConApp_maybe ty of
+ Just (tyCon, argTys) | isTupleTyCon tyCon -> argTys
+ _ ->
+ pprPanic "NDPCoreUtils.tupleTyArgs: wrong type: " (ppr ty)
+
+-- determines the argument and result type of a function type (EXPORTED)
+--
+funTyArgs :: Type -> (Type, Type)
+funTyArgs = splitFunTy
+
+-- for a type of the form `[:t:]', yield `t' (EXPORTED)
+--
+-- * if the type has any other form, a fatal error occurs
+--
+parrElemTy :: Type -> Type
+parrElemTy ty =
+ case splitTyConApp_maybe ty of
+ Just (tyCon, [argTy]) | tyCon == parrTyCon -> argTy
+ _ ->
+ pprPanic "NDPCoreUtils.parrElemTy: wrong type: " (ppr ty)
+
+
+-- Core generation functions
+-- -------------------------
+
+-- make a tuple construction expression from a list of argument types and
+-- argument values (EXPORTED)
+--
+-- * the two lists need to be of the same length
+--
+mkTuple :: [Type] -> [CoreExpr] -> CoreExpr
+mkTuple [] [] = Var unitDataConId
+mkTuple [_] [e] = e
+mkTuple ts es | length ts == length es =
+ mkConApp (tupleCon Boxed (length es)) (map Type ts ++ es)
+mkTuple _ _ =
+ panic "NDPCoreUtils.mkTuple: mismatch between number of types and exprs!"
+
+-- make a boxed integer from an unboxed one (EXPORTED)
+--
+mkInt :: CoreExpr -> CoreExpr
+mkInt e = mkConApp intDataCon [e]
+
+
+-- query functions
+-- ---------------
+
+-- checks whether a given case alternative is a default alternative (EXPORTED)
+--
+isDefault :: CoreAlt -> Bool
+isDefault (DEFAULT, _, _) = True
+isDefault _ = False
+
+-- check whether a list of case alternatives in belongs to a case over a
+-- literal type (EXPORTED)
+--
+isLit :: [CoreAlt] -> Bool
+isLit ((DEFAULT, _, _ ):alts) = isLit alts
+isLit ((LitAlt _, _, _):_ ) = True
+isLit _ = False
+
+-- FIXME: this function should get a more expressive name and maybe also a
+-- more detailed return type (depends on how the analysis goes)
+isSimpleExpr:: CoreExpr -> Bool
+isSimpleExpr _ =
+ -- FIXME
+ False
+
+
+-- Substitution
+-- -------------
+
+substIdEnv:: IdEnv Id -> CoreExpr -> CoreExpr
+substIdEnv env e@(Lit _) = e
+substIdEnv env e@(Var id) =
+ case (lookupVarEnv env id) of
+ Just v -> (Var v)
+ _ -> e
+substIdEnv env (App e arg) =
+ App (substIdEnv env e) (substIdEnv env arg)
+substIdEnv env (Lam b expr) =
+ Lam b (substIdEnv (delVarEnv env b) expr)
+substIdEnv env (Let (NonRec b expr1) expr2) =
+ Let (NonRec b (substIdEnv env expr1))
+ (substIdEnv (delVarEnv env b) expr2)
+substIdEnv env (Let (Rec bnds) expr) =
+ let
+ newEnv = delVarEnvList env (map fst bnds)
+ newExpr = substIdEnv newEnv expr
+ substBnd (b,e) = (b, substIdEnv newEnv e)
+ in Let (Rec (map substBnd bnds)) newExpr
+substIdEnv env (Case expr b ty alts) =
+ Case (substIdEnv newEnv expr) b ty (map substAlt alts)
+ where
+ newEnv = delVarEnv env b
+ substAlt (c, bnds, expr) =
+ (c, bnds, substIdEnv (delVarEnvList env bnds) expr)
+substIdEnv env (Note n expr) =
+ Note n (substIdEnv env expr)
+substIdEnv env e@(Type t) = e