Grades and deadlines

The big idea

In the previous lab, you were given working code for a complete AST, and were asked to write the code which would generate the AST from a parse tree in your language. The interpreter just did scanning, parsing, AST generation (semantic analysis), and then called exec() on the root AST node.

In this lab, almost all of that will stay the same: scanning, parsing, and AST generation.

But what will be completely different is what happens with the AST itself. The Stmt and Expr interfaces both have a new method compile() which needs to be implemented in every AST node. The job of each compile method is to output LLVM IR code corresponding to whatever that AST node does, and to recursively compile any child nodes.

A lot of the AST compile() methods have already been filled in for you, because they are doing the same things as you already got working in the previous two compiler labs.

Your focus in this lab will be on three tasks:

There is a lot less code to write in this lab compared to some previous labs, but the code is getting more intricate and tricky. So you might have to think and plan more than before. Fortunately, this is the most fun part of programming and the reason computer science is a thing!

Getting started: files

Start by downloading the starter files. Running this command will create a new directory lab3.2:

git clone https://github.com/si413usna/startlab.git -b lab3.2 lab3.2

As usual, you should see an empty lab3.2.yml file for you to fill in, plus a pom.xml file for maven, and a src/ directory with all the starter code.

Remember that we said the scanning, parsing, and AST generation will work exactly the same as in the previous lab?

Well, that corresponds to you copying these three files from the previous lab, into the new lab:

After getting all the files set up, try running your compiler on a simple program (with no variables, if statements, or loops) and testing the resulting .ll code using lli or clang. It should work!

Remember, if you have some example program in example.prog, you can test your compiler like this on the command line:

./run.sh example.prog example.ll
lli example.ll

Task 1: Write your compiler

Most of your work will be in Compiler.java, Expr.java, and Stmt.java. Concretely, your goal is to fill in the missing compile() methods. Each missing method in the starter code has a // TODO comment to help you spot them.

You need to basically implement variables and control structures, and that’s it! Remember what we have been doing recently in class: allocating memory (for variable storage), and implementing branching (for if statements and while loops).

Now you will need to work at one more level of abstraction, writing Java code that produces LLVM code which deals with memory allocation and branching.

This is all the guidance we are going to give here! Look through the code that you are given in Compiler.java, Expr.java, and Stmt.java to help get you started.

You are ready for this challenge. Good luck!

Extra challenge

To make your compiler extra awesome, try the following two enhancements: