so i don't think that adding to the main text alone would help
people like me, who would need an index or a how-to faq. but trying to keep an entirely separate index or faq in sync with the main text seems hopeless as well.
in light of this, my suggestion for improvement would be
to embedd individual faq answers directly into the main
text, with a special tag, and to have a separate faq page,
which would do nothing but gather those tags from the
main text in a single collection (preferably automatically).

something like this shouldn't be too hard, in principle, but
as always, there are hurdles, in practice:-) my first thought,
since the wiki seems to be xhtml, was to use xslt (after all,
it seems a straightforward task of extracting some elements marked FAQ from a collection of xml documents).

unfortunately, the commentary pages aren't quite valid xhtml,
the main offender being unescaped & and the like (should be & - even in hrefs?? at least, the error messages complain about incomplete EntityRefs there, or missing ';'), especially, but not only, in the sidebars (which i can't edit on the wiki?).

there might be objections against the xslt approach in
general (wiki will never stay valid; not all browsers support
xslt fully, so instead of just putting an xml-page with an
xslt-stylesheet online, one would need to run something like xsltproc, to regenerate the index whenever one of the commentary pages was updated; perhaps one might
want to use something like haskell tagsoup instead).

but anyway, i thought i'd use the Renamer page (edited
to escape &s and to add one FAQ, which is just a div
with a class and an anchor for reference) to demonstrate the idea: if you put the attached files in a single directory,
and either open faq.xml in ie, or run xsltproc over faq.xml,
you'll get, courtesy of Index.xslt, a simple html page listing h1/h2-headers, with the single faq entry mixed in, all with links back to the edited Renamer page.
so the faq entries would remain in the main text, where
they could provide a focus, and stay in sync, while the
faq, providing a how-to reference index, would be extracted from the main text by script. similar methods
could perhaps be applied to the user guide?

do you think this would be worthwhile to have? and how
would one keep the wiki xml valid (can the trac wiki
validate on edit?), or should one use tagsoup instead?
is it even possible to trigger an extraction script on edit?

claus

it's been a long time since i did silly things like using xslt to read rss feeds, so expect some errors in the xslt/xml!-)
Title: Commentary/Compiler/Renamer - GHC - Trac

[ Up: Commentary/Compiler/HscMain ]

The renamer

The renamer's Number One task is to replace RdrNames with Names. For example, consider

module K where
  f x = True

module N where
  import K

module M where
  import N( f ) as Q
  f = (f, M.f, Q.f, \f -> f)

(where all the variables are RdrNames). The result of renaming module M is:

M.f = (M.f, M.f, K.f, \f_22 -> f_22)

where all these names are now Names.

  • The top-level unqualifed RdrName "f" has become the External Name M.f.
  • The occurrences "f" and "M.f" are both bound to this Name.
  • The qualified RdrName "Q.f" becomes the Name K.f, because the function is defined in module K.
  • The lambda-bound "f" becomes an Internal name, here written f_22. (All the External names have uniques too, but we often do not print them.)

In addition, the renamer does the following things:

  • Sort out fixities. The parser parses all infix applications as right-associative, regardless of fixity. For example "a * b + c" is parsed as "a * (b + c)". The renamer re-associates such nested operator applications, using the fixities declared in the module.
  • Dependency analysis for mutually-recursive groups of declarations. This divides the declarations into strongly-connected components.
  • Lots of lexical error checking: variables out of scope, unused bindings, unused imports, patterns that use the same binder many times, etc.

The renamer sits between the parser and the typechecker. However, its operation is quite tightly interwoven with the typechecker. This is mainly 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. It uses the same monad as the typechecker.

The global renamer environment, GlobalRdrEnv

A big part of the renamer's task is to build the global rdr-env for the module, of type GlobalRdrEnv. This environment allows us to take a qualified or un-qualified RdrName and figure out which Name it means. The global rdr-env is built by looking at all the imports, and the top-level declarations of the module.

You might think that the global rdr-env would be a mapping from RdrName to Name, but it isn't. Here is what it looks like, after at least three iterations (all in compiler/basicTypes/RdrName.lhs):

type GlobalRdrEnv = OccEnv [GlobalRdrElt]
  -- An (OccEnv a) is a mapping from OccName to a

