lluvia900125 2023-06-08 12:35 采纳率: 45%
浏览 56
已结题

cs61A的scheme解释器代码实现问题

我现在在跟着berkeley 61a(2023版本)自学转码,请帮忙debug scheme解释器的第9题:网站 , 需要对整个project 都有了解才可以回答这个问题。请直接改错,说明错误原因,
这是我的scheme_eval_apply.py中的代码,也可以直接看我的github,查看其他相关文件,problem9之前都做了。

这是报错信息

Problem 9 > Suite 3 > Case 1
 
scm> (define outer (lambda (x y)
....   (define inner (lambda (z x)
....     (+ x (* y 2) (* z 3))))
....   (inner x 10)))
outer
scm> (outer 1 2)
17
scm> (define outer-func (lambda (x y)
....   (define inner (lambda (z x)
....     (+ x (* y 2) (* z 3))))
....   inner))
outer-func
scm> ((outer-func 1 2) 1 10)
# Error: unknown identifier: y
 
# Error: expected
#     17
# but got
#     Traceback (most recent call last):
#       ...
#     SchemeError: unknown identifier: y
 



这是我摘出来的代码,含problem9

import sys
 
from pair import *
from scheme import *
from scheme_utils import *
from ucb import main, trace
 
import scheme_forms
 
##############
# Eval/Apply #
##############
 
 
def scheme_eval(expr, env, _=None):  # Optional third argument is ignored
    """Evaluate Scheme expression EXPR in Frame 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.rest
    if scheme_symbolp(first) and first in scheme_forms.SPECIAL_FORMS:
        return scheme_forms.SPECIAL_FORMS[first](rest, env)
    else:
        '''scheme_eval(Pair('+', Pair(2, Pair(2, nil))), create_global_frame())
         expr = read_line('(+ (+ 2 2) (+ 1 3) (* 1 4))') 
        '''
        # in map function, mapped = fn(self.first), but scheme_eval has two arguments
        operator = scheme_eval(expr.first, env)
        # probleme9 这里很可能是有问题的
        # if isinstance(operator, LambdaProcedure):
        #     return scheme_apply(operator, expr.rest, env)
        operands = expr.rest.map(lambda x: scheme_eval(x, env))
        return scheme_apply(operator, operands, env)
 
 
 
def scheme_apply(procedure, args, env):
    """Apply Scheme PROCEDURE to argument values ARGS (a Scheme list) in
    Frame ENV, the current environment."""
    validate_procedure(procedure)
    if not isinstance(env, Frame):
       assert False, "Not a Frame: {}".format(env)
    if isinstance(procedure, BuiltinProcedure):
 
        func = procedure.py_func
        argu = []
        while args != nil:
            argu.append(args.first)
            args = args.rest
 
        try:
            if procedure.need_env:
                return func(*argu, env)
            else:
                return func(*argu)
        except TypeError as err:
            raise SchemeError('incorrect number of arguments: {0}'.format(procedure))
    elif isinstance(procedure, LambdaProcedure):
        # PROBLEM 9
        formals = procedure.formals
        # vals = args.map(lambda x: scheme_eval(x, env))
        current_frame = env.make_child_frame(formals, args)
        return eval_all(procedure.body, current_frame)
 
        # END PROBLEM 9
 
    elif isinstance(procedure, MuProcedure):
        # BEGIN PROBLEM 11
        "*** YOUR CODE HERE ***"
        # END PROBLEM 11
    else:
        assert False, "Unexpected procedure: {}".format(procedure)
# (define outer-func (lambda (x y) (define inner (lambda (z x) (+ x (* y 2) (* z 3)))) inner))
 
 
def eval_all(expressions, env):
    """Evaluate each expression in the Scheme list EXPRESSIONS in
    Frame ENV (the current environment) and return the value of the last.
    >>> eval_all(read_line("(1)"), create_global_frame())
    1
    >>> eval_all(read_line("(1 2)"), create_global_frame())
    2
    >>> x = eval_all(read_line("((print 1) 2)"), create_global_frame())
    1
    >>> x
    2
    >>> eval_all(read_line("((define x 2) x)"), create_global_frame())
    2
    """
    # BEGIN PROBLEM 6
    result = None
    expr = expressions
    while expr != nil:
        result = scheme_eval(expr.first, env)
        expr = expr.rest
    return result
 
 
      # replace this with lines of your own code
    # END PROBLEM 6
 

  • 写回答

2条回答 默认 最新

  • MR_Bone 2023-06-08 15:46
    关注

    根据您提供的代码和报错信息,问题出现在scheme_apply函数的部分。

    scheme_apply函数中,对于LambdaProcedure类型的过程,我们需要对形参进行绑定。在这个问题中,错误出现在形参绑定的部分。

    您可以将以下代码块替换原始代码中的# PROBLEM 9部分,进行修正:

    # PROBLEM 9
    formals = procedure.formals
    vals = args.map(lambda x: scheme_eval(x, env))
    current_frame = env.make_child_frame(formals, vals)
    return scheme_eval(procedure.body, current_frame)
    # END PROBLEM 9
    

    这段代码将使用args中的实际参数值进行形参绑定,并在新的子环境中对过程体进行求值。

    请注意,这是针对特定问题的修改。如果还有其他问题出现,可能需要检查其他部分的代码。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月12日
  • 创建了问题 6月8日

悬赏问题

  • ¥30 计算机硬件实验报告寻代
  • ¥15 51单片机写代码,要求是图片上的要求,请大家积极参与,设计一个时钟,时间从12:00开始计时,液晶屏第一行显示time,第二行显示时间
  • ¥15 用C语言判断命题逻辑关系
  • ¥15 原子操作+O3编译,程序挂住
  • ¥15 使用STM32F103C6微控制器设计两个从0到F计数的一位数计数器(数字),同时,有一个控制按钮,可以选择哪个计数器工作:需要两个七段显示器和一个按钮。
  • ¥15 在yolo1到yolo11网络模型中,具体有哪些模型可以用作图像分类?
  • ¥15 AD9910输出波形向上偏移,波谷不为0V
  • ¥15 淘宝自动下单XPath自动点击插件无法点击特定<span>元素,如何解决?
  • ¥15 曙光1620-g30服务器安装硬盘后 看不到硬盘
  • ¥15 抖音直播广场scheme