This first step in the compiling mechanism is necessary, but not so important since it is done very cleanly by the default Pliant parser and so most of you wont change it.
var Int i := 3
For more details about parsing, please read the advanced description of the Pliant parsing mechanism.
This is the main step of the Pliant compiling machinery: the one that gives Pliant the ability to be extended much deeper than any other language.
We will start by studying the data structures on which we deal at this step of the compiling mechanism.
Let's start by a tiny example:suppose we have defined an integer variable 'x' and we write the tiny programx+2
The result of the parsing is an expression which initial value is the identifier '+'. This expression as two sub expressions; the first one as an initial value which is the identifier 'x' and the second one as an initial value which the the integer 2.Compiling will consist in attaching to the expression the program that does the job. In order to do that, the compiler will ask each '+' functions available if it can compile the expression. The various '+' functions will ask to compile both subexpressions to check if there types match.The integer '+' function will match, so it will create a new temporary integer argument to store the result, then attach the instruction that perform the operation to the expression
As a summary, compiling an expression consists in checking the various possible functions for the initial value, and attaching the instruction that call the right one.A meta function is a function that does the compiling job itself. It has a single argument which is a pointer the expression to be compiled, can check the number of arguments, their types and so on, and finally chose to attach some instructions and define the result (which means that it succeeded to compile the expression) or abort
An expression contains:
An argument is a compile time object that defines a data on which the program will deal at run time.An argument contains:
The argument location may be:
compiling our sample program would build:
Please notice that the instructions produced in this sample are not accurate, because i wanted to keep the example simple.
At the beginning of this step, we have a list of plateform independent instructions; then we go through multiple rewriting (optimizing) functions, so that finely we get a list of machine code instructions.Each optimizing function takes a GeneratorContext structure as parameter (a GeneratorContext contains mainly the list of instructions) and rewrites instructions or set arguments location on the fly.
There are many rewriting steps, but the main ones are:
As a summary, we slowly move from an abstract coding of the program to a concrete one.
Please notice that most peoples working on large projects or building libraries should be writing functions that work at the first stages of the low level compiling mechanism, in order to dynamically check and optimize the user program. This kind of functions typically makes things such as turning 2*x to x+x.
The program coding model at the beginning of the low level compiling mechanism is very interesting since it very basic, yet plateform independent (just like the Pascal Pcode or the Java byte code).
The last stages of the low level compiling mechanism should be extended only by optimizing dedicated libraries, not by application libraries. If you plan to such a library, please keep in touch with Hubert Tonneau since the rules in the low level compiling mechanism may change in the next few months to better meet the needs of optimizing functions (the Pliant code optimizer is yet far from being a state of the art optimizer).