Lab 2 - Compiler Infrastructure and Testing

This lab aims at preparing you for Homework 2. Specifically, this lab will cover:

Prepare Stencil

  1. Accept the assignment on Github Classroom here.

  2. In shell, run dune build. This repo is identical to the one for HW2, except this README file.

Directory Layout

Working with Assembly

It is easy to forget the definition of directive, operand, and register. Don't worry, there are three convenient ways to remind yourself their definitions.

(Assuming that you are editing ./lib/compile.ml)

Task: From lib/compile.ml/, try all these four approaches of finding the definition of directive.

Writing tests

When you want to test if the result of a program (e.g. (add1 42)) is as expected (e.g. 42), you should

Some programs are expected to result in an error instead of a value. For example, (char->num 42) should result in an error because 42 is not a char. To test this behavior, you should use an *.err file instead of *.out. The content of *.err files are ignored but you are free to put descriptions of why an error should occur there. (You are not require to make use of *.err files in HW2, as we will not test your implementations against "bad" programs.)

When you want to test only if the interpreter and the compiler agree on the result of a program (e.g. (char->num #\newline)), you may leave out the *.out file. (For HW2, the ASCII encoding is required, so the result must be 10. However, there is nothing wrong with using other encodings as long as (num->char (char->num c)) = c holds for all c and all implementations agree on the encoding)

Task: Choose 2 unary operator and 1 constants (i.e. num, bool, and char), and write a test for each of them (3 tests in total).

Working with the Compiler Runtime

Updating the compiler typically involves modifying ./lib/compile.ml. If you introduce a new kind of data (e.g. HW2, where char is introduced), you will also need to modify ./lib/runtime/runtime.c because print_value needs to know how to print the new data.

Note: You might want to write some tests before changing interpreters and compilers.

Task: Change the compiler such that both booleans and numbers use 1 bit for tagging. Boolean are tagged with 0 and numbers are tagged with 1.

Task: Change the interpreter and the compiler such that the boolean true is printed as #t and the boolean false is printed as #f

Task: Implement bool?

Running the Interpreter and the Compiler manually

Assume there is a program.lisp file containts the following code

(add1 41)

To interprete this program,

dune exec -- bin/interp.exe program.lisp 

To compile this program, (assuming that there is no file or directory named out in the current directory)

dune exec -- bin/compile.exe program.lisp ./out/
./out/program.lisp.exe 

There will be three files in ./out/

Task: Interprete the 3 testing programs that you just wrote.

Task: Compile and run the 3 testing programs that you just wrote.