g2-0.1.0.0: src/G2/Language/Monad/AST.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module G2.Language.Monad.AST where
import G2.Language.AST
import G2.Language.Syntax
import qualified Data.Text as T
class AST t => ASTM t where
modifyChildrenM :: Monad m => (t -> m t) -> t -> m t
modifyM :: (ASTM t, Monad m) => (t -> m t) -> t -> m t
modifyM f t = go t
where
go t' = modifyChildrenM go =<< f t'
modifyFixM :: (ASTM t, Monad m, Eq t) => (t -> m t) -> t -> m t
modifyFixM f e = do
e' <- f e
if e == e'
then modifyChildrenM (modifyFixM f) e'
else modifyFixM f e'
class (ASTM t, ASTContainer c t) => ASTContainerM c t where
modifyContainedASTsM :: Monad m => (t -> m t) -> c -> m c
modifyASTsM :: (ASTContainerM c e, Monad m) => (e -> m e) -> c -> m c
modifyASTsM f = modifyContainedASTsM (modifyM f)
-- | Instance ASTContainerM of Itself
-- Every ASTM is defined as an ASTContainerM of itself. Generally, functions
-- should be written using the ASTContainerM typeclass.
instance ASTM t => ASTContainerM t t where
modifyContainedASTsM f t = f t
instance ASTM Expr where
modifyChildrenM f (App fx ax) = do
fx' <- f fx
ax' <- f ax
return $ App fx' ax'
modifyChildrenM f (Lam u b e) = return . Lam u b =<< f e
modifyChildrenM f (Let bind e) = do
bind' <- modifyContainedASTsM f bind
return . Let bind' =<< f e
modifyChildrenM f (Case m b as) = do
m' <- f m
return . Case m' b =<< modifyContainedASTsM f as
modifyChildrenM f (Cast e c) = do
e' <- f e
return $ Cast e' c
modifyChildrenM f (Tick t e) = return . Tick t =<< f e
modifyChildrenM f (NonDet es) = return . NonDet =<< mapM f es
modifyChildrenM f (Assume is e1 e2) = do
is' <- modifyContainedASTsM f is
e1' <- f e1
e2' <- f e2
return $ Assume is' e1' e2'
modifyChildrenM f (Assert is e1 e2) = do
is' <- modifyContainedASTsM f is
e1' <- f e1
e2' <- f e2
return $ Assert is' e1' e2'
modifyChildrenM _ e = return e
instance ASTM Type where
modifyChildrenM f (TyVar i) = return . TyVar =<< modifyContainedASTsM f i
modifyChildrenM f (TyFun tf ta) = do
tf' <- f tf
ta' <- f ta
return $ TyFun tf' ta'
modifyChildrenM f (TyApp tf ta) = do
tf' <- f tf
ta' <- f ta
return $ TyApp tf' ta'
modifyChildrenM f (TyCon b ts) =
return . TyCon b =<< f ts
modifyChildrenM f (TyForAll b t) = do
b' <- modifyContainedASTsM f b
return . TyForAll b' =<< modifyChildrenM f t
modifyChildrenM _ t = return t
instance ASTContainerM Expr Type where
modifyContainedASTsM f (Var i) = return . Var =<< modifyContainedASTsM f i
modifyContainedASTsM f (Prim p t) = return . Prim p =<< f t
modifyContainedASTsM f (Data dc) = return . Data =<< modifyContainedASTsM f dc
modifyContainedASTsM f (App fx ax) = do
fx' <- modifyContainedASTsM f fx
ax' <- modifyContainedASTsM f ax
return $ App fx' ax'
modifyContainedASTsM f (Lam u b e) = do
b' <- modifyContainedASTsM f b
e' <- modifyContainedASTsM f e
return $ Lam u b' e'
modifyContainedASTsM f (Let bnd e) = do
bnd' <- modifyContainedASTsM f bnd
e' <- modifyContainedASTsM f e
return $ Let bnd' e'
modifyContainedASTsM f (Case m i as) = do
m' <- modifyContainedASTsM f m
i' <- modifyContainedASTsM f i
as' <- modifyContainedASTsM f as
return $ Case m' i' as'
modifyContainedASTsM f (Type t) = return . Type =<< f t
modifyContainedASTsM f (Cast e c) = do
e' <- modifyContainedASTsM f e
c' <- modifyContainedASTsM f c
return $ Cast e' c'
modifyContainedASTsM f (Coercion c) = return . Coercion =<< modifyContainedASTsM f c
modifyContainedASTsM f (Tick t e) = return . Tick t =<< modifyContainedASTsM f e
modifyContainedASTsM f (NonDet es) = return . NonDet =<< modifyContainedASTsM f es
modifyContainedASTsM f (Assume is e1 e2) = do
is' <- modifyContainedASTsM f is
e1' <- modifyContainedASTsM f e1
e2' <- modifyContainedASTsM f e2
return $ Assume is' e1' e2'
modifyContainedASTsM f (Assert is e1 e2) = do
is' <- modifyContainedASTsM f is
e1' <- modifyContainedASTsM f e1
e2' <- modifyContainedASTsM f e2
return $ Assert is' e1' e2'
modifyContainedASTsM _ e = return e
instance ASTContainerM c e => ASTContainerM [c] e where
modifyContainedASTsM f = mapM (modifyContainedASTsM f)
instance ASTContainerM c e => ASTContainerM (Maybe c) e where
modifyContainedASTsM f = mapM (modifyContainedASTsM f)
instance (ASTContainerM c t, ASTContainerM d t) => ASTContainerM (c, d) t where
modifyContainedASTsM f (x, y) = do
x' <- modifyContainedASTsM f x
y' <- modifyContainedASTsM f y
return (x', y')
instance ASTContainerM Id Expr where
{-# INLINE modifyContainedASTsM #-}
modifyContainedASTsM _ i = return i
instance ASTContainerM Id Type where
modifyContainedASTsM f (Id n t) = return . Id n =<< f t
instance ASTContainerM TyBinder Type where
modifyContainedASTsM f (AnonTyBndr t) = return . AnonTyBndr =<< f t
modifyContainedASTsM f (NamedTyBndr i) =
return . NamedTyBndr =<< modifyContainedASTsM f i
instance ASTContainerM DataCon Expr where
{-# INLINE modifyContainedASTsM #-}
modifyContainedASTsM _ dc = return dc
instance ASTContainerM DataCon Type where
modifyContainedASTsM f (DataCon n t) = return . DataCon n =<< f t
instance ASTContainerM AltMatch Expr where
{-# INLINE modifyContainedASTsM #-}
modifyContainedASTsM _ am = return am
instance ASTContainerM Alt Expr where
modifyContainedASTsM f (Alt a e) = do
e' <- modifyContainedASTsM f e
return $ Alt a e'
instance ASTContainerM AltMatch Type where
modifyContainedASTsM f (DataAlt dc i) = do
dc' <- modifyContainedASTsM f dc
i' <- modifyContainedASTsM f i
return $ DataAlt dc' i'
modifyContainedASTsM _ am = return am
instance ASTContainerM Alt Type where
modifyContainedASTsM f (Alt a e) = do
a' <- modifyContainedASTsM f a
e' <- modifyContainedASTsM f e
return $ Alt a' e'
instance ASTContainerM Coercion Type where
modifyContainedASTsM f (t1 :~ t2) = do
t1' <- f t1
t2' <- f t2
return $ t1' :~ t2'
instance ASTContainerM FuncCall Expr where
modifyContainedASTsM f fc@(FuncCall { arguments = as, returns = r}) = do
as' <- modifyContainedASTsM f as
r' <- modifyContainedASTsM f r
return $ fc { arguments = as', returns = r' }
instance ASTContainerM FuncCall Type where
modifyContainedASTsM f fc@(FuncCall { arguments = as, returns = r}) = do
as' <- modifyContainedASTsM f as
r' <- modifyContainedASTsM f r
return $ fc { arguments = as', returns = r' }
instance ASTContainerM T.Text Expr where
modifyContainedASTsM _ = return
instance ASTContainerM T.Text Type where
modifyContainedASTsM _ = return