7. Processing Phases

Like C, Felix processes code in well defined phases, however the phasing is not per program as in C, but per parse unit for early phases, and per program for late phases.
Hash-pre-processor
This processor lexes on a linewise bases. Lines beginning with the # symbol are managed by the hash-pre-processor. Other lines may also be skipped as a result of # conditional compilation. The # pre-processor may also recursively include files, which by convention use ".flxh" suffix. The # preprocessor outputs a token stream.
Token-pre-processor
The token pre-processor accepts the hash-preprocessor output token stream and produces another token stream as its output. It is used to prepare the input stream for the parser, by rewriting certain constructs which are not parsable by an LALR parser.

It currently consists of a sequence of filters:

White filter
White filtering elides whitespace, end of line, and free form comments.
Int filter
The 'int' filter replaces sequences of tokens representing ISO C99 arithmetic type names with the corresponding Felix equivalent. For example "long long" is replaced by "vlong".
Parser
The parser accepts a token stream constructed by the token level preprocessor, parses it, applies syntactic constraints, and generates an Syntax Tree (AST). [The tree is technically not abstract but we call it an AST anyhow]
Syntax Macro Processor
The syntax macro processor is a high end macro processor which operates on the AST. In particular it respects scope and syntactic kind, so that, for example, the result of macros in a subexpression are restricted to that subexpression, and the result is an expression.

In particular, syntax macros also respect block scope and file scope. Therefore, if you prepare syntax macros in a separate file, you must #import or #include the file, to export the macros. Macros defined in a file included by an include directive are only recognized within that file (after other phases of processing of course).

Desugarer
The desugarer is responsible for mapping some higher level constructions of the grammar to lower level primitives, and also for recognizing certain special identifiers in certain contexts, and performing rewriting operations, thus avoiding the introduction of too many keywords.

It also handles elision of conditional constructions nased on constant conditions, and the recursive conditional desugaring of files denoted by include directives. The include facility caches the results of syntax macro processing, and inclusion is subject to time-stamp checking to relieve the compiler from expensive front end processing. The caches have the extension ".par".

Desugaring is also responsible for splitting scoped entities into one of three kinds of statement forms: directives, definitions and executable. Some statements, notably variable initialisations, can generate both a definition and an executable component.

Symbol Table construction
The symbol table contructor is responsible for translation of the hierarchical forms output by the desugarer
Name Binder
The name binding (lookup) phase is responsible for translating the AST into a set of bound definitions. This is the slowest phase of compilation, and involves all overload resolution. The name binder is fully polymorphic. Note in Felix, definitions are not sequential: all definitions may depend on definitions in the same scope or any definition in an ancestor. There is no need to provide forward declarations to support recursion (and indeed there is no syntax for it).
Optimiser
Felix has a high end optimiser which primarily functions by inlining and substitution. However the optimiser also does usage analysis, and eliminates unused components.
Code Generator
The code generator is responsible for translating optimised sets of definitions into files which are subsequently processed by the C++ compiler. The code generator also applies the instantiator, which is used to instantiate polymorphic entities. This instantiation is transient and purely functional: no instantiated definitions are ever created, except in the ouput C++ code.
C++ Compilation
This phase invokes the client C++ compiler and linker to generate object files, libraries, shared libraries and/or programs. It may include or link to standard Felix run time library (RTL) support code, and/or standard Felix driver routines.
Execution
The binaries generated by C++ compilation are finally executed. If dynamic linkage was chose in the C++ compile/link phase, this phase includes loading of the support code, and loading of the user application code by the chosen driver.