X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=c%CE%BBash%2FCLasH%2FUtils%2FCore%2FCoreTools.hs;h=a66904e1141334c5d5b66083a24967aed152eea3;hb=4a1b18cd81cebb66c95cc0ca8a6aaa441bee1418;hp=b4808026fe37958e0d34d81baf70a229a83a5517;hpb=4ae6d0942205c704ef4c15a8ffd9398fd9f7ca53;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git "a/c\316\273ash/CLasH/Utils/Core/CoreTools.hs" "b/c\316\273ash/CLasH/Utils/Core/CoreTools.hs" index b480802..a66904e 100644 --- "a/c\316\273ash/CLasH/Utils/Core/CoreTools.hs" +++ "b/c\316\273ash/CLasH/Utils/Core/CoreTools.hs" @@ -1,3 +1,4 @@ +{-# LANGUAGE PatternGuards, TypeSynonymInstances #-} -- | This module provides a number of functions to find out things about Core -- programs. This module does not provide the actual plumbing to work with -- Core and Haskell (it uses HsTools for this), but only the functions that @@ -19,6 +20,9 @@ import qualified HscTypes import qualified RdrName import qualified Name import qualified OccName +import qualified Type +import qualified Id +import qualified TyCon import qualified TysWiredIn import qualified Bag import qualified DynFlags @@ -183,6 +187,10 @@ has_free_tyvars = not . VarSet.isEmptyVarSet . (CoreFVs.exprSomeFreeVars Var.isT has_free_vars :: CoreSyn.CoreExpr -> Bool has_free_vars = not . VarSet.isEmptyVarSet . CoreFVs.exprFreeVars +-- Does the given expression use any of the given binders? +expr_uses_binders :: [CoreSyn.CoreBndr] -> CoreSyn.CoreExpr -> Bool +expr_uses_binders bndrs = not . VarSet.isEmptyVarSet . (CoreFVs.exprSomeFreeVars (`elem` bndrs)) + -- Turns a Var CoreExpr into the Id inside it. Will of course only work for -- simple Var CoreExprs, not complexer ones. exprToVar :: CoreSyn.CoreExpr -> Var.Id @@ -222,3 +230,41 @@ reduceCoreListToHsList app@(CoreSyn.App _ _) = out otherwise -> [] reduceCoreListToHsList _ = [] + +-- | Is the given type a State type? +isStateType :: Type.Type -> Bool +-- Resolve any type synonyms remaining +isStateType ty | Just ty' <- Type.tcView ty = isStateType ty' +isStateType ty = Maybe.isJust $ do + -- Split the type. Don't use normal splitAppTy, since that looks through + -- newtypes, and we want to see the State newtype. + (typef, _) <- Type.repSplitAppTy_maybe ty + -- See if the applied type is a type constructor + (tycon, _) <- Type.splitTyConApp_maybe typef + if TyCon.isNewTyCon tycon && Name.getOccString tycon == "State" + then + Just () + else + Nothing + +-- | Does the given TypedThing have a State type? +hasStateType :: (TypedThing t) => t -> Bool +hasStateType expr = case getType expr of + Nothing -> False + Just ty -> isStateType ty + + +-- | A class of things that (optionally) have a core Type. The type is +-- optional, since Type expressions don't have a type themselves. +class TypedThing t where + getType :: t -> Maybe Type.Type + +instance TypedThing CoreSyn.CoreExpr where + getType (CoreSyn.Type _) = Nothing + getType expr = Just $ CoreUtils.exprType expr + +instance TypedThing CoreSyn.CoreBndr where + getType = return . Id.idType + +instance TypedThing Type.Type where + getType = return . id