CS170

Project Assignment #4

TARGET DATE : Thursday 4/23.


If you have not already done so, be sure that your program evaluates all levels of function calls. It's a matter of having your function "eval" call itself at the correct times. In addition, for the rest of the project, be sure to continue to always evaluate arguments before evaluating a function. For example, (car (cdr '(a b c))) should return b, rather than cdr. (Of course, (car '(cdr (a b c))) WILL return cdr because the quote should continue to suppress evaluation.)

This assignment sets up the necessary preliminaries for function definition. We will concentrate here on simply defining symbols to have values, which is much the same as defining constant functions. This is analogous to assigning values to variables in imperative languages.

There are two parts to this.

Some New Functions

Add the following built-in Scheme functions to your interpreter. Some comments are added for functions that you're not familiar with or that need some clarification: cond is, as you know, used for flow of control in defining Scheme functions, so it is extremely important that it works properly. (If you want to add the if construct as well, please do.)

Binding of Values to Symbols

The Scheme syntax for binding a value to a symbol is,
   (define < symbol-name > < value >)
For example, if you type the following into your interpreter,
   (define name '(joan q public))
the value (joan q public) is now bound to the symbol name. Thus if you subsequently type the following into your interpreter,
   name
the interpreter should respond with the list (joan q public). You have bound the "value" (joan q public) to the "variable" name. It is therefore now possible for the interpreter to evaluate symbols that have been bound to values. Eval's main new job in this assignment is to evaluate symbols.

This can be implemented in a number of ways. The simplest one is probably the following. Define a global association list in your program that contains a list of symbol-value pairs. It should be an empty list when your program starts. We will refer to this list as the referencing environment. Here's how it is used:

(1) When a definition is made using define, we will ADD to the referencing environment. For example, assuming the referencing environment was (), the Scheme form,
   (define name '(joan q public))
should have the following effect. The interpreter makes a pair out of the symbol name and the list (joan q public). The pair would look like (name (joan q public)). It then "conses" this onto the referencing environment, and the result becomes the new referencing environment. That is, the new referencing environment would be in this case ((name (joan q public))). Note that all of this could be regarded as a "side effect" to the "function call" to define. The "function" define should also return a value, namely the name it is defining. In this case, define should return the symbol name. The important thing, though, is its side effect that changes the referencing environment.

When subsequent definitions are made, MORE things are added to the referencing environment. Suppose we make the definition,
  (define clark (cdr '(university main street worcester)))
Then the new referencing environment should be,
  ((clark (main street worcester)) (name (joan q public)))
(2) When eval comes across a symbol, it should try to "evaluate" it. How? It can use the assoc function with the given atom as the first argument and the referencing environment as the second. This gives the pair binding the name to a value. Then eval should return the value belonging to that name. Thus, as mentioned above, given the previous definitions,
   name
evaluates to
   (joan q public)
and
   clark
evaluates to
   (main street worcester)
But also, symbols like name and clark can appear in expressions. For example,
   (cons (car (cdr (cdr name))) (cdr clark))
evaluates to
   (public street worcester)
NOTE: There's not a lot of code to write here! For the referencing environment, the two main necessary tools are: cons, for implementing define, and assoc, for evaluating symbols.

Testing: Here is a file to test your code. If you run it with the command "./scheme < input.txt", here is what you should expect (something a lot like it, anyway.

Submit the usual file here.

Back to CS170 Assignments.