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