Libraries for processing GHC Core

Latest on Hackage:1.0.2

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.

BSD3 licensed by Andrew Tolmach, Tim Chevalier, The GHC Team
Maintained by Tim Chevalier
This package contains a set of example programs for handing GHC's
External Core format. The typechecker and interpreter give a precise
static and dynamic semantics.

==== Documentation ====

Documentation for the External Core format lives at:

Since this URL has been known to change, you can also search the web for
"An External Representation for the GHC Core Language" (a PDF; make sure
the date listed on page 1 is in 2009 or later).

==== Building ====

The ext-core library can be built in the usual Cabal manner:
1. runhaskell Setup.lhs configure
2. runhaskell Setup.lhs build
3. runhaskell Setup.lhs install

The file Language/Core/PrimEnv.hs can be automatically generated from GHC's
primop table. This distribution (as of September 2009) contains a snapshot
of GHC 6.10.4's primops. See the sources for Setup.lhs in this directory
for how to re-generate this file from a more recent version of GHC (you need
a GHC build tree if you want to do this.)

==== Parser warning ====

The parsers in this package don't parse negative rational literals
as found in Core generated by GHC 6.10.* or 6.12.2. The bug is in GHC
rather than the parsers. The bug is currently fixed in the HEAD
(as of June 14, 2010) and will be fixed in GHC 6.12.4. In the meantime,
you can get a patch for the stable branch (GHC 6.10) at:

If you want to use GHC 6.12.* instead, then just pull the HEAD.

==== Running the code ====

The easiest way to run the included checker and interpreter is to
install and use the Core Linker, which combines multiple External Core
source files into a single source file. Since even a very simple GHC-
compiled program relies on many different library modules, this makes
the code easier, and (as of September 2009) I haven't recently tested
the checker and interpreter on Core programs consisting of sets of
multiple modules.

The Core Linker lives at:

To use the tools, you need to generate External Core for all the base,
integer and ghc-prim libraries. You need a GHC source tree for
this. Adding "-fext-core" to the GhcLibHcOpts in your build.mk file,
then run "make" under libraries/.

If you want to run the sample interpreter, then before doing the previous
step, you need to apply some library patches that circumvent some of
GHC's implementations of I/O functions to avoid exposing primops that the
ext-core interpreter doesn't know how to do. In this directory, you'll
find a patch called simple_io.dpatch. "darcs apply" it under libraries/base.
In addition, base-library.dpatch masks out some additional library code
and can be "darcs apply" it under libraries/base. It contains implementations
of GHC.Float code that are ***very likely buggy***! This code is mainly
meant for demonstrating what you can do, not for generating ext-core code
that you can execute without substantial additional work. Finally,
download the integer-simple library from:
and "darcs apply" the patch in this directory called integer-simple-library.dpatch
under libraries/integer-simple.

Once you've compiled all the libraries to Core, installed the Core Linker, and
generated an example file from it -- say, hello_out.hcr -- you can try running
the checker and interpreter.

To do that, build the example Driver program (included in this directory) with:
ghc -package extcore Driver.hs -o Driver
and then:
./Driver hello_out.hcr

Of course, you can also import Language.Core.ParsecParser, Language.Core.Check,
Language.Core.Interp, etc. from your own programs.

Tested most recently with GHC 6.12.2.

==== Acknowledgments ====

Thanks to Neil Brown for contributing the code in Language.Core.DebugPrinter
and to Sönke Hahn for contributing patches updating the library for
GHC 7.6.

==== Bugs? ====

Probably. Please direct questions or bug reports both to:
Tim Chevalier <chevalier@alum.wellesley.edu>
and to

==== Notes ====
[Warning: the following notes may be out of date, as of September 2009.]

The checker should work on most programs. Bugs (and infelicities)
I'm aware of:

There's some weirdness involving funny character literals. This can
be fixed by writing a new lexer for chars rather than using Parsec's
built-in charLiteral lexer. But I haven't done that.

Typechecking all the GHC libraries eats about a gig of heap and takes a
long time. I blame Parsec. (Someone who was bored, or understood happy
better than I do, could update the old happy parser, which is still in the

The interpreter is also memory-hungry, but works for small programs
that only do simple I/O (e.g., putStrLn is okay; not much more than that)
and don't use Doubles or arrays. For example: exp3_8, gen_regexps, queens,
primes, rfib, tak, wheel-sieve1, and wheel-sieve2, if modified so as not
to take input or arguments.


extcore change log

New in version 1.0.1:
* Fixed documentation URL in README. Updated required Cabal version.

New in version 1.0:

* Disambiguate everythingBut function defined in Language.Core.Utils,
as Data.Generics in GHC 7 defines a function with the same name (but a
different type); thanks to Jason Dagit.

* As the library appears to have more than one user and no major bugs
have been reported, increment version to 1.0.

New in version 0.9.2:

* Added debug printer code, contributed by Neil Brown (see

New in version 0.9.1:

* Print out negative rational literals correctly (that is,
according to the External Core syntax specification).

New in version 0.9:

* Documentation only.

New in version 0.8:

* Added more library patches (allowing for more library code
to be usefully compiled to External Core).

* Removed stray debug traces.

New in version 0.7:

* Tested with GHC 6.12.2 and 6.10.4, and updated compiler flags appropriately.

* Eliminated compiler warnings in ParsecParser (no substantial changes) and
some other modules.

New in version 0.6:

* Re-added old lexer and happy parser. (The Parsec parser is quite inefficient
and not recommended if you desire good performance. It contains some
backtracking that could be removed easily, but other kinds of backtracking in
it are harder to remove while keeping the parser nice and modular.)

* Rewrote ElimDeadCode without using Data.Generics.

* Re-added Dependencies module.

* Fixed bug in Prep that was causing some unapplied data constructors to
not be eta-expanded.

* Changed Env type to Data.Map everywhere.

* Fixed bug in Printer with printing of escape characters.
comments powered byDisqus