计划 - 建立自己的评估程序

时间:2018-02-12 23:07:38

标签: function lambda scheme racket

我正在尝试在学校计划中建立一个评估程序。它需要自己的环境,作为列表构建。例如

(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))] `

我遇到的麻烦是每次函数经过递归时应用该过程。我如何申请说添加到列表的每个元素?谢谢

2 个答案:

答案 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本质上是递归的。