Extensible Haskell front-end for the Programatica project
What is in this directory (pfe)
This directory contains modules implementing PFE, the Preliminary Front-End.
PFE provides the infrastructure to work with Haskell programs consisting of
a number of interdependent modules, stored in files. We use the term
project to denote a collection of Haskell modules that are to be
processed together by PFE.
PFE has built-in make(1)-like functionality: it
automatically processes files in the right order, and caches results between
runs to avoid reparsing and reanalyzing files that haven't changed.
Functionality
PFE provides the following functionality, which is available both in the
form of command line tools and as Haskell functions:
- Level 0
- Project management: creating a project, adding/removing files to
a project. Computing the module dependency graph. Various module level
queries.
- Level 1
- Computing some module properties that can be determined locally and that
does not require proper parsing.
- Level 2
- Analysis of import/export specifications, to determine what is in scope
on the top level of each module. This is based on the code decribed
in our paper
A Formal Specification
for the Haskell 98 Module System.
- Level 3
- Proper parsing of Haskell modules, taking fixity declarations into
account. The identifiers in the output of the proper parser are
decorated so that they are unique and you can tell what original entity
they refer to.
- Level 4
- Type checking. The type checker can output a syntax tree decorated with
type annotations. It can also perform the dictionary translation.
- Level 5
- Function level dependency graph. This is done after type checking, to
properly account for dependencies involving instance declarations.
(The module is called
PFEdeps
.)
- Chase (built on top of level 0)
- Import chasing. Searches for source files containing needed modules in
specified directories. This function assumes that a module
M
is stored in a file called M.hs
or M.lhs
.
(This is the only function of PFE that assumes a relation between file
names and module names.)
- HTML (built on top of level 3)
- Conversion to HTML, with highlighting and cross references.
Extensibility
PFE is designed to be extensible in several dimensions:
- Functionality
- It should be ease to create new command line tools that
inherits and extends the provided functionality.
- Language extensions.
- PFE is parameterized over the source language parser, so the source
language is not hardwired in PFE, but there are some restrictions:
- The type of the lexer is fixed and the parser is expected to
cooperate with the lexer to implement Haskell's layout conventions.
(See module
ParseMonad
.)
- The source file parser is expected to return something of
type
HsModuleI
i ds,
for some types i and ds.
(See module HsModule
.)
- The types returned by the parser are required to be instances
of a number of classes: a small number of instances are required
for level 0 functionality, more instances are required
for higher levels.
See ../property
for an example
of reusing PFE in an extended language.
- Monadic abstraction
- The PFE functions are operations in a monad, but the exact monad
type is left open. Code providing new functionality can use an
extended monad. The monad is constructed using
monad
transformers.
- Although various forms of IO are used by PFE, there are no
hardwired dependencies on the
IO
monad. Instead
we have defined classes of abstract IO operations
(see module AbstractIO
.)
and provide instances for the ordinary IO
monad and
some monad transformers. It should be possible to use PFE in
contexts where the standard monadic IO system is not directly
available (e.g., inside a Fudget).
Authors: TH
Contact: TH