CS 3520 Homework 5   - Due October 5

This homework is due October 5, 8:00 AM.

Exercise 5.1, Multiple Recursive Functions

Start with an interpreter from HW 4.1 that supports multiple arguments to functions and function calls, and extend the implementation to support if0 and multiple mutually recursive bindings:

  <RCFAE> = <number>
          | {+ <RCFAE> <RCFAE>}
          | {- <RCFAE> <RCFAE>}
          | <id>
          | {fun {<id>*} <RCFAE>}
          | {<RCFAE> <RCFAE>*}
          | {if0 <RCFAE> <RCFAE> <RCFAE>}
          | {rec {{<id> <RCFAE>}*} <RCFAE>}

Assume that each argument <id> is distinct for a rec expression.

As in HW 4, provide a parse function and a interp-expr function:

  ;; All the tests from HW 4.1, plus..
  (test (interp-expr (parse '{if0 0 1 2}))
        1)
  (test (interp-expr (parse '{if0 {+ 1 0} 1 2}))
        2)
  (test (interp-expr (parse '{if0 0 {fun {x} {+ x 1}} {fun {x} {+ x 2}}}))
        'function)
  (test (interp-expr (parse '{{if0 0 {fun {x} {+ x 1}} {fun {x} {+ x 2}}} 32}))
        33)
  (test (interp-expr (parse '{rec {{even {fun {x}
                                              {if0 x
                                                   1
                                                   {odd {- x 1}}}}}
                                   {odd {fun {x}
                                             {if0 x
                                                  0
                                                  {even {- x 1}}}}}}
                                {even 10}}))
        1)
  (test (interp-expr (parse '{rec {{f {fun {x} {h x}}}
                                   {g {fun {x} {f x}}}
                                   {h {fun {x} {g x}}}}
                               f}))
        'function)

Exercise 5.2, Extra Credit: Compiling Recursive Functions

This exercise is optional, for extra credit.

Implement a compile-expr function that takes an RCFAE and produces a CRCFAE, which is like RCFAE except that all binding names are removed, and each bound identifier is replaced by a number. Since a fun can take any number of arguments, a compiled fun must record the number of expected arguments:

  <CRCFAE> = <number>
           | {+ <CRCFAE> <CRCFAE>}
           | {- <CRCFAE> <CRCFAE>}
           | {at <number>}
           | {fun <number> <RCFAE>}
           | {<CRCFAE> <CRCFAE>*}
           | {if0 <CRCFAE> <CRCFAE> <CRCFAE>}
           | {rec {<RCFAE>*} <RCFAE>}

(You do not need a parser for CRCFAEs. The above grammar is merely to clarify the content of a compiled expression.)

In addition to compile-expr, provide cinterp-expr, which interprets the result of compile-expr and produces a number or 'function:

  (test (cinterp-expr (compile-expr (parse '{{fun {x y} {- y x}} 10 12})))
        2)
  (test (cinterp-expr (compile-expr (parse '{fun {} 12})))
        'function)
  ;; etc.


Last update: Wednesday, November 23rd, 2005
mflatt@cs.utah.edu