summaryrefslogtreecommitdiff
path: root/ghc/compiler/abstractSyn/HsDecls.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/compiler/abstractSyn/HsDecls.lhs')
-rw-r--r--ghc/compiler/abstractSyn/HsDecls.lhs299
1 files changed, 299 insertions, 0 deletions
diff --git a/ghc/compiler/abstractSyn/HsDecls.lhs b/ghc/compiler/abstractSyn/HsDecls.lhs
new file mode 100644
index 0000000000..806377563a
--- /dev/null
+++ b/ghc/compiler/abstractSyn/HsDecls.lhs
@@ -0,0 +1,299 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+%
+\section[HsDecls]{Abstract syntax: global declarations}
+
+Definitions for: @FixityDecl@, @TyDecl@ and @ConDecl@, @ClassDecl@,
+@InstDecl@, @DefaultDecl@.
+
+\begin{code}
+#include "HsVersions.h"
+
+module HsDecls where
+
+import HsBinds ( nullMonoBinds, ProtoNameMonoBinds(..),
+ MonoBinds, Sig
+ )
+import HsPat ( ProtoNamePat(..), RenamedPat(..), InPat )
+import HsPragmas ( DataPragmas, TypePragmas, ClassPragmas,
+ InstancePragmas, ClassOpPragmas
+ )
+import HsTypes
+import Id ( Id )
+import Name ( Name )
+import Outputable
+import Pretty
+import ProtoName ( cmpProtoName, ProtoName(..) ) -- .. for pragmas only
+import SrcLoc ( SrcLoc )
+import Unique ( Unique )
+import Util
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[FixityDecl]{A fixity declaration}
+%* *
+%************************************************************************
+
+These are only used in generating interfaces at the moment. They are
+not used in pretty-printing.
+
+\begin{code}
+data FixityDecl name
+ = InfixL name Int
+ | InfixR name Int
+ | InfixN name Int
+
+type ProtoNameFixityDecl = FixityDecl ProtoName
+type RenamedFixityDecl = FixityDecl Name
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Outputable name)
+ => Outputable (FixityDecl name) where
+ ppr sty (InfixL var prec) = ppCat [ppStr "infixl", ppInt prec, pprOp sty var]
+ ppr sty (InfixR var prec) = ppCat [ppStr "infixr", ppInt prec, pprOp sty var]
+ ppr sty (InfixN var prec) = ppCat [ppStr "infix ", ppInt prec, pprOp sty var]
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[TyDecl]{An algebraic datatype or type-synonym declaration (plus @DataTypeSig@...)}
+%* *
+%************************************************************************
+
+\begin{code}
+data TyDecl name
+ = TyData (Context name) -- context (not used yet)
+ name -- type constructor
+ [name] -- type variables
+ [ConDecl name] -- data constructors
+ [name] -- derivings
+ (DataPragmas name)
+ SrcLoc
+
+ | TySynonym name -- type constructor
+ [name] -- type variables
+ (MonoType name) -- synonym expansion
+ TypePragmas
+ SrcLoc
+
+type ProtoNameTyDecl = TyDecl ProtoName
+type RenamedTyDecl = TyDecl Name
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Outputable name)
+ => Outputable (TyDecl name) where
+
+ ppr sty (TyData context tycon tyvars condecls derivings pragmas src_loc)
+ = ppAbove (ifPprShowAll sty (ppr sty src_loc)) -- ToDo: pragmas
+ (ppHang (ppCat [ppStr "data", pprContext sty context, ppr sty tycon, interppSP sty tyvars])
+ 4
+ (ppSep [
+ ppr sty condecls,
+ if (null derivings) then
+ ppNil
+ else
+ ppBesides [ppStr "deriving (", interpp'SP sty derivings, ppStr ")"]]))
+
+ ppr sty (TySynonym tycon tyvars mono_ty pragmas src_loc)
+ = ppHang (ppCat [ppStr "type", ppr sty tycon, interppSP sty tyvars])
+ 4 (ppCat [ppEquals, ppr sty mono_ty,
+ ifPprShowAll sty (ppr sty src_loc)]) -- ToDo: pragmas
+\end{code}
+
+A type for recording what type synonyms the user wants treated as {\em
+abstract} types. It's called a ``Sig'' because it's sort of like a
+``type signature'' for an synonym declaration.
+
+Note: the Right Way to do this abstraction game is for the language to
+support it.
+\begin{code}
+data DataTypeSig name
+ = AbstractTypeSig name -- tycon to abstract-ify
+ SrcLoc
+ | SpecDataSig name -- tycon to specialise
+ (MonoType name)
+ SrcLoc
+
+
+type ProtoNameDataTypeSig = DataTypeSig ProtoName
+type RenamedDataTypeSig = DataTypeSig Name
+
+instance (NamedThing name, Outputable name)
+ => Outputable (DataTypeSig name) where
+
+ ppr sty (AbstractTypeSig tycon _)
+ = ppCat [ppStr "{-# ABSTRACT", ppr sty tycon, ppStr "#-}"]
+
+ ppr sty (SpecDataSig tycon ty _)
+ = ppCat [ppStr "{-# SPECIALSIE data", ppr sty ty, ppStr "#-}"]
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[ConDecl]{A data-constructor declaration}
+%* *
+%************************************************************************
+
+A data constructor for an algebraic data type.
+
+\begin{code}
+data ConDecl name = ConDecl name [MonoType name] SrcLoc
+
+type ProtoNameConDecl = ConDecl ProtoName
+type RenamedConDecl = ConDecl Name
+\end{code}
+
+In checking interfaces, we need to ``compare'' @ConDecls@. Use with care!
+\begin{code}
+eqConDecls cons1 cons2
+ = case (cmpList cmp cons1 cons2) of { EQ_ -> True; _ -> False }
+ where
+ cmp (ConDecl n1 tys1 _) (ConDecl n2 tys2 _)
+ = case cmpProtoName n1 n2 of
+ EQ_ -> cmpList (cmpMonoType cmpProtoName) tys1 tys2
+ xxx -> xxx
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Outputable name) => Outputable (ConDecl name) where
+
+ ppr sty (ConDecl con mono_tys src_loc)
+ = ppCat [pprNonOp sty con,
+ ppInterleave ppNil (map (pprParendMonoType sty) mono_tys)]
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[ClassDecl]{A class declaration}
+%* *
+%************************************************************************
+
+\begin{code}
+data ClassDecl name pat
+ = ClassDecl (Context name) -- context...
+ name -- name of the class
+ name -- the class type variable
+ [Sig name] -- methods' signatures
+ (MonoBinds name pat) -- default methods
+ (ClassPragmas name)
+ SrcLoc
+
+type ProtoNameClassDecl = ClassDecl ProtoName ProtoNamePat
+type RenamedClassDecl = ClassDecl Name RenamedPat
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Outputable name,
+ NamedThing pat, Outputable pat)
+ => Outputable (ClassDecl name pat) where
+
+ ppr sty (ClassDecl context clas tyvar sigs methods pragmas src_loc)
+ = ppAboves [ppCat [ppStr "class", pprContext sty context, ppr sty clas,
+ ppr sty tyvar, ppStr "where"],
+ -- ToDo: really shouldn't print "where" unless there are sigs
+ ppNest 4 (ppAboves (map (ppr sty) sigs)),
+ ppNest 4 (ppr sty methods),
+ ppNest 4 (ppr sty pragmas)]
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[InstDecl]{An instance declaration (also, @SpecialisedInstanceSig@)}
+%* *
+%************************************************************************
+
+\begin{code}
+data InstDecl name pat
+ = InstDecl (Context name)
+ name -- class
+ (MonoType name)
+ (MonoBinds name pat)
+ Bool -- True <=> This instance decl is from the
+ -- module being compiled; False <=> It is from
+ -- an imported interface.
+
+ FAST_STRING{-ModuleName-}
+ -- The module where the instance decl
+ -- originally came from; easy enough if it's
+ -- the module being compiled; otherwise, the
+ -- info comes from a pragma.
+
+ FAST_STRING
+ -- Name of the module who told us about this
+ -- inst decl (the `informer') ToDo: listify???
+
+ [Sig name] -- actually user-supplied pragmatic info
+ (InstancePragmas name) -- interface-supplied pragmatic info
+ SrcLoc
+
+type ProtoNameInstDecl = InstDecl ProtoName ProtoNamePat
+type RenamedInstDecl = InstDecl Name RenamedPat
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Outputable name,
+ NamedThing pat, Outputable pat)
+ => Outputable (InstDecl name pat) where
+
+ ppr sty (InstDecl context clas ty binds local modname imod uprags pragmas src_loc)
+ = let
+ top_matter = ppCat [ppStr "instance", pprContext sty context, ppr sty clas, ppr sty ty]
+ in
+ if nullMonoBinds binds && null uprags then
+ ppAbove top_matter (ppNest 4 (ppr sty pragmas))
+ else
+ ppAboves [
+ ppCat [top_matter, ppStr "where"],
+ ppNest 4 (ppr sty uprags),
+ ppNest 4 (ppr sty binds),
+ ppNest 4 (ppr sty pragmas) ]
+\end{code}
+
+A type for recording what instances the user wants to specialise;
+called a ``Sig'' because it's sort of like a ``type signature'' for an
+instance.
+\begin{code}
+data SpecialisedInstanceSig name
+ = InstSpecSig name -- class
+ (MonoType name) -- type to specialise to
+ SrcLoc
+
+type ProtoNameSpecialisedInstanceSig = SpecialisedInstanceSig ProtoName
+type RenamedSpecialisedInstanceSig = SpecialisedInstanceSig Name
+
+instance (NamedThing name, Outputable name)
+ => Outputable (SpecialisedInstanceSig name) where
+
+ ppr sty (InstSpecSig clas ty _)
+ = ppCat [ppStr "{-# SPECIALIZE instance", ppr sty clas, ppr sty ty, ppStr "#-}"]
+\end{code}
+
+%************************************************************************
+%* *
+\subsection[DefaultDecl]{A @default@ declaration}
+%* *
+%************************************************************************
+
+There can only be one default declaration per module, but it is hard
+for the parser to check that; we pass them all through in the abstract
+syntax, and that restriction must be checked in the front end.
+
+\begin{code}
+data DefaultDecl name
+ = DefaultDecl [MonoType name]
+ SrcLoc
+
+type ProtoNameDefaultDecl = DefaultDecl ProtoName
+type RenamedDefaultDecl = DefaultDecl Name
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Outputable name)
+ => Outputable (DefaultDecl name) where
+
+ ppr sty (DefaultDecl tys src_loc)
+ = ppBesides [ppStr "default (", interpp'SP sty tys, ppStr ")"]
+\end{code}