COSC 3410 Programming Languages

Homework Assignment #8

μ

Due: April 24 @ 11:59PM CDT

Submit: Turn in two Scheme source files called "hw8.scm" and "hw8-test.scm" using the turnin command on the Systems Lab machines.

Work is to be completed in teams of two. Your source file should be in the EoPL dialect ("#lang eopl" at top of file) supported by DrRacket, and should not make use of non-standard features like comment boxes that produce an XML file rather than a flat text .scm file.

At the bottom of your hw8.scm, please include the line:

(provide scan&parse run typecheck)

Your hw8-test.scm file should be a SchemeUnit testsuite, as shown in class. You are only expected to have testcases for typecheck for this assisgnment

Click here to download the in-class demo from Friday, the 17th

The Grammar

Extend your grammar from the previous assignment to include simple type annotations as noted below:

<type-exp>  ::=  int
    int-type-exp ()
   |  bool
    bool-type-exp ()
   |  ( { <type-exp> }*(*) -> <type-exp> )
    proc-type-exp (arg-types result-type)
   |   listof <type-exp>
    list-type-exp (element-type)

A concrete function type would thus look like "(int -> int)" or "(int * int * int -> bool)".

Because type-checking of S-expression operators is more complex than the other primitives, it is necessary to pull the S-expression operators out of the default environment, and to put them back into the grammar. Restore productions to the grammar for the primitives cons, car, cdr, list, null?, and emptylist.

Concrete types are to be added to the grammar in precisely three productions:

<expr>    ::=    ( lambda ( {<identifier> : <type-exp>}* ) <expression> )
    proc-exp (vars types body)
     |    ( letrec ( { ( <type-exp> <identifier> ( lambda ( { <identifier> : <type-exp>}* ) <expression> )) }* ) <expression> )
    letrec-exp (p-result-types p-names b-varss b-vars-types p-bodies letrec-body)
     |  emptylist <type>
    emptylist-exp (element-type)

This language is a close relative to the CHECKED language of EoPL Chapter 7, extensions from exercises 7.5 (multi-args), 7.6 (assignment), and 7.9 (listof types).

Interpreter

With only minimal changes to your interpreter (essentially adding the type fields to the cases clauses for the three modified productions, and then ignoring them,) you should be able to run all previous testcases by adding the appropriate type annotations.

Type Checker

Write a typecheck function that performs type checking on programs and returns either the result type or a type error if one is found.

typecheck : String → Type
Usage: (typecheck "pgm") = t, the resulting type of the program "pgm" or a type error if one is found.

Examples:
> (typecheck "print 5")
int
> (typecheck "if #t then print 5 else print 6")
void
> (typecheck "print (emptylist bool)")
(listof bool)
> (typecheck "print (list (lambda (x:int) (add x 1)) (lambda (y:int) (add y 2)) (lambda (z:int) (add z 3)))"
(listof (int -> int))
> (typecheck "print (letrec ((int fib (lambda (x:int) (if (lesser x 2) x (add (fib (sub x 1)) (fib (sub x 2))))))) (fib 1))"
int

Notes: