X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FhsSyn%2FHsBinds.lhs;h=458a713daddf017087e03307fb2c49101a3f1b11;hb=1796a476986f14cca2f7628d2f7cf6d530853495;hp=0c167d6e5a9f6874522a579e607925a168b9a1ae;hpb=0e61daaa0c9871cabc76f49515699d8b3e6111e3;p=ghc-hetmet.git diff --git a/ghc/compiler/hsSyn/HsBinds.lhs b/ghc/compiler/hsSyn/HsBinds.lhs index 0c167d6..458a713 100644 --- a/ghc/compiler/hsSyn/HsBinds.lhs +++ b/ghc/compiler/hsSyn/HsBinds.lhs @@ -1,142 +1,115 @@ % -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 +% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % \section[HsBinds]{Abstract syntax: top-level bindings and signatures} -Datatype for: @HsBinds@, @Bind@, @Sig@, @MonoBinds@. +Datatype for: @BindGroup@, @Bind@, @Sig@, @Bind@. \begin{code} -#include "HsVersions.h" - module HsBinds where -IMP_Ubiq() +#include "HsVersions.h" + +import {-# SOURCE #-} HsExpr ( HsExpr, pprExpr, LHsExpr, + LMatch, pprFunBind, + GRHSs, pprPatBind ) -- friends: -#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201 -IMPORT_DELOOPER(HsLoop) ( pprMatches, pprGRHSsAndBinds, - Match, GRHSsAndBinds, - pprExpr, HsExpr ) -#else -import {-# SOURCE #-} HsMatches ( pprMatches, Match, pprGRHSsAndBinds, GRHSsAndBinds ) -import {-# SOURCE #-} HsExpr ( pprExpr, HsExpr ) -#endif - -import HsPragmas ( GenPragmas, ClassOpPragmas ) -import HsTypes ( HsType ) -import CoreSyn ( SYN_IE(CoreExpr) ) +import HsPat ( LPat ) +import HsTypes ( LHsType ) --others: -import Id ( SYN_IE(DictVar), SYN_IE(Id), GenId ) -import Name ( OccName, NamedThing(..) ) -import Outputable ( interpp'SP, ifnotPprForUser, pprQuote, - Outputable(..){-instance * (,)-} - ) -import PprCore --( GenCoreExpr {- instance Outputable -} ) -import PprType ( GenTyVar {- instance Outputable -} ) -import Pretty -import Bag -import SrcLoc ( SrcLoc{-instances-} ) -import TyVar ( GenTyVar{-instances-} ) -import Unique ( Unique {- instance Eq -} ) +import Name ( Name ) +import NameSet ( NameSet, elemNameSet, nameSetToList ) +import BasicTypes ( IPName, RecFlag(..), Activation(..), Fixity ) +import Outputable +import SrcLoc ( Located(..), unLoc ) +import Var ( TyVar ) +import Bag ( Bag, bagToList ) \end{code} %************************************************************************ %* * -\subsection{Bindings: @HsBinds@} +\subsection{Bindings: @BindGroup@} %* * %************************************************************************ -The following syntax may produce new syntax which is not part of the input, -and which is instead a translation of the input to the typechecker. -Syntax translations are marked TRANSLATION in comments. New empty -productions are useful in development but may not appear in the final -grammar. - -Collections of bindings, created by dependency analysis and translation: - -\begin{code} -data HsBinds tyvar uvar id pat -- binders and bindees - = EmptyBinds - - | ThenBinds (HsBinds tyvar uvar id pat) - (HsBinds tyvar uvar id pat) - - | MonoBind (MonoBinds tyvar uvar id pat) - [Sig id] -- Empty on typechecker output - RecFlag - -type RecFlag = Bool -recursive = True -nonRecursive = False -\end{code} - -\begin{code} -nullBinds :: HsBinds tyvar uvar id pat -> Bool - -nullBinds EmptyBinds = True -nullBinds (ThenBinds b1 b2) = nullBinds b1 && nullBinds b2 -nullBinds (MonoBind b _ _) = nullMonoBinds b -\end{code} +Global bindings (where clauses) \begin{code} -instance (Outputable pat, NamedThing id, Outputable id, - Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar) => - Outputable (HsBinds tyvar uvar id pat) where - - ppr sty binds = pprQuote sty (\ sty -> ppr_binds sty binds) - -ppr_binds sty EmptyBinds = empty -ppr_binds sty (ThenBinds binds1 binds2) - = ($$) (ppr_binds sty binds1) (ppr_binds sty binds2) -ppr_binds sty (MonoBind bind sigs is_rec) - = vcat [ - ifnotPprForUser sty (ptext rec_str), - if null sigs - then empty - else vcat (map (ppr sty) sigs), - ppr sty bind +data HsBindGroup id + = HsBindGroup -- A mutually recursive group + (LHsBinds id) + [LSig id] -- Empty on typechecker output, Type Signatures + RecFlag + + | HsIPBinds + [LIPBind id] -- Not allowed at top level + +instance OutputableBndr id => Outputable (HsBindGroup id) where + ppr (HsBindGroup binds sigs is_rec) + = vcat [ppr_isrec, + vcat (map ppr sigs), + pprLHsBinds binds ] where - rec_str | is_rec = SLIT("{- rec -}") - | otherwise = SLIT("{- nonrec -}") -\end{code} - -%************************************************************************ -%* * -\subsection{Bindings: @MonoBinds@} -%* * -%************************************************************************ - -Global bindings (where clauses) - -\begin{code} -data MonoBinds tyvar uvar id pat - = EmptyMonoBinds - - | AndMonoBinds (MonoBinds tyvar uvar id pat) - (MonoBinds tyvar uvar id pat) - - | PatMonoBind pat - (GRHSsAndBinds tyvar uvar id pat) - SrcLoc - - | FunMonoBind id - Bool -- True => infix declaration - [Match tyvar uvar id pat] -- must have at least one Match - SrcLoc - - | VarMonoBind id -- TRANSLATION - (HsExpr tyvar uvar id pat) - - | CoreMonoBind id -- TRANSLATION - CoreExpr -- No zonking; this is a final CoreExpr with Ids and Types! - - | AbsBinds -- Binds abstraction; TRANSLATION - [tyvar] -- Type variables - [id] -- Dicts - [([tyvar], id, id)] -- (type variables, polymorphic, momonmorphic) triples - (MonoBinds tyvar uvar id pat) -- The "business end" + ppr_isrec = getPprStyle $ \ sty -> + if userStyle sty then empty else + case is_rec of + Recursive -> ptext SLIT("{- rec -}") + NonRecursive -> ptext SLIT("{- nonrec -}") + + ppr (HsIPBinds ipbinds) + = vcat (map ppr ipbinds) + +-- ----------------------------------------------------------------------------- +-- Implicit parameter bindings + +type LIPBind id = Located (IPBind id) + +-- | Implicit parameter bindings. +data IPBind id + = IPBind + (IPName id) + (LHsExpr id) + +instance (OutputableBndr id) => Outputable (IPBind id) where + ppr (IPBind id rhs) = pprBndr LetBind id <+> equals <+> pprExpr (unLoc rhs) + +-- ----------------------------------------------------------------------------- + +type LHsBinds id = Bag (LHsBind id) +type LHsBind id = Located (HsBind id) + +pprLHsBinds :: OutputableBndr id => LHsBinds id -> SDoc +pprLHsBinds binds = lbrace <+> vcat (map ppr (bagToList binds)) <+> rbrace + +data HsBind id + = FunBind (Located id) + -- Used for both functions f x = e + -- and variables f = \x -> e + -- Reason: the Match stuff lets us have an optional + -- result type sig f :: a->a = ...mentions a... + -- + -- This also means that instance decls can only have + -- FunBinds, so if you change this, you'll need to + -- change e.g. rnMethodBinds + Bool -- True => infix declaration + [LMatch id] + + | PatBind (LPat id) -- The pattern is never a simple variable; + -- That case is done by FunBind + (GRHSs id) + + | VarBind id (Located (HsExpr id)) -- Dictionary binding and suchlike; + -- located only for consistency + + | AbsBinds -- Binds abstraction; TRANSLATION + [TyVar] -- Type variables + [id] -- Dicts + [([TyVar], id, id)] -- (type variables, polymorphic, momonmorphic) triples + NameSet -- Set of *polymorphic* variables that have an INLINE pragma + (LHsBinds id) -- The "business end" -- Creates bindings for *new* (polymorphic, overloaded) locals -- in terms of *old* (monomorphic, non-overloaded) ones. @@ -167,50 +140,31 @@ So the desugarer tries to do a better job: (fm,gm) -> fm ..ditto for gp.. - p = /\ [a,b] -> \ [d1,d2] -> letrec DBINDS and BIND - in (fm,gm) + tp = /\ [a,b] -> \ [d1,d2] -> letrec DBINDS and BIND + in (fm,gm) \begin{code} -nullMonoBinds :: MonoBinds tyvar uvar id pat -> Bool - -nullMonoBinds EmptyMonoBinds = True -nullMonoBinds (AndMonoBinds bs1 bs2) = nullMonoBinds bs1 && nullMonoBinds bs2 -nullMonoBinds other_monobind = False +instance OutputableBndr id => Outputable (HsBind id) where + ppr mbind = ppr_monobind mbind -andMonoBinds :: [MonoBinds tyvar uvar id pat] -> MonoBinds tyvar uvar id pat -andMonoBinds binds = foldr AndMonoBinds EmptyMonoBinds binds -\end{code} +ppr_monobind :: OutputableBndr id => HsBind id -> SDoc -\begin{code} -instance (NamedThing id, Outputable id, Outputable pat, - Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar) => - Outputable (MonoBinds tyvar uvar id pat) where - ppr sty mbind = pprQuote sty (\ sty -> ppr_monobind sty mbind) - - -ppr_monobind sty EmptyMonoBinds = empty -ppr_monobind sty (AndMonoBinds binds1 binds2) - = ($$) (ppr_monobind sty binds1) (ppr_monobind sty binds2) - -ppr_monobind sty (PatMonoBind pat grhss_n_binds locn) - = hang (ppr sty pat) 4 (pprGRHSsAndBinds sty False grhss_n_binds) - -ppr_monobind sty (FunMonoBind fun inf matches locn) - = pprMatches sty (False, ppr sty fun) matches +ppr_monobind (PatBind pat grhss) = pprPatBind pat grhss +ppr_monobind (VarBind var rhs) = ppr var <+> equals <+> pprExpr (unLoc rhs) +ppr_monobind (FunBind fun inf matches) = pprFunBind (unLoc fun) matches -- ToDo: print infix if appropriate -ppr_monobind sty (VarMonoBind name expr) - = hang (hsep [ppr sty name, equals]) 4 (pprExpr sty expr) - -ppr_monobind sty (CoreMonoBind name expr) - = hang (hsep [ppr sty name, equals]) 4 (ppr sty expr) - -ppr_monobind sty (AbsBinds tyvars dictvars exports val_binds) - = ($$) (sep [ptext SLIT("AbsBinds"), - brackets (interpp'SP sty tyvars), - brackets (interpp'SP sty dictvars), - brackets (interpp'SP sty exports)]) - (nest 4 (ppr sty val_binds)) +ppr_monobind (AbsBinds tyvars dictvars exports inlines val_binds) + = sep [ptext SLIT("AbsBinds"), + brackets (interpp'SP tyvars), + brackets (interpp'SP dictvars), + brackets (sep (punctuate comma (map ppr exports))), + brackets (interpp'SP (nameSetToList inlines))] + $$ + nest 4 ( vcat [pprBndr LetBind x | (_,x,_) <- exports] + -- Print type signatures + $$ + pprLHsBinds val_binds ) \end{code} %************************************************************************ @@ -225,63 +179,115 @@ signatures. Then all the machinery to move them into place, etc., serves for both. \begin{code} +type LSig name = Located (Sig name) + data Sig name - = Sig name -- a bog-std type signature - (HsType name) - SrcLoc - - | ClassOpSig name -- Selector name - name -- Default-method name - (HsType name) - SrcLoc - - | SpecSig name -- specialise a function or datatype ... - (HsType name) -- ... to these types - (Maybe name) -- ... maybe using this as the code for it - SrcLoc - - | InlineSig name -- INLINE f - SrcLoc - - | DeforestSig name -- Deforest using this function definition - SrcLoc - - | MagicUnfoldingSig - name -- Associate the "name"d function with - FAST_STRING -- the compiler-builtin unfolding (known - SrcLoc -- by the String name) + = Sig (Located name) -- a bog-std type signature + (LHsType name) + + | SpecSig (Located name) -- specialise a function or datatype ... + (LHsType name) -- ... to these types + + | InlineSig Bool -- True <=> INLINE f, False <=> NOINLINE f + (Located name) -- Function name + Activation -- When inlining is *active* + + | SpecInstSig (LHsType name) -- (Class tys); should be a specialisation of the + -- current instance decl + + | FixSig (FixitySig name) -- Fixity declaration + +type LFixitySig name = Located (FixitySig name) +data FixitySig name = FixitySig (Located name) Fixity \end{code} \begin{code} -instance (NamedThing name, Outputable name) => Outputable (Sig name) where - ppr sty sig = pprQuote sty (\ sty -> ppr_sig sty sig) +okBindSig :: NameSet -> LSig Name -> Bool +okBindSig ns sig = sigForThisGroup ns sig + +okClsDclSig :: LSig Name -> Bool +okClsDclSig (L _ (SpecInstSig _)) = False +okClsDclSig sig = True -- All others OK + +okInstDclSig :: NameSet -> LSig Name -> Bool +okInstDclSig ns lsig@(L _ sig) = ok ns sig + where + ok ns (Sig _ _) = False + ok ns (FixSig _) = False + ok ns (SpecInstSig _) = True + ok ns sig = sigForThisGroup ns lsig + +sigForThisGroup :: NameSet -> LSig Name -> Bool +sigForThisGroup ns sig + = case sigName sig of + Nothing -> False + Just n -> n `elemNameSet` ns + +sigName :: LSig name -> Maybe name +sigName (L _ sig) = f sig + where + f (Sig n _) = Just (unLoc n) + f (SpecSig n _) = Just (unLoc n) + f (InlineSig _ n _) = Just (unLoc n) + f (FixSig (FixitySig n _)) = Just (unLoc n) + f other = Nothing + +isFixitySig :: Sig name -> Bool +isFixitySig (FixSig _) = True +isFixitySig _ = False + +isPragSig :: Sig name -> Bool + -- Identifies pragmas +isPragSig (SpecSig _ _) = True +isPragSig (InlineSig _ _ _) = True +isPragSig (SpecInstSig _) = True +isPragSig other = False + +hsSigDoc (Sig _ _) = ptext SLIT("type signature") +hsSigDoc (SpecSig _ _) = ptext SLIT("SPECIALISE pragma") +hsSigDoc (InlineSig True _ _) = ptext SLIT("INLINE pragma") +hsSigDoc (InlineSig False _ _) = ptext SLIT("NOINLINE pragma") +hsSigDoc (SpecInstSig _) = ptext SLIT("SPECIALISE instance pragma") +hsSigDoc (FixSig (FixitySig _ _)) = ptext SLIT("fixity declaration") +\end{code} + +Signature equality is used when checking for duplicate signatures +\begin{code} +eqHsSig :: Sig Name -> Sig Name -> Bool +eqHsSig (FixSig (FixitySig n1 _)) (FixSig (FixitySig n2 _)) = unLoc n1 == unLoc n2 +eqHsSig (Sig n1 _) (Sig n2 _) = unLoc n1 == unLoc n2 +eqHsSig (InlineSig b1 n1 _) (InlineSig b2 n2 _) = b1 == b2 && unLoc n1 == unLoc n2 + -- For specialisations, we don't have equality over + -- HsType, so it's not convenient to spot duplicate + -- specialisations here. Check for this later, when we're in Type land +eqHsSig _other1 _other2 = False +\end{code} -ppr_sig sty (Sig var ty _) - = hang (hsep [ppr sty var, ptext SLIT("::")]) - 4 (ppr sty ty) +\begin{code} +instance (OutputableBndr name) => Outputable (Sig name) where + ppr sig = ppr_sig sig -ppr_sig sty (ClassOpSig var _ ty _) - = hang (hsep [ppr sty (getOccName var), ptext SLIT("::")]) - 4 (ppr sty ty) +ppr_sig :: OutputableBndr name => Sig name -> SDoc +ppr_sig (Sig var ty) + = sep [ppr var <+> dcolon, nest 4 (ppr ty)] -ppr_sig sty (DeforestSig var _) - = hang (hsep [text "{-# DEFOREST", ppr sty var]) - 4 (text "#-") +ppr_sig (SpecSig var ty) + = sep [ hsep [text "{-# SPECIALIZE", ppr var, dcolon], + nest 4 (ppr ty <+> text "#-}") + ] -ppr_sig sty (SpecSig var ty using _) - = hang (hsep [text "{-# SPECIALIZE", ppr sty var, ptext SLIT("::")]) - 4 (hsep [ppr sty ty, pp_using using, text "#-}"]) +ppr_sig (InlineSig True var phase) + = hsep [text "{-# INLINE", ppr phase, ppr var, text "#-}"] - where - pp_using Nothing = empty - pp_using (Just me) = hsep [char '=', ppr sty me] +ppr_sig (InlineSig False var phase) + = hsep [text "{-# NOINLINE", ppr phase, ppr var, text "#-}"] -ppr_sig sty (InlineSig var _) +ppr_sig (SpecInstSig ty) + = hsep [text "{-# SPECIALIZE instance", ppr ty, text "#-}"] - = hsep [text "{-# INLINE", ppr sty var, text "#-}"] +ppr_sig (FixSig fix_sig) = ppr fix_sig -ppr_sig sty (MagicUnfoldingSig var str _) - = hsep [text "{-# MAGIC_UNFOLDING", ppr sty var, ptext str, text "#-}"] +instance Outputable name => Outputable (FixitySig name) where + ppr (FixitySig name fixity) = sep [ppr fixity, ppr name] \end{code} -