Skip to content
Adam Bergmark edited this page May 17, 2014 · 6 revisions

TODO: The ordering still applies, but as of fay 0.20 some modules have moved around.

Fay compiles code through a number of different passes, let's go through them!

This can be seen as a sequence of operations. In reality it isn't quite that simple, but unless you are modifying the pipeline itself it shouldn't matter.

Executable

The outermost endpoint is the fay executable (src/main/Main.hs) which parses command line parameters to create a configuration (Fay.Types:CompileConfig) and invokes the API.

API

The API is used by the executable, tests, and is also available for other packages that want to use fay as a library. Fay.compileFromTo is the simplest entry point.

Fay.Compiler

Delegates to other modules to perform the actual compilation. The starting point is compileToplevelModule. This module shouldn't be used by other libraries.

Typechecking (optional)

Fay.Compiler.Typecheck:typecheck invokes GHC to typecheck all files including imports. This is done by default but can be disabled with the --no-ghc flag.

Parsing

The parser uses haskell-src-exts which takes a file path, does lexing and parsing and returns a haskell AST annotated with source locations for every node.

Desugaring

Simplifies the haskell-src-exts AST by removing some redundant nodes (e.g. transform (,) into \x y -> (x,y)), it throws errors for unsupported syntax (such as mdo). This is done in Fay.Compiler.Desugar.

Name resolution

haskell-names further annotates the HSE AST with name information so you can look up where names are defined (head -> Prelude.head). Name resolution is done after desugaring for RebindableSyntax support.

Preprocessing

ADTs, newtypes and type signatures are collected into the global compilation state so they are available when compiling each module. See Fay.Compiler.InitialPass.

Code generation

The Haskell AST is transformed into a custom JavaScript AST. Intertwined in this is compiling FFI declarations. Fay.Compiler.Decl, Fay.Compiler.Exp, Fay.Compiler.FFI etc.

Optimizations (optional)

Does some tail call optimizations and general flattening of the output. This is enabled with the -O flag. Note that some parts of the output becomes more readable when this occurs, and that file size will probably increase. We also do some optimizations so that compression will be easier. Fay.Compiler.Optimizer.

FFI data

Some transcoding information is needed for each abstract data type. These are generated from data available in CompileState and is then used by the FFI for converting between the Fay representation of data and JSON. Fay.Compiler.FFI.

Printing

Fay.Compiler.Print prints the JS AST to JavaScript.

Compression (optional)

The Closure Compiler can be invoked to reduce the output size significantly. It is invoked externally from Fay. Use this in production!