CS 224 Project - Part 3

In this part of the project you will implement function calls that use pass by value.

The Environment

We will modify the environment to include function definitions as well as numeric variables.

   
data Value = Val Integer | Fun Function

We can then store the function definitions in the environment using addfuncs defined as:

    addfuncs :: [Function] -> Dictionary.T String Value -> Dictionary.T String Value
  addfuncs [] dict = dict
  addfuncs (Function f args body : fs) dict =
        addfuncs fs (Dictionary.insert (f,Fun(Function f args body)) dict)

Evaluating Expressions

We must add a case to the value function to handle function calls.  To evaluate a function you need to create a new environment for that function.  That new environment will contain any locally defined functions as well as the formal parameters for the function. 

Suppose we are translating the code:

   
func f(x:val y:val)
        z := 3;
        return x+y+z;
  endfunc
  a := 5;
  write f(2*a 6);

In the main program we evaluate the expression f(2*a 6).  In evaluating this expression, we first have to lookup the function definition in the environment.   Then we create a new environment which will contain variables x, with a value of 10, and y with a value of 6.  This is performed by evaluating the actual arguments, 2*a and 6, in the callers environment and inserting those values in the new environment.

We then execute the body of the function using this new environment, returning the result.

Be sure to test for error conditions when trying to evaluate a function which is not defined.

The Return Statement

We can assume that a function will always have a return which will return a result.  We will treat a return statement very much like a write statement in that a value will be added to the list of integers produced as output by statement execution. The only difference is that there will only be one value in this list and that any statements after the return will not be executed.

Therefore in the evaluation of a function call, the return result is extracted after execution of the body of the function by taking the last value from the list of output values.

You will need to implement the Return case for the exec function.

The following main program includes placing the function definitions into the environment.

        -- The main program executes the interpreter and runs the program
       
main =
           
do putStr "Filename: "
            name <-
getLine
           
contents <- readFile name
           
putStr "Input: "
           
input <- getLine
            putStr (show
(run (fromString contents) (fromString input)))

        run :: Program-> InputList -> [Integer]
        run (Program funcs stmts) (Input input) =
           
fst
(exec stmts (addfuncs funcs Dictionary.empty) input)

Send me your modified zipped project in the dropbox in BlackBoard.