Start with the F1WAE interpreter for deferred substitution, and extend the implementation to support any number of arguments to a function (including zero), and any number of arguments (including zero) in a function application:

<FunDef> = {deffun {<id> <id>*} <FnWAE>} <FnWAE> = <number> | {+ <FnWAE> <FnWAE>} | {- <FnWAE> <FnWAE>} | {with {<id> <FnWAE>} <FnWAE>} | <id> | {<id> <FnWAE>*}

Since you must change the `F1WAE` datatype, and since different people may change it in different ways, you must provide a `parse` function. It must accept a quoted expression and produce an `FnWAE` value. For parsing, assume that any symbol other than `'+`, `'-`, or `'with` can be a function name for a function call. Also, you must provide a `parse-defn` function that takes one (quoted) `deffun` form and produces a `FunDef` value.

At run-time, a new error is now possible: function application with the wrong number of arguments. Your `interp-expr` function should detect the mismatch and report an error that includes the words "wrong arity".

If a free variable is detected, your interpreter must report an error that includes the words "free variable".

If a use of an un-defined function is detected, your interpreter must report an error that includes the words "undefined function".

Some examples:

(test (interp-expr (parse '{f 1 2}) (list (parse-defn '{deffun {f x y} {+ x y}}))) 3) (test (interp-expr (parse '{+ {f} {f}}) (list (parse-defn '{deffun {f} 5}))) 10) (test/exn (interp-expr (parse '{f 1}) (list (parse-defn '{deffun {f x y} {+ x y}}))) "wrong arity")

Your interpreter must evaluate all of the argument expressions in an application expressions before signaling any arity errors. For example:

(test/exn (interp-expr (parse '{f x}) (list (parse-defn '{deffun {f a b c} c}))) "free variable")

Similarly, your interpreter must check to see if the function position of an application is legtimate before evaluating the arguments. For example:

(test/exn (interp-expr (parse '{f x}) (list (parse-defn '{deffun {g a b c} c}))) "undefined function")

A function would be ill-defined if two of its argument `<id>`s are the same. To prevent this problem, your `parse-defn` function should detect this problem and reports a "bad syntax" error. For example, `(parse-defn '{deffun {f x x} x})` should report a "bad syntax" error, while `(parse-defn '{deffun {f x y} x})` should produce a `FunDef` value.

If the list of definitions contains multiple definitions for the same function, use just the first one (ignoring the others).

Otherwise, assume that the input to your parser is a well-formed program.

Add `if0`, a conditional expression. It has three subexpressions:

<FnWAE> = ... | {if0 FnWAE FnWAE FnWAE}

Evaluating an `if0` expression evaluates the first subexpression; if it produces `0`, then the result of the entire expression is the result of the second subexpression. Otherwise, the result is the result of the third subexpression.

Examples:

(test (interp-expr (parse '{if0 0 1 2}) '()) 1) (test (interp-expr (parse '{if0 1 2 3}) '()) 3)

Implement, in the FnWAE language (without any extensions), a predicate `neg?` that determines if an integer is negative.

{deffun {neg? x} ...}

It must return either `0` (if the input is negative), or `1` (if not).

Implement, in the FnWAE language (without any extensions), a function `mult` that computes the product of two integers.

{deffun {mult x y} ...}

The final program you handin should:

- have definitions of
`parse`and`parse-defn`that accept quoted versions of`FnWAE`and`FunDef`respectively (as above) and return the corresponding trees. - have a definition of
`interp-expr`with the contract`FnWAE (listof FunDef) -> Number`(it will be called with the result of your parsers) that supports both`if0`and multi-arity functions. - have a PLAI-level definition of
`mult-and-neg-deffuns`that is bound to a list of (unparsed) deffuns that contains both`neg?`and`mult`as well as any helper functions you wish.(define mult-and-neg-deffuns (list `{deffun {neg? x} ...} `{deffun {mult x y} ...} ;; other deffuns okay, too ))

- not have any unused code (i.e., no
`subst`). - have the 8 rules from the Provost's website (see the homework 1 assignment for more details).

Last update: Thursday, October 15th, 2015robby@eecs.northwestern.edu |