Project 4: A type checker

In this project, you will write a type checker for Jay in ML, essentially an ML version of the program we saw in class on Feb 6.

1. Setup

In a directory for this class and project, copy the files from

/cslab/class/cs365/proj4

This includes a variety of files:

errormsg.sml
jay.grm.sig
jay.grm.sml
jay.lex.sml
jay.sml
parse.sml
sources.cm

These, above, provide some some base code for the interpreter, mainly implementing the parser. You won't be modifying these.

absyn.sml

This contains the datatypes for the representation of the abstract syntax.

prettyPrint.sml

This contains the code for a pretty-printer, to give an example of how the datatypes are used.

typeCheck.sml

This is where the code for the interpreter will go, and this is the main file you will be modifying.

test-t.sml
test-p.sml

These test the type-checker and pretty-printer, respectively.

euclid.jay
badtypes.jay

These are sample Jay programs.

2. Writing the type checker

The file typeCheck.sml contains the code for the type-checker, which you need to finish. This will help you understand what's going on in the type checker and what needs to be done.

First, there is the datatype tyty, and this corresponds to the Type enumeration in the Java version. Then there are a handful of utility functions, like converting a typeName from the abstract syntax to a tyty, and the function getOpType which gives a 3-tuple of tytys-- the two operand types and result types of the various operators.

The type map is implemented as a list of string, tyty pairs. The function getType looks up the type of an identifier in the type map.

The work is done by the verify functions, starting with verifyProg, which takes a program and returns the number of type errors. Along the way, the specific type errors are displayed. Since a program is a list of declarations and a list of statements, we use the declarations to generate the type map, and then pass the type map to the functions that verify the statements.

1. verifyDeclIds. Finish the function verifyDeclIds; replace (0, []) with something that appropriately generates the number of errors and revised typemap in the case where the first id on the list of identifiers is undefined in the type map so far.

2. verifyStmt(Assign(targ, expr), tm). Finish the function to verify assignment statements. Be sure to catch type errors of an undeclared target and a type mismatch between the expression and the target.

3. verifyStmt(Loop(guard, body), tm). Using the verify function for conditionals (immediately above), write the verify function for loops. Be sure to catch the type error of a non-boolean guard.

4. verifyExpr(BinExpr(e1, opp, e2), tm) (the hard one). The function verifyExpression must do two things-- catch and record errors, and infer a type. Thus it must return a tuple: an int and a tyty. Using the verify functions for other expressions (especially unary expressions) as examples, write the verify function for binary expressions. Be sure to catch the type error of mismatched operands. Here the function getOpType will be of use. Note that ML allows you to use equals to compare tuples, as long as the tuple components can be compared using equals.

3. Testing

Remember that in the file test-t.sml, the line

runTests(["euclid.jay", "badtypes.jay"])

executes all the test files in the list (in this case, just a.mex). To add (or remove) tests, just edit this line. Then to run the type-checker on the listed test files, just enter at the command line

sml < test-t.sml

ML will spit out a verbose list of processing information, but you'll also see the result-- or a list of your mistakes.

You should also write testfiles of your own and test them.

4. Turn-in

Copy your typeCheck.sml to

/cslab/class/cs365/turnin/proj4/xxxxxx

where "xxxxxx" is [andy|david|tyler|yelemis]. I will grade your project by running it against a collection of test files.

DUE: Wednesday, Feb 20, 5:00 pm.


Thomas VanDrunen
Last modified: Tue Feb 12 10:19:58 CST 2008