ddc-core-simpl-0.4.3.1: DDC/Core/Transform/FoldCase.hs
module DDC.Core.Transform.FoldCase
( Config (..)
, configZero
, foldCase
, foldCaseX )
where
import DDC.Core.Exp.Annot
import DDC.Core.Transform.TransformDownX
import Control.Monad.State.Strict
import qualified Data.Map.Strict as M
import qualified DDC.Type.Env as Env
data Config
= Config
{ -- | Perform the case-of-constructor transformation.
configCaseOfConstructor :: Bool
-- | Perform the case-of-case transformation.
-- Not implemented yet.
, configCaseOfCase :: Bool }
configZero :: Config
configZero
= Config
{ configCaseOfConstructor = False
, configCaseOfCase = False }
---------------------------------------------------------------------------------------------------
type FoldCase a n = State (M.Map n (DaCon n (Type n), [Exp a n]))
foldCase :: (Ord n, TransformDownMX (FoldCase a n) c)
=> Config
-> c a n
-> c a n
foldCase config xx
= {-# SCC foldCase #-}
evalState (transformDownMX (\_ _ -> foldCaseX config) Env.empty Env.empty xx) M.empty
foldCaseX :: Ord n
=> Config
-> Exp a n
-> FoldCase a n (Exp a n)
-- Collect ----------------------------------------------------------------------------------------
foldCaseX _
x@(XLet _ (LLet (BName b _) ex) _)
| Just (dc, args) <- takeXConApps ex
= do
modify (M.insert b (dc, args))
return x
-- Case of Constructor ----------------------------------------------------------------------------
-- @
-- let x = Con y z in
-- case x of
-- Con a b -> x1
--
-- ==> let x = Con y z in
-- let a = y in
-- let b = z in
-- x1
-- @
--
foldCaseX config
x@(XCase _ (XVar _ (UName n)) [alt])
| configCaseOfConstructor config
, AAlt (PData dc binds) rest <- alt
= do
seen <- gets (M.lookup n)
return $ case seen of
Just (dc', args') | dc == dc'
-> foldr (\(x', bnd) next -> XLet (annotOfExp x') (LLet bnd x') next)
rest (zip (filter (not . isXType) args') binds)
_ -> x
-- Default case.
foldCaseX _ x = return x