X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fcomm%2Fthe-beast%2Frenamer.html;fp=docs%2Fcomm%2Fthe-beast%2Frenamer.html;h=828b569bb92e526fb7619ea74f4eb864bcdddb12;hp=0000000000000000000000000000000000000000;hb=0065d5ab628975892cea1ec7303f968c3338cbe1;hpb=28a464a75e14cece5db40f2765a29348273ff2d2 diff --git a/docs/comm/the-beast/renamer.html b/docs/comm/the-beast/renamer.html new file mode 100644 index 0000000..828b569 --- /dev/null +++ b/docs/comm/the-beast/renamer.html @@ -0,0 +1,249 @@ + + +
+ ++ The renamer sits between the parser and the typechecker. + However, its operation is quite tightly interwoven with the + typechecker. This is partially due to support for Template Haskell, + where spliced code has to be renamed and type checked. In particular, + top-level splices lead to multiple rounds of renaming and type + checking. +
+
+ The main externally used functions of the renamer are provided by the
+ module rename/RnSource.lhs
. In particular, we have
+
+++rnSrcDecls :: HsGroup RdrName -> RnM (TcGblEnv, HsGroup Name) +rnTyClDecls :: [LTyClDecl RdrName] -> RnM [LTyClDecl Name] +rnSplice :: HsSplice RdrName -> RnM (HsSplice Name, FreeVars)+
+ All of which execute in the renamer monad RnM
. The first
+ function, rnSrcDecls
renames a binding group; the second,
+ rnTyClDecls
renames a list of (toplevel) type and class
+ declarations; and the third, rnSplice
renames a Template
+ Haskell splice. As the types indicate, the main task of the renamer is
+ to convert converts all the RdrNames to Names, which includes a number of
+ well-formedness checks (no duplicate declarations, all names are in
+ scope, and so on). In addition, the renamer performs other, not
+ strictly name-related, well-formedness checks, which includes checking
+ that the appropriate flags have been supplied whenever language
+ extensions are used in the source.
+
+ A RdrName.RdrName is pretty much just a string (for an + unqualified name like "f") or a pair of strings (for a + qualified name like "M.f"): +
++++data RdrName + = Unqual OccName + -- Used for ordinary, unqualified occurrences + + | Qual Module OccName + -- A qualified name written by the user in + -- *source* code. The module isn't necessarily + -- the module where the thing is defined; + -- just the one from which it is imported + + | Orig Module OccName + -- An original name; the module is the *defining* module. + -- This is used when GHC generates code that will be fed + -- into the renamer (e.g. from deriving clauses), but where + -- we want to say "Use Prelude.map dammit". + + | Exact Name + -- We know exactly the Name. This is used + -- (a) when the parser parses built-in syntax like "[]" + -- and "(,)", but wants a RdrName from it + -- (b) when converting names to the RdrNames in IfaceTypes + -- Here an Exact RdrName always contains an External Name + -- (Internal Names are converted to simple Unquals) + -- (c) by Template Haskell, when TH has generated a unique name+
+ The OccName type is described in The + truth about names. +
+ ++ Due to the tight integration of the renamer with the typechecker, both + use the same monad in recent versions of GHC. So, we have +
++++type RnM a = TcRn a -- Historical +type TcM a = TcRn a -- Historical+
+ with the combined monad defined as +
++++type TcRn a = TcRnIf TcGblEnv TcLclEnv a +type TcRnIf a b c = IOEnv (Env a b) c + +data Env gbl lcl -- Changes as we move into an expression + = Env { + env_top :: HscEnv, -- Top-level stuff that never changes + -- Includes all info about imported things + + env_us :: TcRef UniqSupply, -- Unique supply for local varibles + + env_gbl :: gbl, -- Info about things defined at the top level + -- of the module being compiled + + env_lcl :: lcl -- Nested stuff; changes as we go into + -- an expression + }+
+ the details of the global environment type TcGblEnv
and
+ local environment type TcLclEnv
are also defined in the
+ module typecheck/TcRnTypes.lhs
. The monad
+ IOEnv
is defined in utils/IOEnv.hs
and extends
+ the vanilla IO
monad with an additional state parameter
+ env
that is treated as in a reader monad. (Side effecting
+ operations, such as updating the unique supply, are done with
+ TcRef
s, which are simply a synonym for IORef
s.)
+
+ As anticipated by the variants Orig
and Exact
+ of RdrName
some names should not change during renaming,
+ whereas others need to be turned into unique names. In this context,
+ the two functions RnEnv.newTopSrcBinder
and
+ RnEnv.newLocals
are important:
+
+++newTopSrcBinder :: Module -> Maybe Name -> Located RdrName -> RnM Name +newLocalsRn :: [Located RdrName] -> RnM [Name]+
+ The two functions introduces new toplevel and new local names,
+ respectively, where the first two arguments to
+ newTopSrcBinder
determine the currently compiled module and
+ the parent construct of the newly defined name. Both functions create
+ new names only for RdrName
s that are neither exact nor
+ original.
+
+ A global RdrName
environment
+ RdrName.GlobalRdrEnv
is a map from OccName
s to
+ lists of qualified names. More precisely, the latter are
+ Name
s with an associated Provenance
:
+
+++data Provenance + = LocalDef -- Defined locally + Module + + | Imported -- Imported + [ImportSpec] -- INVARIANT: non-empty + Bool -- True iff the thing was named *explicitly* + -- in *any* of the import specs rather than being + -- imported as part of a group; + -- e.g. + -- import B + -- import C( T(..) ) + -- Here, everything imported by B, and the constructors of T + -- are not named explicitly; only T is named explicitly. + -- This info is used when warning of unused names.+
+ The part of the global RdrName
environment for a module
+ that contains the local definitions is created by the function
+ RnNames.importsFromLocalDecls
, which also computes a data
+ structure recording all imported declarations in the form of a value of
+ type TcRnTypes.ImportAvails
.
+
+ The function importsFromLocalDecls
, in turn, makes use of
+ RnNames.getLocalDeclBinders :: Module -> HsGroup RdrName -> RnM
+ [AvailInfo]
to extract all declared names from a binding group,
+ where HscTypes.AvailInfo
is essentially a collection of
+ Name
s; i.e., getLocalDeclBinders
, on the fly,
+ generates Name
s from the RdrName
s of all
+ top-level binders of the module represented by the HsGroup
+ RdrName
argument.
+
+ It is important to note that all this happens before the renamer
+ actually descends into the toplevel bindings of a module. In other
+ words, before TcRnDriver.rnTopSrcDecls
performs the
+ renaming of a module by way of RnSource.rnSrcDecls
, it uses
+ importsFromLocalDecls
to set up the global
+ RdrName
environment, which contains Name
s for
+ all imported and all locally defined toplevel binders. Hence,
+ when the helpers of rnSrcDecls
come across the
+ defining occurences of a toplevel RdrName
, they
+ don't rename it by generating a new name, but they simply look up its
+ name in the global RdrName
environment.
+
+ In Haskell when one writes "3" one gets "fromInteger 3", where + "fromInteger" comes from the Prelude (regardless of whether the + Prelude is in scope). If you want to completely redefine numbers, + that becomes inconvenient. So GHC lets you say + "-fno-implicit-prelude"; in that case, the "fromInteger" comes from + whatever is in scope. (This is documented in the User Guide.) +
++ This feature is implemented as follows (I always forget). +
HsExpr.SyntaxExpr
. Moreover, the association list
+ HsExpr.SyntaxTable
is set up by the renamer to map
+ rebindable names to the value they are bound to.
+ HsExpr.NegApp
, HsPat.NPat
,
+ HsPat.NPlusKPat
, HsLit.HsIntegral
, and
+ HsLit.HsFractional
) and
+ two constructs related to code>do expressions
+ (HsExpr.BindStmt
and
+ HsExpr.ExprStmt
) have rebindable syntax.
+ + +Last modified: Wed May 4 17:16:15 EST 2005 + + + + +