CS 3520 Homework 8   - Due November 5

Exercise 8.1, Interpreting an Interpreter

Your task is to implement an interepreter using the language implemented in hw8.scm. More precisely, modify the definition of interp-example in hw8.scm so that it contains an interpreter implementation.

NOTE: see below for an alterative to using hw8.scm.

The grammar for the langauge you must interpret is as follows:

  <exp> = <num>                     ; literal
        | <id>                      ; refers to a lam binding
        | (lam (id) <exp>)          ; procedure of 1 argument
        | (<exp> <exp>)             ; function call with 1 argument
        | <exp> + <exp>             ; addition
        | <exp> - <exp>             ; subtraction
        | ifzero <exp> <exp> <exp>  ; branch on zero

The evaluation rules are the usual ones. There are two kinds of values (numbers and procedures), identifiers are lexically scoped, etc.

For simplicity, we ignore the problem of parsing. Instead, we represent expressions by directly instantiating the exp datatype:

  exp = (var num)
      or (lit num)
      or (lam num exp)
      or (app exp exp)
      or (plus exp exp)
      or (minus exp exp)
      or (ifz exp exp exp)

Note that, since our implementation language does not provide symbols, we use numbers for identifiers. There is no confusion between literal numbers and identifier numbers, because the constructors distinguish them.

For example, to write down a program that computes 3+5, we write:

(plus (lit 3) (lit 5))

To compute the same result using an add-5 procedure, we could write

(app (lam 17 (plus (var 17) (lit 5))) (lit 3))

which is analogous to the Scheme expression ((lambda (x) (+ x 5)) 3).

The given hw8.scm includes a complex example:

     (app (lam 19 (app (app (var 19) (var 19))
                       (lit 10)))
          (lam 18
               (lam 17 (ifz (var 17) 
                            (lit 0)
                            (plus (var 17)
                                  (app (app (var 18) (var 18))
                                       (minus (var 17) (lit 1))))))))

This expression conputes the sum of numbers from 10 to 1. It is equivalent to the Scheme program

(letrec ([sum (lambda (n)
                (if (zero? n)
                    (+ n (sum (- n 1)))))])
  (sum 10))

except that it's written without letrec or let, which means it's closer to the Scheme program

((lambda (sum) ((sum sum) 10))
 (lambda (sum)
   (lambda (n)
     (if (zero? n)
	 (+ n ((sum sum) (- n 1)))))))

Note, however, that you do not necessarily need to write programs like the one above. Your task is to implement the interpreter, and the graders will write test programs like the ones above. However, you may find that writing your own test programs can be helpful in debugging your interpreter.

Alternative Assignment

Instead of handing in a hw8.scm file, you can choose to implement the interepreter in OCaml, and hand in a completed hw8.ml. OCaml provides better error messages than the type checker implemented by hw8.scm, but its syntax is different.

For this alternative assignment, start with hw8.ml.

Last update: Wednesday, October 30th, 2002