{-# LANGUAGE MultiParamTypeClasses, GADTs, FlexibleInstances #-}
module GhcShim.API (
-- * Traversing the AST
IsBinder(..)
, AstAlg(..)
, Fold(..)
, FoldPhase(..)
) where
import Type (Type)
import SrcLoc (SrcSpan, Located)
import Name (Name)
import Var (Var)
-- | Is this a binding occurrence of @f@?
data IsBinder =
DefSite -- ^ @f = ..@
| UseSite -- ^ @g = f ..@
| SigSite -- ^ @f :: ..@ or fixity declaration
-- | The "algebra" that we use while traversing the AST.
--
-- This is not a general purpose fold; we look for identifiers and types.
data AstAlg m id = AstAlg {
-- | Mark a branch point in the AST
astMark :: Maybe SrcSpan -> String -> m (Maybe Type) -> m (Maybe Type)
-- | Throw a runtime error
, astUnsupported :: Maybe SrcSpan -> String -> m (Maybe Type)
-- | Found a subexpression type
, astExpType :: SrcSpan -> Maybe Type -> m (Maybe Type)
-- | Found a 'Name' (i.e., pre type checking)
, astId :: IsBinder -> Located id -> m (Maybe Type)
-- | Are we running pre or post type checking?
, astPhase :: FoldPhase id
}
class Fold id a where
fold :: Monad m => AstAlg m id -> a -> m (Maybe Type)
data FoldPhase id where
FoldPreTc :: FoldPhase Name
FoldPostTc :: FoldPhase Var
instance Fold id a => Fold id [a] where
fold alg xs = do
mapM_ (fold alg) xs
return Nothing
instance Fold id a => Fold id (Maybe a) where
fold _alg Nothing = return Nothing
fold alg (Just x) = fold alg x