Problem 2 (150pts): @builtin
To be able to call built-in procedures, such as +
, you need to complete the BuiltinProcedure
case within the scheme_apply
function in scheme_eval_apply.py
. Built-in procedures are applied by calling a corresponding Python function that implements the procedure.
To see a list of all Scheme built-in procedures used in the project, look in the
scheme_builtins.py
file. Any function decorated with@builtin
will be added to the globally-definedBUILTINS
list.
A BuiltinProcedure
has two instance attributes:
py_func
: the Python function that implements the built-in Scheme procedure.expect_env
: a Boolean flag that indicates whether or not this built-in procedure will expect the current environment to be passed in as the last argument. The environment is required, for instance, to implement the built-ineval
procedure.
scheme_apply
takes the procedure
object, a list of argument values, and the current environment. args
is a Scheme list represented as a Pair
object or nil
. Your implementation should do the following:
- Convert the Scheme list to a Python list of arguments. Hint:
args
is a Pair, which has a.first
and.rest
similar to a Linked List. Think about how you would put the values of a Linked List into a list. - If
procedure.expect_env
isTrue
, then add the current environmentenv
as the last argument to this Python list. - Call
procedure.py_func
on all of those arguments using*args
notation (f(1, 2, 3)
is equivalent tof(*[1, 2, 3])
). - If calling the function results in a
TypeError
exception being raised, then the wrong number of arguments were passed. Use atry
/except
block to intercept the exception and raise aSchemeError
with the message'incorrect number of arguments'
. - Otherwise,
scheme_apply
should return the value obtained by callingprocedure.py_func
Use Ok to unlock and test your code:
python ok -q 02 -u
python ok -q 02