# Implement an interpreter for simple recursive programs. The # following syntax is taken unchanged from ‹t1_while›: # # • one line = one statement (no exceptions), # • blocks are delimited by indentation (1–5 spaces), # • there are following statement types: # ◦ assignment, # ◦ ‹if› statement. # # There are also two important changes: # # 1. The right-hand side of an assignment can be a function call, in # addition to a built-in operation, written as: # # name₀ = func name₁ name₂ … nameₙ # # 2. There is a new statement type, «function definition», which can # only appear in the top-level scope (and is the only statement # than can appear there), of the form: # # def funcname name₁ name₂ … nameₙ # # All functions can call all other functions, regardless of the # order in which they are defined in the source. Function names # follow the same rules as variable names. # # Semantics change in the following way: # # • all variables are «local» to the function in which they are # used (declarations are still not needed), # • the result of a function call is the value of a variable with # the same name, i.e. in function ‹foo›, the statement ‹foo = 7› # sets the return value to ‹7› (but does not terminate the # function), # • the namespaces for variables and for functions are separate; # operation names (‹add›, ‹and›, …) must not be used for # functions (but they can be used for variables). # # Like ‹if›, a ‹def› statement is followed by a body, indented by a # single space. Other restrictions on blocks remain the same as in # ‹t1_while›. # # Example program: # # def fib n # one = 1 # two = 2 # fib = 1 # rec = gt n two # if rec # n_1 = sub n one # n_2 = sub n two # fib_1 = fib n_1 # fib_2 = fib n_2 # fib = add fib_1 fib_2 # # Write a function ‹do_rec› which takes a recursive program (as a # string), a function name, and an arbitrary number of integers. The # result is the return value of the function invoked, or a tuple of # (line number, error string) in case the program fails. Return the # first error in this order (within a group, return the number of # the first line with an error): # # 1. syntax errors (including attempts to redefine a function), # 2. use of an undefined function or bad argument count, # 3. runtime errors (division by zero).