freesect-0.0.5: HSE/Build.hs
-----------------------------------------------------------------------------
-- |
-- Module : Language.Haskell.Exts.Build
-- Copyright : (c) The GHC Team, 1997-2000,
-- (c) Niklas Broberg 2004
-- License : BSD-style (see the file LICENSE.txt)
--
-- Maintainer : Niklas Broberg, d00nibro@chalmers.se
-- Stability : experimental
-- Portability : portable
--
-- This module contains combinators to use when building
-- Haskell source trees programmatically, as opposed to
-- parsing them from a string. The contents here are quite
-- experimental and will likely receive a lot of attention
-- when the rest has stabilised.
--
-----------------------------------------------------------------------------
module HSE.Build (
-- * Syntax building functions
name, -- :: String -> Name
sym, -- :: String -> Name
var, -- :: Name -> Exp
op, -- :: Name -> QOp
qvar, -- :: Module -> Name -> Exp
pvar, -- :: Name -> Pat
app, -- :: Exp -> Exp -> Exp
infixApp, -- :: Exp -> QOp -> Exp -> Exp
appFun, -- :: Exp -> [Exp] -> Exp
pApp, -- :: Name -> [Pat] -> Pat
tuple, -- :: [Exp] -> Exp
pTuple, -- :: [Pat] -> Pat
varTuple, -- :: [Name] -> Exp
pvarTuple, -- :: [Name] -> Pat
function, -- :: String -> Exp
strE, -- :: String -> Exp
charE, -- :: Char -> Exp
intE, -- :: Integer -> Exp
strP, -- :: String -> Pat
charP, -- :: Char -> Pat
intP, -- :: Integer -> Pat
doE, -- :: [Stmt] -> Exp
lamE, -- :: SrcLoc -> [Pat] -> Exp -> Exp
letE, -- :: [Decl] -> Exp -> Exp
caseE, -- :: Exp -> [Alt] -> Exp
alt, -- :: SrcLoc -> Pat -> Exp -> Alt
altGW, -- :: SrcLoc -> Pat -> [Stmt] -> Exp -> Binds -> Alt
listE, -- :: [Exp] -> Exp
eList, -- :: Exp
peList, -- :: Pat
fscontext, -- :: Exp -> Exp
paren, -- :: Exp -> Exp
pParen, -- :: Pat -> Pat
qualStmt, -- :: Exp -> Stmt
genStmt, -- :: SrcLoc -> Pat -> Exp -> Stmt
letStmt, -- :: [Decl] -> Stmt
binds, -- :: [Decl] -> Binds
noBinds, -- :: Binds
freeSectSlot, -- :: Exp
wildcard, -- :: Pat
genNames, -- :: String -> Int -> [Name]
-- * More advanced building
sfun, -- :: SrcLoc -> Name -> [Name] -> Rhs -> Binds -> Decl
simpleFun, -- :: SrcLoc -> Name -> Name -> Exp -> Decl
patBind, -- :: SrcLoc -> Pat -> Exp -> Decl
patBindWhere, -- :: SrcLoc -> Pat -> Exp -> [Decl] -> Decl
nameBind, -- :: SrcLoc -> Name -> Exp -> Decl
metaFunction, -- :: String -> [Exp] -> Exp
metaConPat -- :: String -> [Pat] -> Pat
) where
import HSE.Syntax
-----------------------------------------------------------------------------
-- Help functions for Abstract syntax
-- | An identifier with the given string as its name.
-- The string should be a valid Haskell identifier.
name :: String -> Name
name = Ident
-- | A symbol identifier. The string should be a valid
-- Haskell symbol identifier.
sym :: String -> Name
sym = Symbol
-- | A local variable as expression.
var :: Name -> Exp
var = Var . UnQual
-- | Use the given identifier as an operator.
op :: Name -> QOp
op = QVarOp . UnQual
-- | A qualified variable as expression.
qvar :: ModuleName -> Name -> Exp
qvar m n = Var $ Qual m n
-- | A pattern variable.
pvar :: Name -> Pat
pvar = PVar
-- | Application of expressions by juxtaposition.
app :: Exp -> Exp -> Exp
app = App
-- | Apply an operator infix.
infixApp :: Exp -> QOp -> Exp -> Exp
infixApp = InfixApp
-- | Apply a function to a list of arguments.
appFun :: Exp -> [Exp] -> Exp
appFun f [] = f
appFun f (a:as) = appFun (app f a) as
-- | A constructor pattern, with argument patterns.
pApp :: Name -> [Pat] -> Pat
pApp n ps = PApp (UnQual n) ps
-- | A tuple expression.
tuple :: [Exp] -> Exp
tuple = Tuple
-- | A tuple pattern.
pTuple :: [Pat] -> Pat
pTuple = PTuple
-- | A tuple expression consisting of variables only.
varTuple :: [Name] -> Exp
varTuple ns = tuple $ map var ns
-- | A tuple pattern consisting of variables only.
pvarTuple :: [Name] -> Pat
pvarTuple ns = pTuple $ map pvar ns
-- | A function with a given name.
function :: String -> Exp
function = var . Ident
-- | A literal string expression.
strE :: String -> Exp
strE = Lit . String
-- | A literal character expression.
charE :: Char -> Exp
charE = Lit . Char
-- | A literal integer expression.
intE :: Integer -> Exp
intE = Lit . Int
-- | A literal string pattern.
strP :: String -> Pat
strP = PLit . String
-- | A literal character pattern.
charP :: Char -> Pat
charP = PLit . Char
-- | A literal integer pattern.
intP :: Integer -> Pat
intP = PLit . Int
-- | A do block formed by the given statements.
-- The last statement in the list should be
-- a 'Qualifier' expression.
doE :: [Stmt] -> Exp
doE = Do
-- | Lambda abstraction, given a list of argument
-- patterns and an expression body.
lamE :: SrcLoc -> [Pat] -> Exp -> Exp
lamE = Lambda
-- | A @let@ ... @in@ block.
letE :: [Decl] -> Exp -> Exp
letE ds e = Let (binds ds) e
-- | A @case@ expression.
caseE :: Exp -> [Alt] -> Exp
caseE = Case
-- | An unguarded alternative in a @case@ expression.
alt :: SrcLoc -> Pat -> Exp -> Alt
alt s p e = Alt s p (unGAlt e) noBinds
-- | An alternative with a single guard in a @case@ expression.
altGW :: SrcLoc -> Pat -> [Stmt] -> Exp -> Binds -> Alt
altGW s p gs e w = Alt s p (gAlt s gs e) w
-- | An unguarded righthand side of a @case@ alternative.
unGAlt :: Exp -> GuardedAlts
unGAlt = UnGuardedAlt
-- | An list of guarded righthand sides for a @case@ alternative.
gAlts :: SrcLoc -> [([Stmt],Exp)] -> GuardedAlts
gAlts s as = GuardedAlts $ map (\(gs,e) -> GuardedAlt s gs e) as
-- | A single guarded righthand side for a @case@ alternative.
gAlt :: SrcLoc -> [Stmt] -> Exp -> GuardedAlts
gAlt s gs e = gAlts s [(gs,e)]
-- | A list expression.
listE :: [Exp] -> Exp
listE = List
-- | The empty list expression.
eList :: Exp
eList = List []
-- | The empty list pattern.
peList :: Pat
peList = PList []
-- | Put FreeSect context around an expression.
fscontext :: Exp -> Exp
fscontext = FSContext
-- | Put parentheses around an expression.
paren :: Exp -> Exp
paren = Paren
-- | Put parentheses around a pattern.
pParen :: Pat -> Pat
pParen = PParen
-- | A qualifier expression statement.
qualStmt :: Exp -> Stmt
qualStmt = Qualifier
-- | A generator statement: /pat/ @<-@ /exp/
genStmt :: SrcLoc -> Pat -> Exp -> Stmt
genStmt = Generator
-- | A @let@ binding group as a statement.
letStmt :: [Decl] -> Stmt
letStmt ds = LetStmt $ binds ds
-- | Hoist a set of declarations to a binding group.
binds :: [Decl] -> Binds
binds = BDecls
-- | An empty binding group.
noBinds :: Binds
noBinds = binds []
-- | FreeSect placeholder: @__@
freeSectSlot :: Exp
freeSectSlot = FreeSectSlot
-- | The wildcard pattern: @_@
wildcard :: Pat
wildcard = PWildCard
-- | Generate k names by appending numbers 1 through k to a given string.
genNames :: String -> Int -> [Name]
genNames s k = [ Ident $ s ++ show i | i <- [1..k] ]
-------------------------------------------------------------------------------
-- Some more specialised help functions
-- | A function with a single clause
sfun :: SrcLoc -> Name -> [Name] -> Rhs -> Binds -> Decl
sfun s f pvs rhs bs = FunBind [Match s f (map pvar pvs) Nothing rhs bs]
-- | A function with a single clause, a single argument, no guards
-- and no where declarations
simpleFun :: SrcLoc -> Name -> Name -> Exp -> Decl
simpleFun s f a e = let rhs = UnGuardedRhs e
in sfun s f [a] rhs noBinds
-- | A pattern bind where the pattern is a variable, and where
-- there are no guards and no 'where' clause.
patBind :: SrcLoc -> Pat -> Exp -> Decl
patBind s p e = let rhs = UnGuardedRhs e
in PatBind s p Nothing rhs noBinds
-- | A pattern bind where the pattern is a variable, and where
-- there are no guards, but with a 'where' clause.
patBindWhere :: SrcLoc -> Pat -> Exp -> [Decl] -> Decl
patBindWhere s p e ds = let rhs = UnGuardedRhs e
in PatBind s p Nothing rhs (binds ds)
-- | Bind an identifier to an expression.
nameBind :: SrcLoc -> Name -> Exp -> Decl
nameBind s n e = patBind s (pvar n) e
-- | Apply function of a given name to a list of arguments.
metaFunction :: String -> [Exp] -> Exp
metaFunction s es = mf s (reverse es)
where mf s [] = var $ name s
mf s (e:es) = app (mf s es) e
-- | Apply a constructor of a given name to a list of pattern
-- arguments, forming a constructor pattern.
metaConPat :: String -> [Pat] -> Pat
metaConPat s ps = pApp (name s) ps