+getLiterals lit@(CoreSyn.Lit _) = [lit]
+
+reduceCoreListToHsList ::
+ [HscTypes.CoreModule] -- ^ The modules where parts of the list are hidden
+ -> CoreSyn.CoreExpr -- ^ The refence to atleast one of the nodes
+ -> TranslatorSession [CoreSyn.CoreExpr]
+reduceCoreListToHsList cores app@(CoreSyn.App _ _) = do {
+ ; let { (fun, args) = CoreSyn.collectArgs app
+ ; len = length args
+ } ;
+ ; case len of
+ 3 -> do {
+ ; let topelem = args!!1
+ ; case (args!!2) of
+ (varz@(CoreSyn.Var id)) -> do {
+ ; binds <- mapM (findExpr (isVarName id)) cores
+ ; otherelems <- reduceCoreListToHsList cores (head (Maybe.catMaybes binds))
+ ; return (topelem:otherelems)
+ }
+ (appz@(CoreSyn.App _ _)) -> do {
+ ; otherelems <- reduceCoreListToHsList cores appz
+ ; return (topelem:otherelems)
+ }
+ otherwise -> return [topelem]
+ }
+ otherwise -> return []
+ }
+ where
+ isVarName :: Monad m => Var.Var -> Var.Var -> m Bool
+ isVarName lookfor bind = return $ (Var.varName lookfor) == (Var.varName bind)
+
+reduceCoreListToHsList _ _ = return []
+
+-- Is the given var the State data constructor?
+isStateCon :: Var.Var -> Bool
+isStateCon var = do
+ -- See if it is a DataConWrapId (not DataConWorkId, since State is a
+ -- newtype).
+ case Id.idDetails var of
+ IdInfo.DataConWrapId dc ->
+ -- See if the datacon is the State datacon from the State type.
+ let tycon = DataCon.dataConTyCon dc
+ tyname = Name.getOccString tycon
+ dcname = Name.getOccString dc
+ in case (tyname, dcname) of
+ ("State", "State") -> True
+ _ -> False
+ _ -> False
+
+-- | 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
+
+
+-- | Flattens nested lets into a single list of bindings. The expression
+-- passed does not have to be a let expression, if it isn't an empty list of
+-- bindings is returned.
+flattenLets ::
+ CoreSyn.CoreExpr -- ^ The expression to flatten.
+ -> ([Binding], CoreSyn.CoreExpr) -- ^ The bindings and resulting expression.
+flattenLets (CoreSyn.Let binds expr) =
+ (bindings ++ bindings', expr')
+ where
+ -- Recursively flatten the contained expression
+ (bindings', expr') =flattenLets expr
+ -- Flatten our own bindings to remove the Rec / NonRec constructors
+ bindings = CoreSyn.flattenBinds [binds]
+flattenLets expr = ([], expr)
+
+-- | Create bunch of nested non-recursive let expressions from the given
+-- bindings. The first binding is bound at the highest level (and thus
+-- available in all other bindings).
+mkNonRecLets :: [Binding] -> CoreSyn.CoreExpr -> CoreSyn.CoreExpr
+mkNonRecLets bindings expr = MkCore.mkCoreLets binds expr