%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[HsExpr]{Abstract Haskell syntax: expressions}
-- friends:
import {-# SOURCE #-} HsMatches ( pprMatches, pprMatch, Match )
-import HsBinds ( HsBinds )
+import HsBinds ( HsBinds(..) )
import HsBasic ( HsLit )
import BasicTypes ( Fixity(..), FixityDirection(..) )
import HsTypes ( HsType )
-- others:
-import Name ( NamedThing )
-import Id ( Id )
+import Name ( Name, isLexId )
import Outputable
-import PprType ( pprGenType, pprParendGenType, GenType, GenTyVar )
+import PprType ( pprType, pprParendType )
+import Type ( Type )
+import Var ( TyVar, Id )
+import DataCon ( DataCon )
import SrcLoc ( SrcLoc )
\end{code}
%************************************************************************
\begin{code}
-data HsExpr flexi id pat
+data HsExpr id pat
= HsVar id -- variable
| HsLit HsLit -- literal
| HsLitOut HsLit -- TRANSLATION
- (GenType flexi) -- (with its type)
+ Type -- (with its type)
- | HsLam (Match flexi id pat) -- lambda
- | HsApp (HsExpr flexi id pat) -- application
- (HsExpr flexi id pat)
+ | HsLam (Match id pat) -- lambda
+ | HsApp (HsExpr id pat) -- application
+ (HsExpr id pat)
-- Operator applications:
-- NB Bracketed ops such as (+) come out as Vars.
-- NB We need an expr for the operator in an OpApp/Section since
-- the typechecker may need to apply the operator to a few types.
- | OpApp (HsExpr flexi id pat) -- left operand
- (HsExpr flexi id pat) -- operator
+ | OpApp (HsExpr id pat) -- left operand
+ (HsExpr id pat) -- operator
Fixity -- Renamer adds fixity; bottom until then
- (HsExpr flexi id pat) -- right operand
+ (HsExpr id pat) -- right operand
-- We preserve prefix negation and parenthesis for the precedence parser.
-- They are eventually removed by the type checker.
- | NegApp (HsExpr flexi id pat) -- negated expr
- (HsExpr flexi id pat) -- the negate id (in a HsVar)
+ | NegApp (HsExpr id pat) -- negated expr
+ (HsExpr id pat) -- the negate id (in a HsVar)
- | HsPar (HsExpr flexi id pat) -- parenthesised expr
+ | HsPar (HsExpr id pat) -- parenthesised expr
- | SectionL (HsExpr flexi id pat) -- operand
- (HsExpr flexi id pat) -- operator
- | SectionR (HsExpr flexi id pat) -- operator
- (HsExpr flexi id pat) -- operand
+ | SectionL (HsExpr id pat) -- operand
+ (HsExpr id pat) -- operator
+ | SectionR (HsExpr id pat) -- operator
+ (HsExpr id pat) -- operand
- | HsCase (HsExpr flexi id pat)
- [Match flexi id pat] -- must have at least one Match
+ | HsCase (HsExpr id pat)
+ [Match id pat]
SrcLoc
- | HsIf (HsExpr flexi id pat) -- predicate
- (HsExpr flexi id pat) -- then part
- (HsExpr flexi id pat) -- else part
+ | HsIf (HsExpr id pat) -- predicate
+ (HsExpr id pat) -- then part
+ (HsExpr id pat) -- else part
SrcLoc
- | HsLet (HsBinds flexi id pat) -- let(rec)
- (HsExpr flexi id pat)
+ | HsLet (HsBinds id pat) -- let(rec)
+ (HsExpr id pat)
- | HsDo DoOrListComp
- [Stmt flexi id pat] -- "do":one or more stmts
+ | HsDo StmtCtxt
+ [Stmt id pat] -- "do":one or more stmts
SrcLoc
- | HsDoOut DoOrListComp
- [Stmt flexi id pat] -- "do":one or more stmts
- id -- id for return
- id -- id for >>=
+ | HsDoOut StmtCtxt
+ [Stmt id pat] -- "do":one or more stmts
+ id -- id for return
+ id -- id for >>=
id -- id for zero
- (GenType flexi) -- Type of the whole expression
+ Type -- Type of the whole expression
SrcLoc
| ExplicitList -- syntactic list
- [HsExpr flexi id pat]
+ [HsExpr id pat]
| ExplicitListOut -- TRANSLATION
- (GenType flexi) -- Gives type of components of list
- [HsExpr flexi id pat]
+ Type -- Gives type of components of list
+ [HsExpr id pat]
| ExplicitTuple -- tuple
- [HsExpr flexi id pat]
+ [HsExpr id pat]
-- NB: Unit is ExplicitTuple []
-- for tuples, we can get the types
-- direct from the components
+ Bool -- boxed?
- | HsCon Id -- TRANSLATION; a saturated constructor application
- [GenType flexi]
- [HsExpr flexi id pat]
+ | HsCon DataCon -- TRANSLATION; a saturated constructor application
+ [Type]
+ [HsExpr id pat]
-- Record construction
| RecordCon id -- The constructor
- (HsExpr flexi id pat) -- Always (HsVar id) until type checker,
- -- but the latter adds its type args too
- (HsRecordBinds flexi id pat)
+ (HsRecordBinds id pat)
+
+ | RecordConOut DataCon
+ (HsExpr id pat) -- Data con Id applied to type args
+ (HsRecordBinds id pat)
+
-- Record update
- | RecordUpd (HsExpr flexi id pat)
- (HsRecordBinds flexi id pat)
+ | RecordUpd (HsExpr id pat)
+ (HsRecordBinds id pat)
- | RecordUpdOut (HsExpr flexi id pat) -- TRANSLATION
- (GenType flexi) -- Type of *result* record (may differ from
+ | RecordUpdOut (HsExpr id pat) -- TRANSLATION
+ Type -- Type of *result* record (may differ from
-- type of input record)
[id] -- Dicts needed for construction
- (HsRecordBinds flexi id pat)
+ (HsRecordBinds id pat)
- | ExprWithTySig -- signature binding
- (HsExpr flexi id pat)
+ | ExprWithTySig -- signature binding
+ (HsExpr id pat)
(HsType id)
- | ArithSeqIn -- arithmetic sequence
- (ArithSeqInfo flexi id pat)
+ | ArithSeqIn -- arithmetic sequence
+ (ArithSeqInfo id pat)
| ArithSeqOut
- (HsExpr flexi id pat) -- (typechecked, of course)
- (ArithSeqInfo flexi id pat)
+ (HsExpr id pat) -- (typechecked, of course)
+ (ArithSeqInfo id pat)
| CCall FAST_STRING -- call into the C world; string is
- [HsExpr flexi id pat] -- the C function; exprs are the
+ [HsExpr id pat] -- the C function; exprs are the
-- arguments to pass.
Bool -- True <=> might cause Haskell
-- garbage-collection (must generate
-- NOTE: this CCall is the *boxed*
-- version; the desugarer will convert
-- it into the unboxed "ccall#".
- (GenType flexi) -- The result type; will be *bottom*
+ Type -- The result type; will be *bottom*
-- until the typechecker gets ahold of it
| HsSCC FAST_STRING -- "set cost centre" (_scc_) annotation
- (HsExpr flexi id pat) -- expr whose cost is to be measured
+ (HsExpr id pat) -- expr whose cost is to be measured
+\end{code}
+
+These constructors only appear temporarily in the parser.
+
+\begin{code}
+ | EWildPat -- wildcard
+
+ | EAsPat id -- as pattern
+ (HsExpr id pat)
+
+ | ELazyPat (HsExpr id pat) -- ~ pattern
\end{code}
Everything from here on appears only in typechecker output.
\begin{code}
| TyLam -- TRANSLATION
- [GenTyVar flexi]
- (HsExpr flexi id pat)
+ [TyVar]
+ (HsExpr id pat)
| TyApp -- TRANSLATION
- (HsExpr flexi id pat) -- generated by Spec
- [GenType flexi]
+ (HsExpr id pat) -- generated by Spec
+ [Type]
-- DictLam and DictApp are "inverses"
| DictLam
[id]
- (HsExpr flexi id pat)
+ (HsExpr id pat)
| DictApp
- (HsExpr flexi id pat)
+ (HsExpr id pat)
[id]
-type HsRecordBinds flexi id pat
- = [(id, HsExpr flexi id pat, Bool)]
+type HsRecordBinds id pat
+ = [(id, HsExpr id pat, Bool)]
-- True <=> source code used "punning",
-- i.e. {op1, op2} rather than {op1=e1, op2=e2}
\end{code}
\end{verbatim}
\begin{code}
-instance (NamedThing id, Outputable id, Outputable pat) =>
- Outputable (HsExpr flexi id pat) where
+instance (Outputable id, Outputable pat) =>
+ Outputable (HsExpr id pat) where
ppr expr = pprExpr expr
\end{code}
\begin{code}
-pprExpr :: (NamedThing id, Outputable id, Outputable pat)
- => HsExpr flexi id pat -> SDoc
+pprExpr :: (Outputable id, Outputable pat)
+ => HsExpr id pat -> SDoc
pprExpr e = pprDeeper (ppr_expr e)
+pprBinds b = pprDeeper (ppr b)
ppr_expr (HsVar v) = ppr v
ppr_expr (HsLitOut lit _) = ppr lit
ppr_expr (HsLam match)
- = hsep [char '\\', nest 2 (pprMatch True match)]
+ = hsep [char '\\', nest 2 (pprMatch (True,empty) match)]
ppr_expr expr@(HsApp e1 e2)
= let (fun, args) = collect_args expr [] in
= hang (pprExpr op) 4 (sep [pp_e1, pp_e2])
pp_infixly v
- = sep [pp_e1, hsep [ppr v, pp_e2]]
+ = sep [pp_e1, hsep [pp_v_op, pp_e2]]
+ where
+ pp_v = ppr v
+ pp_v_op | isLexId (_PK_ (showSDoc pp_v)) = char '`' <> pp_v <> char '`'
+ | otherwise = pp_v
+ -- Put it in backquotes if it's not an operator already
+ -- We use (showSDoc pp_v), rather than isSymOcc (getOccName v) simply so
+ -- that we don't need NamedThing in the context of all these funcions.
+ -- Gruesome, but simple.
ppr_expr (NegApp e _)
- = (<>) (char '-') (pprParendExpr e)
+ = char '-' <+> pprParendExpr e
-ppr_expr (HsPar e)
- = parens (ppr_expr e)
+ppr_expr (HsPar e) = parens (ppr_expr e)
ppr_expr (SectionL expr op)
= case op of
-- special case: let ... in let ...
ppr_expr (HsLet binds expr@(HsLet _ _))
- = sep [hang (ptext SLIT("let")) 2 (hsep [ppr binds, ptext SLIT("in")]),
+ = sep [hang (ptext SLIT("let")) 2 (hsep [pprBinds binds, ptext SLIT("in")]),
pprExpr expr]
ppr_expr (HsLet binds expr)
- = sep [hang (ptext SLIT("let")) 2 (ppr binds),
+ = sep [hang (ptext SLIT("let")) 2 (pprBinds binds),
hang (ptext SLIT("in")) 2 (ppr expr)]
ppr_expr (HsDo do_or_list_comp stmts _) = pprDo do_or_list_comp stmts
= brackets (fsep (punctuate comma (map ppr_expr exprs)))
ppr_expr (ExplicitListOut ty exprs)
= hcat [ brackets (fsep (punctuate comma (map ppr_expr exprs))),
- ifNotPprForUser ((<>) space (parens (pprGenType ty))) ]
+ ifNotPprForUser ((<>) space (parens (pprType ty))) ]
-ppr_expr (ExplicitTuple exprs)
+ppr_expr (ExplicitTuple exprs True)
= parens (sep (punctuate comma (map ppr_expr exprs)))
+ppr_expr (ExplicitTuple exprs False)
+ = ptext SLIT("(#") <> sep (punctuate comma (map ppr_expr exprs)) <> ptext SLIT("#)")
+
ppr_expr (HsCon con_id tys args)
- = ppr con_id <+> sep (map pprParendGenType tys ++
+ = ppr con_id <+> sep (map pprParendType tys ++
map pprParendExpr args)
-ppr_expr (RecordCon con_id con rbinds)
+ppr_expr (RecordCon con_id rbinds)
+ = pp_rbinds (ppr con_id) rbinds
+ppr_expr (RecordConOut data_con con rbinds)
= pp_rbinds (ppr con) rbinds
ppr_expr (RecordUpd aexp rbinds)
= pp_rbinds (pprParendExpr aexp) rbinds
ppr_expr (ExprWithTySig expr sig)
- = hang (nest 2 (ppr_expr expr) <+> ptext SLIT("::"))
+ = hang (nest 2 (ppr_expr expr) <+> dcolon)
4 (ppr sig)
ppr_expr (ArithSeqIn info)
4 (ppr_expr expr)
ppr_expr (TyApp expr [ty])
- = hang (ppr_expr expr) 4 (pprParendGenType ty)
+ = hang (ppr_expr expr) 4 (pprParendType ty)
ppr_expr (TyApp expr tys)
= hang (ppr_expr expr)
Parenthesize unless very simple:
\begin{code}
-pprParendExpr :: (NamedThing id, Outputable id, Outputable pat)
- => HsExpr flexi id pat -> SDoc
+pprParendExpr :: (Outputable id, Outputable pat)
+ => HsExpr id pat -> SDoc
pprParendExpr expr
= let
HsVar _ -> pp_as_was
ExplicitList _ -> pp_as_was
ExplicitListOut _ _ -> pp_as_was
- ExplicitTuple _ -> pp_as_was
+ ExplicitTuple _ _ -> pp_as_was
HsPar _ -> pp_as_was
_ -> parens pp_as_was
%************************************************************************
\begin{code}
-pp_rbinds :: (NamedThing id, Outputable id, Outputable pat)
+pp_rbinds :: (Outputable id, Outputable pat)
=> SDoc
- -> HsRecordBinds flexi id pat -> SDoc
+ -> HsRecordBinds id pat -> SDoc
pp_rbinds thing rbinds
= hang thing
%************************************************************************
\begin{code}
-data DoOrListComp = DoStmt | ListComp | Guard
-
+data StmtCtxt -- Context of a Stmt
+ = DoStmt -- Do Statment
+ | ListComp -- List comprehension
+ | CaseAlt -- Guard on a case alternative
+ | PatBindRhs -- Guard on a pattern binding
+ | FunRhs Name -- Guard on a function defn for f
+ | LambdaBody -- Body of a lambda abstraction
+
pprDo DoStmt stmts
= hang (ptext SLIT("do")) 2 (vcat (map ppr stmts))
pprDo ListComp stmts
\end{code}
\begin{code}
-data Stmt flexi id pat
+data Stmt id pat
= BindStmt pat
- (HsExpr flexi id pat)
+ (HsExpr id pat)
SrcLoc
- | LetStmt (HsBinds flexi id pat)
+ | LetStmt (HsBinds id pat)
- | GuardStmt (HsExpr flexi id pat) -- List comps only
+ | GuardStmt (HsExpr id pat) -- List comps only
SrcLoc
- | ExprStmt (HsExpr flexi id pat) -- Do stmts only
+ | ExprStmt (HsExpr id pat) -- Do stmts; and guarded things at the end
SrcLoc
- | ReturnStmt (HsExpr flexi id pat) -- List comps only, at the end
+ | ReturnStmt (HsExpr id pat) -- List comps only, at the end
\end{code}
\begin{code}
-instance (NamedThing id, Outputable id, Outputable pat) =>
- Outputable (Stmt flexi id pat) where
+instance (Outputable id, Outputable pat) =>
+ Outputable (Stmt id pat) where
ppr stmt = pprStmt stmt
pprStmt (BindStmt pat expr _)
= hsep [ppr pat, ptext SLIT("<-"), ppr expr]
pprStmt (LetStmt binds)
- = hsep [ptext SLIT("let"), ppr binds]
+ = hsep [ptext SLIT("let"), pprBinds binds]
pprStmt (ExprStmt expr _)
= ppr expr
pprStmt (GuardStmt expr _)
%************************************************************************
\begin{code}
-data ArithSeqInfo flexi id pat
- = From (HsExpr flexi id pat)
- | FromThen (HsExpr flexi id pat)
- (HsExpr flexi id pat)
- | FromTo (HsExpr flexi id pat)
- (HsExpr flexi id pat)
- | FromThenTo (HsExpr flexi id pat)
- (HsExpr flexi id pat)
- (HsExpr flexi id pat)
+data ArithSeqInfo id pat
+ = From (HsExpr id pat)
+ | FromThen (HsExpr id pat)
+ (HsExpr id pat)
+ | FromTo (HsExpr id pat)
+ (HsExpr id pat)
+ | FromThenTo (HsExpr id pat)
+ (HsExpr id pat)
+ (HsExpr id pat)
\end{code}
\begin{code}
-instance (NamedThing id, Outputable id, Outputable pat) =>
- Outputable (ArithSeqInfo flexi id pat) where
+instance (Outputable id, Outputable pat) =>
+ Outputable (ArithSeqInfo id pat) where
ppr (From e1) = hcat [ppr e1, pp_dotdot]
ppr (FromThen e1 e2) = hcat [ppr e1, comma, space, ppr e2, pp_dotdot]
ppr (FromTo e1 e3) = hcat [ppr e1, pp_dotdot, ppr e3]