Part 2 - Evaluation - Core Functionality

Problem 3

Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-3-2-pt

Implement the define and lookup methods of the Frame class. Each Frame object has the following instance attributes:

  • bindings is a dictionary representing the bindings in the frame. It maps Scheme symbols (represented as Python strings) to Scheme values.

  • parent is the parent Frame instance. The parent of the Global Frame is None.

Solution:

Class Frame


    def define(self, symbol, value):
        """Define Scheme SYMBOL to have VALUE."""
        # BEGIN PROBLEM 3
        "*** YOUR CODE HERE ***"
        self.bindings[symbol] = value
        # END PROBLEM 3

    def lookup(self, symbol):
        """Return the value bound to SYMBOL. Errors if SYMBOL is not found."""
        # BEGIN PROBLEM 3
        "*** YOUR CODE HERE ***"

        if symbol in self.bindings:
            return self.bindings[symbol]
        elif self.parent:
            return self.parent.lookup(symbol)
        # END PROBLEM 3

Problem 4

Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-4-2-pt

Complete the apply method in the BuiltinProcedure class

Solution:

# BEGIN PROBLEM 4
"*** YOUR CODE HERE ***"
if self.use_env:
    python_args.append(env)

try:
    return self.fn(*python_args)
except TypeError:
    raise SchemeError('Wrong number of arguments: {0}'.format(len(args)))

# END PROBLEM 4

Problem 5

Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-5-3-pt

Solution

Code authored by me marked by comments

def scheme_eval(expr, env, _=None): # Optional third argument is ignored
    """Evaluate Scheme expression EXPR in environment ENV.

    >>> expr = read_line('(+ 2 2)')
    >>> expr
    Pair('+', Pair(2, Pair(2, nil)))
    >>> scheme_eval(expr, create_global_frame())
    4
    """
    # Evaluate atoms
    if scheme_symbolp(expr):
        return env.lookup(expr)
    elif self_evaluating(expr):
        return expr

    # All non-atomic expressions are lists (combinations)
    if not scheme_listp(expr):
        raise SchemeError('malformed list: {0}'.format(repl_str(expr)))
    first, rest = expr.first, expr.second
    if scheme_symbolp(first) and first in SPECIAL_FORMS:
        return SPECIAL_FORMS[first](rest, env)
    else:
        # BEGIN PROBLEM 5
        "*** YOUR CODE HERE ***"
        first_eval = scheme_eval(first, env)
        eval_operands = lambda operand: scheme_eval(operand, env)

        if isinstance(first_eval, Procedure):
            operator =  first_eval
            rest_evaled = rest.map(eval_operands) 

            return scheme_apply(operator, rest_evaled, env)

        raise SchemeError('Error - Missing operator')
        # END PROBLEM 5

Problem 6

Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-6-2-pt

Solution:

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

Problem 7

Specs: https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/#problem-7-1-pt

def do_quote_form(expressions, env):
    """Evaluate a quote form."""
    check_form(expressions, 1, 1)
    # BEGIN PROBLEM 7
    "*** YOUR CODE HERE ***"
    return expressions.first
    # END PROBLEM 7

Last updated