-
Notifications
You must be signed in to change notification settings - Fork 89
Compiler passes
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.
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.
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.
Delegates to other modules to perform the actual compilation. The starting point is compileToplevelModule
. This module shouldn't be used by other libraries.
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.
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.
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
.
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.
ADTs, newtypes and type signatures are collected into the global compilation state so they are available when compiling each module. See Fay.Compiler.InitialPass
.
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.
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
.
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
.
Fay.Compiler.Print
prints the JS AST to JavaScript.
The Closure Compiler can be invoked to reduce the output size significantly. It is invoked externally from Fay. Use this in production!