我正在尝试在学校计划中建立一个评估程序。它需要自己的环境,作为列表构建。例如
(define env (list
(list 'x 5)
(list '+ +)
(list '* *)))
用函数
调用的地方 (define lookup
(lambda (symbol env)
(cond [(not (symbol? symbol)) 0]
[(null? env) 0]
[(eq? symbol (car (car env))) (car (cdr (car env)))]
[else (lookup symbol (cdr env))])))
我们可以从符号中获取程序和值。我需要帮助的是评估函数,它采用像'(+ 1 x)
之类的列表,它将查看符号'+
,并发现它使用查找对添加过程进行求值,然后将过程应用于列表中的其他所有内容。到目前为止我已经
(define evaluate
(lambda (expr env)
(cond [(null? expr) 0]
[(number? (car expr)) ((car expr) (evaluate (cdr expr) env))]
[(procedure? (lookup (car expr) env)) ((lookup (car expr) env)
(evaluate (cdr expr) env))] `
我遇到的麻烦是每次函数经过递归时应用该过程。我如何申请说添加到列表的每个元素?谢谢
答案 0 :(得分:0)
很重要很多你打算做多少错误处理。在最简单的情况下,假设所有表达式都具有正确的参数,它就像
(let ((op (lookup (car exp))))
(apply op (cdr exp)))
答案 1 :(得分:0)
lookup
应该不在乎。只要(eq? symbol (car env))
不为空,只需检查env
即可。由于所有表达式都有正确的参数,所以它永远不应该为null,所以我希望(error "should never happen")
在这种情况下是一个好结果。
evaluate
不处理简单表达式。为什么?例如。
(evaluate 5 '()) ; ==> 5
为什么(evaluate '() '()) ; ==> 0
?它没有意义。在许多lisps中它是自我评估,但我想在你的评估器中处理数学它不是一个有效的表达式。这些是:
(evaluate 'x '((x 5))) ; ==> 5
现在为实际的撰写默认情况:
(evaluate '(+ x y) '((x 5) (y 7)))
这应该做:
(apply (eval '+ env)
(evlis '(x y) '((x 5) (y 7)))
evlis
是一个需要制作的过程,它使用列表来评估使用提供的环境的每个元素。因此,上述变成:
(apply + '(5 7))
这样做的全部意义在于:这应该有效:
(* (+ 4 5) 2) ; ==> 18
这是有效的,因为您评估每个部分,因为您评估每个部分,它也将评估其部分。 eval
本质上是递归的。