Components

evc.c

evc.c is the main source file for the compiler. It handles the command line parsing and executes the lower level functions of the compiler accordingly.

These lower level functions are:

compiler.(c|h)

The files compiler.(c|h) handles the parsing of the input and creation of the AST. This is done by initializing the lexer with the input string and passing every token that is generated by the lexer to the parser. The parser then generates the AST based on it's grammar.

The return is an AST.

lexer.l

lexer.l is the specification for the lexer generator Flex, which is invoked to create C source code for a lexer that generates all necessary token for the parser from the input.

The specification consists of some configuration for the lexer generator and all strings that should be matched as single tokens. Whitespace is ignored and code comments are skipped.

parser.y

parser.y is the specification for The LEMON Parser Generator which is used to generate a parser from the grammar of the Event language.

Each grammar rule consists of left and a right side. The left side represents the name of the generated node in the AST. the right side is a composition of components needed to generate that node. Based on the given components the body of the rule executes code. Mostly a new node is created by tree_create_node() from the LibCollect. The components are integrated into the new node to build the whole AST. Some rules create scopes for the validation and code generation. Take a look at Scopes for more information.

parser_signatures.h

parser_signatures.h contains the prototypes of the generated parser functions. LEMON does not generate them itself because it doesn't know which data types the tokens will have.

parser_state.h

parser_state.h contains the state of the parser at any time. It also holds a reference to the generated AST for easier handling inside the compiler.

ast.(c|h)

The files ast.(c|h) define which information the AST is holding. For that, a struct payload is defined which is inserted into a new tree node. The payload contains following information:

The custom data can hold:

scope.(c|h)

The files scope.(c|h) provide functions to create the scopes and references from the information in the AST. The most important function is link_references(). It iterates over the tree and visits every node. For every node it resolves necessary references by search the tree in parent direction until it founds the valid node. That scoping is later used by the validator and the code generator.

validator.(c|h)

validator.(c|h) is used to check if the AST and it's scopes and references are created according to our language definition. For that it provides a single function validate() that iterates over the tree and perform the necessary checks for every node. The checks are more or less complicated. Take a look into the comments of the source code to learn more about the validation.

codegen.(c|h)

codegen.(c|h) generates an LLVM module from the AST. The function generate_module() iterates over all declarations and recursively generates the necessary LLVM-IR for every sub-tree node.

operators.(c|h)

The files operators.(c|h) constitute the standard library for the Event language. It has to be shipped with a compiled Event program. The following operators are implemented: