On this page:
2.2.1 Assignment Summary
2.2.2 Reading
2.2.3 Exercises
8.10

2.2 Milestone 1: Abstracting x64 Boilerplate

2.2.1 Assignment Summary

The goal of this assignment is to introduce the process of designing, implementing, and reasoning about a compiler. In this assignment, you will implement a small abstraction layer on top of x64, called Paren-x64 v1, which allows easily writing a subset of x64 programs while ignoring some of the boilerplate and operating-system-specific details.

Unit test appropriately, with tests for both failure and success for each compiler pass. You should look into the RackUnit: Unit Testing package.

All tests should be inside the special test submodule. See Main and Test Submodules for more details.

There should be a test module for each of the compiler passes next to the implementation of the pass. You can also test the whole compiler pipeline in the compiler.rkt file.

You can use the interrogator to get limited access to the reference solution: https://soft.vub.ac.be/compilers/interrogator?an=a1.

You can use the language diff tool to view differences between languages that aren’t typeset in the book: https://soft.vub.ac.be/compilers/differ.

Assignment Checklist

New passes

2.2.2 Reading

The reading for this milestone is A Compiler Begins with a Language and Abstracting Boilerplate (v1). This milestone description links to the documentation for each exercise in the chapter for convenience, but you are responsible for the reading the entire chapter.

You should read first and work the relevant exercises as you read.

2.2.3 Exercises

Exercise 1: Design and implement the function check-paren-x64-syntax.

It might help to start by writing the template, following the instructions from Appendix: Compiler Design Recipe for templates for language processors.

You can check your implementation against the reference implementation paren-x64-v1?.

You do not have to provide descriptive error as part of this exercise. However, these might be useful for you when debugging your compiler. So make these as precise and descriptive to meet your needs.

Exercise 2: Design and implement the function check-paren-x64-init.

Exercise 3: Design and implement the function check-paren-x64, a validator for Paren-x64 v1. It should just compose check-paren-x64-init and check-paren-x64-syntax, if you’ve implemented both, but could also just be an alias for check-paren-x64-syntax.

Exercise 4: Design and implement the function interp-paren-x64, an interpreter for Paren-x64 v1.

To properly implement arithmetic operations, you need to handle two’s complement arithmetic, which overflows on large positive numbers and underflows on small negative numbers. You may want to use x64-add and x64-mul from cpsc411/compiler-lib.

While testing, you may want to avoid hard-coding values modulo 256, as the interpreter may change in later iterations to return values directly.

You can test your implementation against the reference implementation: interp-paren-x64-v1.

Exercise 5: Design and implement the function generate-x64 which compiles a Paren-x64 v1 represented as an s-expression into an instruction sequence.

Exercise 6: Design and implement the function wrap-x64-run-time which installs the Paren-x64 v1 run-time system.

cpsc411/compiler-lib provides some definitions, such as sys-exit, that are helpful for this.

Note that a similarly named function exists in that library, but will not correctly implement the run-time system for this milestone.

For formatting strings in Racket, you may want to investigate format, ~a, and at-exp.

Exercise 7: Design and implement a Racket function wrap-x64-boilerplate.

Note that a similarly named function exists in the support library, but will not correctly implement the boilerplate this milestone.

Exercise 8: Test your compiler correctness statement by running the same programs through your interpreter and through your compiler and comparing the results.

While testing, you may want to avoid hard-coding values modulo 256, as the run-time system may change in later iterations to return values directly.

You can test your implementation against the reference interpreter, interp-paren-x64-v1.