I'd advise anyone *not* to start by reading Main.hs!

The Main wrapper does lots of head-standing to try to ensure
that things happen in the right order (due to lazy evaluation), that
error messages get reported correctly, and to be as space-efficient as
possible.  The basic thing you need to know from Main is that the
compiler performs a sequence of transformations as follows:

    Lex source code
    Parse it
    Perform "need" analysis (what imported entities are required?)
    Parse interface files for imported modules
    Rename identifiers (also patches fixity information)
    Debugging source-to-source translation (data)  -- for tracing only
    Derive class instances where required
    Extract
    Debugging source-to-source translation (functions)  -- for tracing only
    Remove1.3  (translate list comprehensions, do notation, etc, to core)
    Strongly Connected Component analysis
    Type inference
    Build interface file for this module and write it out
    Fix syntax (small tweaks based on type information)
    Case transformation (change all pattern matches to case expressions)
    Expand primitives
    Determine free variables
    Do arity grouping on declarations
    Lambda lift
    Do arity grouping again
    Pos Atom (not sure what this does!)
    Dump zero-arity constructors to object file (as Gcode)
    Generate Gcode for functions: for each declaration, do
        STGGcode
        GcodeFix
        GcodeOpt1
        GcodeMem
        GcodeOpt2
        GcodeRel
    Dump Gcode to object file (as bytecode)

Each step is defined in a separate module, with fairly obvious naming.
There are also some supporting modules, such as the Tree234 data
structure, which is used as the basic lookup table (known as AssocTree
and Memo in different places); and very importantly, a state monad
which uses the non-standard binding connectives >>> >>>= =>>> >=>.

The source for the runtime interpreter which decodes the G machine
bytecode is in src/runtime/Kernel/mutator.c.

Niklas, the author of nhc, says he followed Simon Peyton Jones's book
"The Implementation of Functional Programming Languages" pretty
closely so I don't think there should be too many surprises.

