Assignment 1, csc431, Spring 2018
1 Goal
2 Repo Creation
3 Language
4 Compilation Strategy
5 Deliverables
6 Testing Plan
7.0.0.7

Assignment 1, csc431, Spring 2018

1 Goal

Develop a compiler for a simple language with straight-line variable declarations.

2 Repo Creation

https://classroom.github.com/g/hDXd8I8-

3 Language

Our language for the first milestone will be a (very very small) subset of the "Mini" language described by Professor Keen in his course materials. Here’s the EBNF for our restricted language:

 

program

 ::= 

mainfunction

 

mainfunction

 ::= 

fun main ( ) int { declaration* assignment* ret }

 

declaration

 ::= 

int id-list ;

 

id-list

 ::= 

id {, id}*

 

assignment

 ::= 

id = expression ;

 

ret

 ::= 

return expression ;

 

expression

 ::= 

term {{+  |  -} term}*

 

term

 ::= 

unary {{*  |  /} unary}*

 

unary

 ::= 

-* factor

 

factor

 ::= 

( expression )  |  id  |  number

This grammar assumes existing definitions for the id and number nonterminals.

So, for instance, you might write

fun main () int {

  int w,x,y,z;

  x = 3+4;

  y = x+(4/3);

  return x+y;

 }

Since this syntax is a subset of the "Mini" language, I would encourage you to use the parser provided for that language. It can produce an AST directly if you’re working in one of the languages that Antlr supports, and can generate JSON if you’re not.

For this assignment, we’re assuming a "C"-like semantics for arithmetic, where division denotes integer division, and overflows lead to unspecified behavior.

It’s an error to use an uninitialized or undeclared variable, and your program must signal an error in these cases.

It’s fine to declare a variable more than once in the same block, as long as it’s given the same type each time.

4 Compilation Strategy

Your compiler should follow these steps:

  1. Parse, to produce an AST,

  2. check that all used variables are declared,

  3. check that no variables are used before initialization,

  4. convert to A-normal form as discussed in lecture,

  5. generate assembly, and

  6. compile and link the assembly with the given C wrapper.

5 Deliverables

Your repo should contain a README indicating how to compile the compiler. This should produce a "consieuten" executable.

After this, calling

consieuten <file.co>

should produce a compiled executable named "a.out" in the current directory.

6 Testing Plan

For the purposes of evaluation, we’re breaking down the functionality into six separate "tiers". Each one is worth a fraction of the overall points for correctness, as follows:

  1. (4 pts) return a constant: return 8;

  2. (4 pts) return a simple binop, e.g. return 3+8;, return 18 / 5;, etc.

  3. (2 pts) bindings for constants, e.g.

    x = 3;

    y = 4;

    return x+y;

  4. (2 pts) bindings to simple binops, e.g.

    a = 3;

    b = a + 4;

    c = b/a;

    return a*c;

  5. (2 pts) nested binops, all correct programs, e.g.

    a = 6+(8/2);

    b = a + (a*7) + 8;

    return a+(2*b);

  6. (2 pts) all error checking