Yet Another Useless Language Part 4 — Compiler

This is the fourth part of the YAUL series. For your convenience you can find other parts in the table of contents in Part 1 — Introduction

Today we are going to take a look at the basics of compilation process.

AST

In order to execute code we are going to parse source code using PLY and generate AST. Next, we are going to parse this AST and generate lambdas. Let’s take the following code:

This code does nothing important, however, it uses almost all features of our language. The AST for this application is:

Lots of code for such a simple application. However, if you try to decipher this structure you will see that it indeed represents whole application.

We will generate this AST using PLY. Having this AST we could easily try to execute it by writing custom processor — we would need to track instruction pointer, variables’ states, call stacks and all that stuff. But in order to generate lambdas we will use visitor pattern to traverse the tree and generate the code.

Compiler application

Let’s write some C# code. We start with the following:

This simple application accepts one command line argument — the path to the source code file. After reading the filwe, we call Parser‘s method to parse the code (we will implement Parser later in this series), next we call Compiler‘s methods to create lambdas and execute the script. Here is the Compiler class:

Pretty simple. We create ExpressionGenerator and execute Accept method. ExpressionGenerator visitor is pretty simple:

Our visitor will be used to hold some of parsed instructions. We will use it to maintain local variables, nested blocks, labels etc.

Next time we are going to handle variables declarations and assignments.