In this part of the project you will implement function calls that use pass by value.
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)
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.
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
run :: Program
-> InputList -> [Integer]Send me your modified zipped project in the dropbox in BlackBoard.