Part 3 - Evaluation - User-Defined Procedures & Special Forms
User-Defined Procedures
Problem 8
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-8-1-pt
def eval_all(expressions, env):
"""Evaluate each expression in the Scheme list EXPRESSIONS in
environment ENV and return the value of the last."""
# BEGIN PROBLEM 8
if expressions is nil:
return None
last_evaled = scheme_eval(expressions.first, env)
next_expr = expressions.second
while next_expr is not nil:
last_evaled = scheme_eval(next_expr.first, env)
next_expr = next_expr.second
return last_evaled
# END PROBLEM 8
Problem 9
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-9-1-pt
def do_lambda_form(expressions, env):
"""Evaluate a lambda form."""
check_form(expressions, 2)
formals = expressions.first
check_formals(formals)
# BEGIN PROBLEM 9
"*** YOUR CODE HERE ***"
body = expressions.second
return LambdaProcedure(formals, body, env)
# END PROBLEM 9
Problem 10
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-10-2-pt
Delimited by comments.
def do_define_form(expressions, env):
"""Evaluate a define form."""
check_form(expressions, 2)
target = expressions.first
if scheme_symbolp(target):
check_form(expressions, 2, 2)
# BEGIN PROBLEM 6
"*** YOUR CODE HERE ***"
if len(expressions.second) == 1:
val = scheme_eval(expressions.second.first, env)
else:
val = scheme_eval(expressions.second, env)
env.define(target, val)
return target
# END PROBLEM 6
elif isinstance(target, Pair) and scheme_symbolp(target.first):
# BEGIN PROBLEM 10
"*** YOUR CODE HERE ***"
name = target.first
formals = target.second
body = expressions.second
val = LambdaProcedure(formals, body, env)
env.define(name, val)
return name
# END PROBLEM 10
else:
bad_target = target.first if isinstance(target, Pair) else target
raise SchemeError('non-symbol: {0}'.format(bad_target))
Problem 11
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-11
def make_child_frame(self, formals, vals):
"""Return a new local frame whose parent is SELF, in which the symbols
in a Scheme list of formal parameters FORMALS are bound to the Scheme
values in the Scheme list VALS. Raise an error if too many or too few
vals are given.
>>> env = create_global_frame()
>>> formals, expressions = read_line('(a b c)'), read_line('(1 2 3)')
>>> env.make_child_frame(formals, expressions)
<{a: 1, b: 2, c: 3} -> <Global Frame>>
"""
# BEGIN PROBLEM 11
"*** YOUR CODE HERE ***"
if len(formals) != len(vals):
raise SchemeError('Error! Differing len of formals & vals!')
child = Frame(self)
if len(formals) == 0:
return child
child.define(formals.first, vals.first)
next_param = formals.second
next_val = vals.second
while next_param is not nil:
child.define(next_param.first, next_val.first)
next_param = next_param.second
next_val = next_val.second
return child
# END PROBLEM 11pyth
Problem 12
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-12-1-pt
def make_call_frame(self, args, env):
"""Make a frame that binds my formal parameters to ARGS, a Scheme list
of values, for a lexically-scoped call evaluated in environment ENV."""
# BEGIN PROBLEM 12
"*** YOUR CODE HERE ***"
return self.env.make_child_frame(self.formals, args)
# END PROBLEM 12
Special Forms
Problem 13
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-13-1-pt
def do_and_form(expressions, env):
"""Evaluate a (short-circuited) and form."""
# BEGIN PROBLEM 13
"*** YOUR CODE HERE ***"
if expressions is nil:
return True
evaled = scheme_eval(expressions.first, env)
if evaled is False:
return evaled
next_expr = expressions.second
while next_expr is not nil:
evaled = scheme_eval(next_expr.first, env)
if evaled is False:
return evaled
next_expr = next_expr.second
return evaled
# END PROBLEM 13
def do_or_form(expressions, env):
"""Evaluate a (short-circuited) or form."""
# BEGIN PROBLEM 13
"*** YOUR CODE HERE ***"
if expressions is nil:
return False
evaled = scheme_eval(expressions.first, env)
if evaled is not False:
return evaled
next_expr = expressions.second
while next_expr is not nil:
evaled = scheme_eval(next_expr.first, env)
if evaled is not False:
return evaled
next_expr = next_expr.second
return evaled
# END PROBLEM 13
Problem 14
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-14-2-pt
def do_cond_form(expressions, env):
"""Evaluate a cond form."""
while expressions is not nil:
clause = expressions.first
check_form(clause, 1)
if clause.first == 'else':
test = True
if expressions.second != nil:
raise SchemeError('else must be last')
else:
test = scheme_eval(clause.first, env)
if scheme_truep(test):
# BEGIN PROBLEM 14
"*** YOUR CODE HERE ***"
if clause.second is nil:
return test
return eval_all(clause.second, env)
# END PROBLEM 14
expressions = expressions.second
Problem 15
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-15-2-pt
def make_let_frame(bindings, env):
"""Create a child frame of ENV that contains the definitions given in
BINDINGS. The Scheme list BINDINGS must have the form of a proper bindings
list in a let expression: each item must be a list containing a symbol
and a Scheme expression."""
if not scheme_listp(bindings):
raise SchemeError('bad bindings list in let form')
# BEGIN PROBLEM 15
"*** YOUR CODE HERE ***"
check_form(bindings.first, 2, 2)
next_binding = bindings.second
while next_binding is not nil:
check_form(bindings.first, 2, 2)
next_binding = next_binding.second
map_formals = lambda binding: binding.first
map_vals = lambda binding: eval_all(binding.second, env)
formals = bindings.map(map_formals)
vals = bindings.map(map_vals)
check_formals(formals)
return env.make_child_frame(formals, vals)
# END PROBLEM 15
Problem 16
Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-16-2-pt
def do_mu_form(expressions, env):
"""Evaluate a mu form."""
check_form(expressions, 2)
formals = expressions.first
check_formals(formals)
# BEGIN PROBLEM 16
body = expressions.second
return MuProcedure(formals, body)
# END PROBLEM 16
class MuProcedure(Procedure):
... ... ... ... ... ... ... ...
# BEGIN PROBLEM 16
"*** YOUR CODE HERE ***"
def make_call_frame(self, args, env):
return env.make_child_frame(self.formals, args)
# END PROBLEM 16
... ... .. .. ... .. ... ... ..
Last updated