% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-
-HsExpr: Abstract Haskell syntax: expressions
-
\begin{code}
+
+-- | Abstract Haskell syntax for expressions.
module HsExpr where
#include "HsVersions.h"
%************************************************************************
\begin{code}
+-- * Expressions proper
+
type LHsExpr id = Located (HsExpr id)
-------------------------
--- PostTcExpr is an evidence expression attached to the
--- syntax tree by the type checker (c.f. postTcType)
--- We use a PostTcTable where there are a bunch of pieces of
--- evidence, more than is convenient to keep individually
+-- | PostTcExpr is an evidence expression attached to the syntax tree by the
+-- type checker (c.f. postTcType).
type PostTcExpr = HsExpr Id
+-- | We use a PostTcTable where there are a bunch of pieces of evidence, more
+-- than is convenient to keep individually.
type PostTcTable = [(Name, Id)]
noPostTcExpr :: PostTcExpr
noPostTcTable = []
-------------------------
--- SyntaxExpr is like PostTcExpr, but it's filled in a little earlier,
+-- | SyntaxExpr is like 'PostTcExpr', but it's filled in a little earlier,
-- by the renamer. It's used for rebindable syntax.
--- E.g. (>>=) is filled in before the renamer by the appropriate Name
--- for (>>=), and then instantiated by the type checker with its
--- type args tec
+--
+-- E.g. @(>>=)@ is filled in before the renamer by the appropriate 'Name' for
+-- @(>>=)@, and then instantiated by the type checker with its type args
+-- tec
type SyntaxExpr id = HsExpr id
type SyntaxTable id = [(Name, SyntaxExpr id)]
--- *** Currently used only for CmdTop (sigh) ***
--- * Before the renamer, this list is noSyntaxTable
+-- ^ Currently used only for 'CmdTop' (sigh)
--
--- * After the renamer, it takes the form [(std_name, HsVar actual_name)]
+-- * Before the renamer, this list is 'noSyntaxTable'
+--
+-- * After the renamer, it takes the form @[(std_name, HsVar actual_name)]@
-- For example, for the 'return' op of a monad
--- normal case: (GHC.Base.return, HsVar GHC.Base.return)
--- with rebindable syntax: (GHC.Base.return, return_22)
--- where return_22 is whatever "return" is in scope
--
--- * After the type checker, it takes the form [(std_name, <expression>)]
--- where <expression> is the evidence for the method
+-- * normal case: @(GHC.Base.return, HsVar GHC.Base.return)@
+--
+-- * with rebindable syntax: @(GHC.Base.return, return_22)@
+-- where @return_22@ is whatever @return@ is in scope
+--
+-- * After the type checker, it takes the form @[(std_name, <expression>)]@
+-- where @<expression>@ is the evidence for the method
noSyntaxTable :: SyntaxTable id
noSyntaxTable = []
-------------------------
+-- | A Haskell expression.
data HsExpr id
- = HsVar id -- variable
- | HsIPVar (IPName id) -- implicit parameter
- | HsOverLit (HsOverLit id) -- Overloaded literals
+ = HsVar id -- ^ variable
+ | HsIPVar (IPName id) -- ^ implicit parameter
+ | HsOverLit (HsOverLit id) -- ^ Overloaded literals
- | HsLit HsLit -- Simple (non-overloaded) literals
+ | HsLit HsLit -- ^ Simple (non-overloaded) literals
| HsLam (MatchGroup id) -- Currently always a single match
-- Record update
| RecordUpd (LHsExpr id)
(HsRecordBinds id)
+-- (HsMatchGroup Id) -- Filled in by the type checker to be
+-- -- a match that does the job
[DataCon] -- Filled in by the type checker to the
-- _non-empty_ list of DataCons that have
-- all the upd'd fields
where idType :: HsExpr id -> HsMatchContext id; idType = undefined
ppr_expr exprType@(HsCase expr matches)
- = sep [ sep [ptext (sLit "case"), nest 4 (ppr expr), ptext (sLit "of")],
- nest 2 (pprMatches (CaseAlt `asTypeOf` idType exprType) matches) ]
+ = sep [ sep [ptext (sLit "case"), nest 4 (ppr expr), ptext (sLit "of {")],
+ nest 2 (pprMatches (CaseAlt `asTypeOf` idType exprType) matches <+> char '}') ]
where idType :: HsExpr id -> HsMatchContext id; idType = undefined
ppr_expr (HsIf e1 e2 e3)
-- Nothing after typechecking
(GRHSs id)
+isEmptyMatchGroup :: MatchGroup id -> Bool
+isEmptyMatchGroup (MatchGroup ms _) = null ms
+
matchGroupArity :: MatchGroup id -> Arity
matchGroupArity (MatchGroup [] _)
- = panic "matchGroupArity" -- MatchGroup is never empty
+ = panic "matchGroupArity" -- Precondition: MatchGroup is non-empty
matchGroupArity (MatchGroup (match:matches) _)
= ASSERT( all ((== n_pats) . length . hsLMatchPats) matches )
-- Assertion just checks that all the matches have the same number of pats
hsLMatchPats :: LMatch id -> [LPat id]
hsLMatchPats (L _ (Match pats _ _)) = pats
--- GRHSs are used both for pattern bindings and for Matches
+-- | GRHSs are used both for pattern bindings and for Matches
data GRHSs id
- = GRHSs [LGRHS id] -- Guarded RHSs
- (HsLocalBinds id) -- The where clause
+ = GRHSs {
+ grhssGRHSs :: [LGRHS id], -- ^ Guarded RHSs
+ grhssLocalBinds :: (HsLocalBinds id) -- ^ The where clause
+ }
type LGRHS id = Located (GRHS id)
+-- | Guarded Right Hand Side.
data GRHS id = GRHS [LStmt id] -- Guards
(LHsExpr id) -- Right hand side
\end{code}
\begin{code}
data HsMatchContext id -- Context of a Match
= FunRhs id Bool -- Function binding for f; True <=> written infix
- | CaseAlt -- Guard on a case alternative
- | LambdaExpr -- Pattern of a lambda
- | ProcExpr -- Pattern of a proc
- | PatBindRhs -- Pattern binding
+ | CaseAlt -- Patterns and guards on a case alternative
+ | LambdaExpr -- Patterns of a lambda
+ | ProcExpr -- Patterns of a proc
+ | PatBindRhs -- Patterns in the *guards* of a pattern binding
| RecUpd -- Record update [used only in DsExpr to
-- tell matchWrapper what sort of
-- runtime error message to generate]
-}
-- Used to generate the string for a *runtime* error message
-matchContextErrString :: Outputable id => HsMatchContext id -> String
-matchContextErrString (FunRhs fun _) = "function " ++ showSDoc (ppr fun)
-matchContextErrString CaseAlt = "case"
-matchContextErrString PatBindRhs = "pattern binding"
-matchContextErrString RecUpd = "record update"
-matchContextErrString LambdaExpr = "lambda"
-matchContextErrString ProcExpr = "proc"
+matchContextErrString :: Outputable id => HsMatchContext id -> SDoc
+matchContextErrString (FunRhs fun _) = ptext (sLit "function") <+> ppr fun
+matchContextErrString CaseAlt = ptext (sLit "case")
+matchContextErrString PatBindRhs = ptext (sLit "pattern binding")
+matchContextErrString RecUpd = ptext (sLit "record update")
+matchContextErrString LambdaExpr = ptext (sLit "lambda")
+matchContextErrString ProcExpr = ptext (sLit "proc")
matchContextErrString (StmtCtxt (ParStmtCtxt c)) = matchContextErrString (StmtCtxt c)
matchContextErrString (StmtCtxt (TransformStmtCtxt c)) = matchContextErrString (StmtCtxt c)
-matchContextErrString (StmtCtxt (PatGuard _)) = "pattern guard"
-matchContextErrString (StmtCtxt DoExpr) = "'do' expression"
-matchContextErrString (StmtCtxt (MDoExpr _)) = "'mdo' expression"
-matchContextErrString (StmtCtxt ListComp) = "list comprehension"
-matchContextErrString (StmtCtxt PArrComp) = "array comprehension"
+matchContextErrString (StmtCtxt (PatGuard _)) = ptext (sLit "pattern guard")
+matchContextErrString (StmtCtxt DoExpr) = ptext (sLit "'do' expression")
+matchContextErrString (StmtCtxt (MDoExpr _)) = ptext (sLit "'mdo' expression")
+matchContextErrString (StmtCtxt ListComp) = ptext (sLit "list comprehension")
+matchContextErrString (StmtCtxt PArrComp) = ptext (sLit "array comprehension")
\end{code}
\begin{code}