data GlobalRdrElt = GRE { gre_name :: Name
                        , gre_prov :: Provenance
                        , gre_par :: Parent }

data Provenance = LocalDef | Imported [ImportSpec]

data ImportSpec = ImpSpec { is_decl :: ImpDeclSpec, is_item ::  ImpItemSpec }

data Parent = NoParent | ParentIs Name

Here is how to understand these types:

  • The environment (GlobalRdrEnv) maps an OccName to a list of all entities with that occurence name that are in scope (in any way).
  • Each of these is represented by a GlobalRdrElt, which gives the entity's Name plus a specification of how it is in scope, its Provenance.
  • The Provenance has one of two forms. Either it is in scope because it is defined in this module (LocalDef), or because it is imported. In the latter case, the [ImportSpec] describes all the import statements that bring it into scope.
  • An ImportSpec has two components:
    • An ImpDeclSpec that describes the entire import declaration. This is shared between all entities brought into scope by a particular import declaration.
    • An ImpItemSpec that describes the import item that brought the entity into scope.

For example, given

import qualified M( x, T(g) ) as Q

the ImpDeclSpec would describe the qualified and as part, while the ImpItemSpec describes the T(g) part. You can look in RdrName.lhs to see what an ImportDeclSpec and ImpItemSpec are like!

  • The Parent of an entity is the Name under which it is grouped when the forms T(..) or T(C,D) are used in an export or import list. In the T(..) form, all the things whose Parent is T are chosen. In the T(C,D) form, it is required that C and D have T as parents. For example,
    • The Parent of a data constructor is its data type
    • The Parent of a record field selector is its data type
    • The Parent of a class operation is its class

With all that information, we can give good error messages, especially in the case where an occurrence "f" is ambiguous (i.e. different entities, both called "f", were imported by diffferent import statements).

The global rdr-env is created by compiler/rename/RnNames.lhs.

It is important to note that the global rdr-env is created before the renamer actually descends into the top=level bindings of a module. In other words, before TcRnDriver.rnTopSrcDecls performs the renaming of a module by way of RnSource.rnSrcDecls, it uses RnNames.importsFromLocalDecls to set up the global rdr-env environment, which contains Names 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 rdr-env.

Name Space Management

(too much detail?)

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 RdrNames? that are neither exact nor original.

Rebindable syntax

(ToDo: Not fully proof-read.)

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).

  • Names that are implicitly bound by the Prelude, are marked by the type 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.
  • Currently, five constructs related to numerals (HsExpr.NegApp, HsPat.NPat, HsPat.NPlusKPat, HsLit.HsIntegral, and HsLit.HsFractional) and two constructs related to do-expressions (HsExpr.BindStmt and HsExpr.ExprStmt) have rebindable syntax.
  • When the parser builds these constructs, it puts in the built-in Prelude Name (e.g. PrelNum.fromInteger).
  • When the renamer encounters these constructs, it calls RnEnv.lookupSyntaxName. This checks for -fno-implicit-prelude; if not, it just returns the same Name; otherwise it takes the occurrence name of the Name, turns it into an unqualified RdrName, and looks it up in the environment. The returned name is plugged back into the construct.
  • The typechecker uses the Name to generate the appropriate typing constraints.
<?xml version='1.0'?>
<?xml-stylesheet href="Index.xslt" type="text/xsl"?>

<Chapters>

  <Chapter src="Renamer.html"/>
  <!--
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Pipeline"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/KeyDataTypes"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/HsSynType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/RdrNameType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/NameType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/EntityTypes"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/TypeType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/FC"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/CoreSynType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/StgSynType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/CmmType"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/HscMain"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Renamer"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/StrictnessAnalysis"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Core2Stg"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/CodeGen"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/CPS"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/API"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/SymbolNames"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/TemplateHaskell"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/WiredIn"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Packages"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Finder"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/PprC"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/NCG"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/HscMain"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/API"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/HaskellExecution"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Profiling"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/PositionIndependentCode"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/DynamicLinking"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/SharedLibraries"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/UserManual"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/EvilMangler"/>
  <Chapter src="http://hackage.haskell.org/trac/ghc/wiki/Commentary/DebuggingGhcCrashes"/>
  -->

</Chapters>


Attachment: Index.xslt
Description: Binary data

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to