EECS 321 Programming Languages: Homework X

Part 0 – Replacement

This homework is optional. It will be used to replace the grade of your lowest homework (if you hand it in).

Part 1 – XCFAE and Errors

For this part, you must eliminate all calls to error in your interpreter. You'll be implementing an interpreter for XCFAE:

 XCFAE ::= {+ XCFAE XCFAE}
         | {- XCFAE XCFAE}
         | number
         | {with {ID XCFAE} XCFAE}
         | identifier
         | {if0 XCFAE XCFAE XCFAE}
         | {fun {x x ...} XCFAE}
         | {XCFAE XCFAE XCFAE ...} ;; application expressions

As in Homework 5 your parser must handle multi-argument functions (and applications) and with expressions.

There are three different kinds of errors that can occur (at runtime) in this language and for each error in the input program, your interpreter must return a string that includes one of the following phrases:

free identifier
application expected procedure
numeric operation expected number

As in past assignments, you must signal those errors correctly, but this time you may not call PLAI's error function or anything else that aborts the computation (either by calling error or by calling something else that might raise an exception or otherwise abort).

Instead, you must change you interpreter so that it returns the error string as the final result of interpretation when an error happens. Note that you must still properly handle all of the same error situations and must get the errors checked in the right order.

All of the old test cases you have (especially those about error ordering) are relevant, but so are some new ones. To help stimulate your thinking, here is an advanced test case:

    (test (interp-expr (parse `{+ x 
                                  {with {loopX
                                         {fun {loopX loopX}
                                              {loopX loopX}}}
                                        {loopX loopX}}}))
          "free identifier")
You don't have to literally return that string, "free identifier: x" would also be okay.

In general, your interpreter must behave exactly the same as your earlier implementation of this language, except that it returns strings in error situations instead of raising exceptions.

Part 2 – Pairs

Much like in Homework 5 where you demonstrated that FAE has enough power to represent numbers without actually using numbers, the programming language also has enough power to define a pairing operator (something like a simplified version of cons; simplified in that you do not have to implement cons?).

Define a pair function that accept two arguments and returns a value. Define fst and snd functions that accept whatever pair produces and return the original arguments passed to pair. Note that pairs can be paired (not just numbers).

For example,

{with {pair ...}
  {with {fst ...}
    {with {snd ...}
      {fst {pair 1 2}}}}}
 => 1
Simlarly, with the appropriate with wrappers, you should get this:
{snd {pair 1 2}} => 2
{snd {fst {pair {pair 1 2} {pair 3 4}}}} => 2
{with {p {pair 1 2}}
  {+ {fst p} {snd p}}} => 3
{with {p {pair {fun {x} {+ x 1}} 2}}
  {{fst p} {snd p}}} => 3

Hint: there are only two choices of values that you might use to represent pairs, numbers and functions. While numbers are plentiful enough, a pair of functions is going to be difficult to turn into a number. So, if functions represent pairs, then consider what the function has to do to be able to act like a pair: it has to be able to return the first and the second pieces of the original pair.

Part 3 – Lists & Summation

Once you have pairs, you can use them to build lists. Specifically, a list is either the number 0 (representing an empty list), or a pair of a number and another list. Use this data definition and build a summation function that takes one of these lists and returns the sum of the values in the list.

For example,

{with {pair ...}
  {with {fst ...}
    {with {snd ...}
      {with {sum ...}
        {sum 0}}}}}  => 0
and, again, with the same with expressions wrapped around these calls:
{sum {pair 1 0}} => 1
{sum {pair 1 {pair 2 {pair 3 0}}}} => 6

Part N – Handin instructions

Provide a definition of interp-expr : XCFAE -> number or string or 'procedure, as above. Also provide a definition of parse : sexpression -> XCFAE, as above.

Bind your definitions of pair, fst, snd, and sum to PLAI-level definitions of the same name, e.g.,

(define pair `{fun {a b} ...})
... etc
Note that these should each be complete XCFAE programs; if you wish, use quasiquote and unquote (see the parsing lecture notes for more on quasiquote and unquote) to avoid duplicating code.


Last update: Thursday, March 20th, 2014
robby@eecs.northwestern.edu