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.pyfile. Any function decorated with@builtinwill be added to the globally-definedBUILTINSlist.
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-inevalprocedure.
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:
argsis a Pair, which has a.firstand.restsimilar to a Linked List. Think about how you would put the values of a Linked List into a list. - If
procedure.expect_envisTrue, then add the current environmentenvas the last argument to this Python list. - Call
procedure.py_funcon all of those arguments using*argsnotation (f(1, 2, 3)is equivalent tof(*[1, 2, 3])). - If calling the function results in a
TypeErrorexception being raised, then the wrong number of arguments were passed. Use atry/exceptblock to intercept the exception and raise aSchemeErrorwith the message'incorrect number of arguments'. - Otherwise,
scheme_applyshould 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