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.
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.
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 tyty
s--
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.
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.
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.