X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FhsSyn%2FHsBinds.lhs;h=c0f01a86108040e9cb4ad85e200d54a17474e8b3;hp=8f9279e923e04b3b2895a5588bea6f2f3def5d22;hb=a8427a4125e9b78e88a487eeabf018f1c6e8bc08;hpb=5653634ead7a7f31f1a584483e53b23e78b047c2 diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs index 8f9279e..c0f01a8 100644 --- a/compiler/hsSyn/HsBinds.lhs +++ b/compiler/hsSyn/HsBinds.lhs @@ -1,4 +1,5 @@ % +% (c) The University of Glasgow 2006 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % \section[HsBinds]{Abstract syntax: top-level bindings and signatures} @@ -15,18 +16,18 @@ import {-# SOURCE #-} HsExpr ( HsExpr, pprExpr, LHsExpr, GRHSs, pprPatBind ) import {-# SOURCE #-} HsPat ( LPat ) -import HsTypes ( LHsType, PostTcType ) -import PprCore ( {- instances -} ) -import Coercion ( Coercion ) -import Type ( Type, pprParendType ) -import Name ( Name ) -import NameSet ( NameSet, elemNameSet ) -import BasicTypes ( IPName, RecFlag(..), InlineSpec(..), Fixity ) +import HsTypes +import PprCore () +import Coercion +import Type +import Name +import NameSet +import BasicTypes import Outputable -import SrcLoc ( Located(..), SrcSpan, unLoc ) -import Util ( sortLe ) -import Var ( TyVar, DictId, Id ) -import Bag ( Bag, emptyBag, isEmptyBag, bagToList, unionBags, unionManyBags ) +import SrcLoc +import Util +import Var +import Bag \end{code} %************************************************************************ @@ -51,7 +52,9 @@ data HsValBinds id -- Value bindings (not implicit parameters) -- Recursive by default | ValBindsOut -- After renaming - [(RecFlag, LHsBinds id)] -- Dependency analysed + [(RecFlag, LHsBinds id)] -- Dependency analysed, later bindings + -- in the list may depend on earlier + -- ones. [LSig Name] type LHsBinds id = Bag (LHsBind id) @@ -76,7 +79,7 @@ data HsBind id fun_matches :: MatchGroup id, -- The payload - fun_co_fn :: ExprCoFn, -- Coercion from the type of the MatchGroup to the type of + fun_co_fn :: HsWrapper, -- Coercion from the type of the MatchGroup to the type of -- the Id. Example: -- f :: Int -> forall a. a -> a -- f x y = y @@ -84,15 +87,15 @@ data HsBind id -- (with a free type variable a'). The coercion will take -- a CoreExpr of this type and convert it to a CoreExpr of -- type Int -> forall a'. a' -> a' - -- Notice that the coercion captures the free a'. That's - -- why coercions are (CoreExpr -> CoreExpr), rather than - -- just CoreExpr (with a functional type) + -- Notice that the coercion captures the free a'. - bind_fvs :: NameSet -- After the renamer, this contains a superset of the + bind_fvs :: NameSet, -- After the renamer, this contains a superset of the -- Names of the other binders in this binding group that -- are free in the RHS of the defn -- Before renaming, and after typechecking, -- the field is unused; it's just an error thunk + + fun_tick :: Maybe (Int,[id]) -- This is the (optional) module-local tick number. } | PatBind { -- The pattern is never a simple variable; @@ -111,7 +114,7 @@ data HsBind id | AbsBinds { -- Binds abstraction; TRANSLATION abs_tvs :: [TyVar], abs_dicts :: [DictId], - abs_exports :: [([TyVar], id, id, [Prag])], -- (tvs, poly_id, mono_id, prags) + abs_exports :: [([TyVar], id, id, [LPrag])], -- (tvs, poly_id, mono_id, prags) abs_binds :: LHsBinds id -- The dictionary bindings and typechecked user bindings -- mixed up together; you can tell the dict bindings because -- they are all VarBinds @@ -162,7 +165,7 @@ instance OutputableBndr id => Outputable (HsValBinds id) where pprValBindsForUser :: (OutputableBndr id1, OutputableBndr id2) => LHsBinds id1 -> [LSig id2] -> SDoc pprValBindsForUser binds sigs - = vcat (map snd (sort_by_loc decls)) + = pprDeeperList vcat (map snd (sort_by_loc decls)) where decls :: [(SrcSpan, SDoc)] @@ -174,7 +177,7 @@ pprValBindsForUser binds sigs pprLHsBinds :: OutputableBndr id => LHsBinds id -> SDoc pprLHsBinds binds | isEmptyLHsBinds binds = empty - | otherwise = lbrace <+> vcat (map ppr (bagToList binds)) <+> rbrace + | otherwise = lbrace <+> pprDeeperList vcat (map ppr (bagToList binds)) <+> rbrace ------------ emptyLocalBinds :: HsLocalBinds a @@ -239,8 +242,13 @@ ppr_monobind :: OutputableBndr id => HsBind id -> SDoc ppr_monobind (PatBind { pat_lhs = pat, pat_rhs = grhss }) = pprPatBind pat grhss ppr_monobind (VarBind { var_id = var, var_rhs = rhs }) = ppr var <+> equals <+> pprExpr (unLoc rhs) -ppr_monobind (FunBind { fun_id = fun, fun_matches = matches }) = pprFunBind (unLoc fun) matches - -- ToDo: print infix if appropriate +ppr_monobind (FunBind { fun_id = fun, fun_infix = inf, + fun_matches = matches, + fun_tick = tick }) = + (case tick of + Nothing -> empty + Just t -> text "-- tick id = " <> ppr t + ) $$ pprFunBind (unLoc fun) inf matches ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_dicts = dictvars, abs_exports = exports, abs_binds = val_binds }) @@ -283,7 +291,7 @@ data IPBind id (LHsExpr id) instance (OutputableBndr id) => Outputable (HsIPBinds id) where - ppr (IPBinds bs ds) = vcat (map ppr bs) + ppr (IPBinds bs ds) = pprDeeperList vcat (map ppr bs) $$ pprLHsBinds ds instance (OutputableBndr id) => Outputable (IPBind id) where @@ -298,51 +306,67 @@ instance (OutputableBndr id) => Outputable (IPBind id) where %************************************************************************ \begin{code} --- A ExprCoFn is an expression with a hole in it +-- A HsWrapper is an expression with a hole in it -- We need coercions to have concrete form so that we can zonk them -data ExprCoFn - = CoHole -- The identity coercion +data HsWrapper + = WpHole -- The identity coercion - | CoCompose ExprCoFn ExprCoFn -- (\a1..an. []) `CoCompose` (\x1..xn. []) + | WpCompose HsWrapper HsWrapper -- (\a1..an. []) `WpCompose` (\x1..xn. []) -- = (\a1..an \x1..xn. []) - | ExprCoFn Coercion -- A cast: [] `cast` co + | WpCo Coercion -- A cast: [] `cast` co -- Guaranteedn not the identity coercion - -- Non-empty list in all of these, so that the identity coercion - -- is always exactly CoHole, not, say, (CoTyLams []) - | CoApps [Var] -- [] x1 .. xn; the xi are dicts or coercions - | CoTyApps [Type] -- [] t1 .. tn - | CoLams [Id] -- \x1..xn. []; the xi are dicts or coercions - | CoTyLams [TyVar] -- \a1..an. [] - | CoLet (LHsBinds Id) -- let binds in [] - -- (ould be nicer to be core bindings) - -instance Outputable ExprCoFn where - ppr CoHole = ptext SLIT("<>") - ppr (ExprCoFn co) = ppr co - ppr (CoApps ids) = ppr CoHole <+> interppSP ids - ppr (CoTyApps tys) = ppr CoHole <+> hsep (map pprParendType tys) - ppr (CoTyLams tvs) = sep [ptext SLIT("/\\") <> hsep (map (pprBndr LambdaBind) tvs), - ptext SLIT("->") <+> ppr CoHole] - ppr (CoLams ids) = sep [ptext SLIT("\\") <> hsep (map (pprBndr LambdaBind) ids), - ptext SLIT("->") <+> ppr CoHole] - ppr (CoLet binds) = sep [ptext SLIT("let") <+> braces (ppr binds), - ppr CoHole] - ppr (CoCompose co1 co2) = sep [ppr co1, ptext SLIT("<.>"), ppr co2] - -(<.>) :: ExprCoFn -> ExprCoFn -> ExprCoFn -CoHole <.> c = c -c <.> CoHole = c -c1 <.> c2 = c1 `CoCompose` c2 - -idCoercion :: ExprCoFn -idCoercion = CoHole - -isIdCoercion :: ExprCoFn -> Bool -isIdCoercion CoHole = True -isIdCoercion other = False + | WpApp Var -- [] d the 'd' is a type-class dictionary + | WpTyApp Type -- [] t the 't' is a type or corecion + | WpLam Id -- \d. [] the 'd' is a type-class dictionary + | WpTyLam TyVar -- \a. [] the 'a' is a type or coercion variable + + -- Non-empty bindings, so that the identity coercion + -- is always exactly WpHole + | WpLet (LHsBinds Id) -- let binds in [] + -- (would be nicer to be core bindings) + +instance Outputable HsWrapper where + ppr co_fn = pprHsWrapper (ptext SLIT("<>")) co_fn + +pprHsWrapper :: SDoc -> HsWrapper -> SDoc +pprHsWrapper it WpHole = it +pprHsWrapper it (WpCompose f1 f2) = pprHsWrapper (pprHsWrapper it f2) f1 +pprHsWrapper it (WpCo co) = it <+> ptext SLIT("`cast`") <+> pprParendType co +pprHsWrapper it (WpApp id) = it <+> ppr id +pprHsWrapper it (WpTyApp ty) = it <+> ptext SLIT("@") <+> pprParendType ty +pprHsWrapper it (WpLam id) = ptext SLIT("\\") <> pprBndr LambdaBind id <> dot <+> it +pprHsWrapper it (WpTyLam tv) = ptext SLIT("/\\") <> pprBndr LambdaBind tv <> dot <+> it +pprHsWrapper it (WpLet binds) = sep [ptext SLIT("let") <+> braces (ppr binds), it] + +(<.>) :: HsWrapper -> HsWrapper -> HsWrapper +WpHole <.> c = c +c <.> WpHole = c +c1 <.> c2 = c1 `WpCompose` c2 + +mkWpTyApps :: [Type] -> HsWrapper +mkWpTyApps tys = mk_co_fn WpTyApp (reverse tys) + +mkWpApps :: [Id] -> HsWrapper +mkWpApps ids = mk_co_fn WpApp (reverse ids) + +mkWpTyLams :: [TyVar] -> HsWrapper +mkWpTyLams ids = mk_co_fn WpTyLam ids + +mkWpLams :: [Id] -> HsWrapper +mkWpLams ids = mk_co_fn WpLam ids + +mk_co_fn :: (a -> HsWrapper) -> [a] -> HsWrapper +mk_co_fn f as = foldr (WpCompose . f) WpHole as + +idHsWrapper :: HsWrapper +idHsWrapper = WpHole + +isIdHsWrapper :: HsWrapper -> Bool +isIdHsWrapper WpHole = True +isIdHsWrapper other = False \end{code} @@ -360,26 +384,38 @@ serves for both. \begin{code} type LSig name = Located (Sig name) -data Sig name - = TypeSig (Located name) -- A bog-std type signature +data Sig name -- Signatures and pragmas + = -- An ordinary type signature + -- f :: Num a => a -> a + TypeSig (Located name) -- A bog-std type signature (LHsType name) - | SpecSig (Located name) -- Specialise a function or datatype ... - (LHsType name) -- ... to these types - InlineSpec + -- An ordinary fixity declaration + -- infixl *** 8 + | FixSig (FixitySig name) -- Fixity declaration + -- An inline pragma + -- {#- INLINE f #-} | InlineSig (Located name) -- Function name InlineSpec + -- A specialisation pragma + -- {-# SPECIALISE f :: Int -> Int #-} + | SpecSig (Located name) -- Specialise a function or datatype ... + (LHsType name) -- ... to these types + InlineSpec + + -- A specialisation pragma for instance declarations only + -- {-# SPECIALISE instance Eq [Int] #-} | 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 -- A Prag conveys pragmas from the type checker to the desugarer +type LPrag = Located Prag data Prag = InlinePrag InlineSpec @@ -388,13 +424,15 @@ data Prag (HsExpr Id) -- An expression, of the given specialised type, which PostTcType -- specialises the polymorphic function [Id] -- Dicts mentioned free in the expression + -- Apr07: I think this is pretty useless + -- see Note [Const rule dicts] in DsBinds InlineSpec -- Inlining spec for the specialised function isInlinePrag (InlinePrag _) = True isInlinePrag prag = False -isSpecPrag (SpecPrag _ _ _ _) = True -isSpecPrag prag = False +isSpecPrag (SpecPrag {}) = True +isSpecPrag prag = False \end{code} \begin{code} @@ -425,13 +463,14 @@ sigForThisGroup ns sig Just n -> n `elemNameSet` ns sigName :: LSig name -> Maybe name -sigName (L _ sig) = f sig - where - f (TypeSig 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 +sigName (L _ sig) = sigNameNoLoc sig + +sigNameNoLoc :: Sig name -> Maybe name +sigNameNoLoc (TypeSig n _) = Just (unLoc n) +sigNameNoLoc (SpecSig n _ _) = Just (unLoc n) +sigNameNoLoc (InlineSig n _) = Just (unLoc n) +sigNameNoLoc (FixSig (FixitySig n _)) = Just (unLoc n) +sigNameNoLoc other = Nothing isFixityLSig :: LSig name -> Bool isFixityLSig (L _ (FixSig {})) = True @@ -502,7 +541,8 @@ pprVarSig var ty = sep [ppr var <+> dcolon, nest 2 (ppr ty)] pprSpec :: (Outputable id, Outputable ty) => id -> ty -> InlineSpec -> SDoc pprSpec var ty inl = sep [ptext SLIT("SPECIALIZE") <+> ppr inl <+> pprVarSig var ty] -pprPrag :: Outputable id => id -> Prag -> SDoc -pprPrag var (InlinePrag inl) = ppr inl <+> ppr var -pprPrag var (SpecPrag expr ty _ inl) = pprSpec var ty inl +pprPrag :: Outputable id => id -> LPrag -> SDoc +pprPrag var (L _ (InlinePrag inl)) = ppr inl <+> ppr var +pprPrag var (L _ (SpecPrag expr ty _ inl)) = pprSpec var ty inl \end{code} +