Skip to content

Liberty compiler design notes

cadrian edited this page Sep 13, 2010 · 16 revisions

This document is by no means an exhaustive “detailed design document”. I don’t believe in those; they are bound not to be up-to-date.

On the other hand one needs a few architecture and general design notes to understand how the Liberty compiler is built. For details… read the code.

Syntax, semantics

Note the difference between “syntax” and “semantics”:

  • the “syntax” trees represent classes, i.e. a syntactic representation of one or more types (think generics here)
  • the “semantics” tree represent types, with:
    • actual generic parameters (which bind formal generic names to types)
    • a set of features correctly (re)named, (re)exported, (re/un)defined, and with a completely defined contract
    • parents (parent types, both conforming and non-conforming)
    • a complete invariant

The syntax tree

The Liberty parser uses a general parsing library. Note that the LIberty Eiffel grammar belongs to the library, so anyone may build parsers using the exact Liberty language definition.

The nodes produced by the parser are “AST” nodes (Abstract Syntactic Tree). Those nodes may be found in the src/tools/syntax/tree cluster.

The root node of an AST is a class.

The semantics tree

It is the most important tree. The root node of a semantics tree is LIBERTY_TYPE, which represents a type of the system.

The semantics nodes are in the src/tools/semantics cluster and sub-clusters:

  • contract contains the pre- and post-conditions, invariants, and so on
  • entities contains all the kinds of named entities which conform to LIBERTY_ENTITY
  • expressions contains all the kinds of expressions which conform to LIBERTY_EXPRESSION
  • features contains all the kinds of features which conform to LIBERTY_FEATURE: attributes, constants, deferred, do-, and once-functions
  • instructions contains all the kinds of instructions which conform to LIBERTY_INSTRUCTION

The class LIBERTY_TYPE_BUILDER is in charge of building a LIBERTY_TYPE from a LIBERTY_AST_CLASS and a set of LIBERTY_TYPE representing the actual generic parameters.

The class LIBERTY_UNIVERSE is in charge of holding all the instances of LIBERTY_TYPE.

A static type is a self-sufficient semantical structure that is attached to every expression of the system. It allows to discover some properties about the system.
A dynamic type is the run-time type of an expression. The compiler will be able to compute the complete set of possible dynamic types at each point of the program, thus allowing the optimization of the late-binding sites.

Each feature is defined in two steps:

The feature hierarchy is:

Instructions are operations the program must perform. There are several kinds of instructions:

Expressions are elements that have a static type (known as “return_type” in Liberty’s code). Each expression may either be a part of another expression, or used by an instruction.