CS 4120: Introduction to Compilers
Fall 2013

Programming Assignment 4: Code Generation

due: Friday, November 1

In this assignment you will implement code generation for the Cubex programming language.

Deliverables

Your submission has to have two parts:

The Compiler

As in the previous assignments, this program should take a file name as an argument, read that file, check it and print results to the standard output. The possible results are:

What Code Do I Generate?

We've decided not to burden you with reading a full semantics for the Cubex language. That means that you should implement the "obvious" semantics of statements, expressions, classes, interfaces, et cetera. (We place "obvious" in quotations because the correct mathematical formulation of those semantics is far from obvious!)

The nitty-gritty details: We provided a small library and makefile that you have to use for your compiler. The top-level execution of the compiled Cubex program should be triggered by a call to the function cubex_main() in out.c. (cubex_main() is forward-declared in cubex_main.h). The file out.c should #include exactly three other files: cubex_main.h, cubex_external_functions.h and cubex_lib.h and be otherwise self-contained. The only code allowed to run when a Cubex program is invoked is that in out.c and that in our provided library functions. A compiler breaking this rule intentionally will get a 0.

Your output must adhere to the ANSI C90 standard and generate no warnings when run with -Wall.

Our provided header file will define the following functions:

A few parts of the semantics are less than obvious. The following constraints, along with the above directive to implement the obvious semantics whenever such are available, should give you enough information to complete this assignment. Of course, we reserve the right to add to this list when we discover that we have (inevitably) left something out.

Staging

This assignment will be graded in a staged mode, which means that you can concentrate on some parts of the assignment and leave others out with a predictable loss of points. Our tests will be organized in the following stages (same as PA3), meaning that programs only consist of the things in that stage and the preceding ones:

  1. Statements
  2. Non-generic functions
  3. Generic functions
  4. Non-Generic classes without inheritance
  5. Generic classes without inheritance
  6. Generic classes with single interface inheritance
  7. Generic classes with single interface inheritance + interface method implementations
  8. Generic classes with class inheritance
  9. Generic classes with multiple interface inheritance

Note: Any stage (including stage 1) may contain code related to Iterable, which you have to handle to the fullest extent.

The distribution of tests to stages is identical to PA3:

80% of the tests will test programs in stages 1-3.

10% of the tests will test programs in stages 4 and 5.

10% of the tests will test programs in stages 6-9.

How to submit

You have to include the complete source code in the jar-file, including inputs for any lexer/parser generators you might use. You will need a manifest file (MANIFEST.MF) that sets the classpath. Your manifest file should look like this:

Manifest-Version: 1.0
Class-Path: . antlr-4.1-complete.jar
Main-Class: [your-class-name-here]

The following code snippet does this packaging for you (.g4 is the file extension for ANTLR files).

jar cvfm x3c.jar MANIFEST.MF *.class *.java *.g4

The preamble file

Like the generated code, this file may only #include the library files we provided. You can use it to implement all data structures and functions common to all generated programs.

The text file

Finally, we ask that you submit a small text file (.txt) that contains the following information:

Source control

We recommend that you use some kind of source control. Be aware that your repositories should not be publicly viewable on the web. GitHub offers private repositories for students.

Testing

You should thoroughly test your solutions before turning them in. We provided some basic test examples for you to play with, but keep in mind that we will test your submissions with more complex examples, too. The way a test works is that after running

java -jar x3c.jar x3_test1.x3
make
cat x3_test.in | xargs ./a.out > x3_test1_actual.out

the content of x3_test1_actual.out should be equal to x3_test1.out .