0

我正在尝试在方案中解释 lambda。这是我的代码:

(define get-operator (lambda (op-symbol)
  (cond
   ((equal? op-symbol '+) +)
   ((equal? op-symbol '-) -)
   ((equal? op-symbol '*) *)
   ((equal? op-symbol '/) /)
   (else (error "interpret: operator not implemented -->" op-symbol)))))

(define (apply-lambda clos actuals)
  (let* ((lam (cadr clos))
         (def-env (caddr clos))
         (formals (cadr lam))
         (body (caddr lam))
         (new-env (bind-all formals actuals def-env)))
    (val-body new-env)))


(define interpret (lambda (e env)
  (cond
   ((number? e) e)
   ((symbol? e) (get-value e env))
   ((not (list? e)) (error "interpret: cannot evaluate -->" e))
   ((if-stmt? e) (if (eq? (cadr e) 0)
                     (interpret (cadddr e) env)
                     (interpret (caddr e) env)))
   ((let-stmt? e) ;;GoZoner's part of code
    (let ((names (map car  (cadr e)))
          (inits (map cadr (cadr e))))
      ;; Evaluate inits in env
      (let ((vals (map (lambda (init) (interpret init env)) inits)))
        ;; Extend env with names+vals
        (let ((new-env (append (map cons names vals) env)))
          ;; Eval body in new env
          (interpret (caddr e) new-env)))))

   ((lambda-stmt? e) (apply-lambda e env))
   (else
    (let ((operands (map interpret (cdr e) (make-list (length (cdr e)) env)))
          (operator (get-operator (car e))))
      (apply operator operands))))))

当我尝试输入((lambda (n) (+ n 2)) 5)时,我收到一条错误消息“对象(),作为参数传递给safe-car不是一对”。为什么会这样?我确信该lambda-stmt?函数运行良好,所以我没有在这里写它,解释有问题apply-lambda但我找不到它。

4

2 回答 2

0

这似乎是错误的:

(lambda-stmt? e)

它应该是:

(lambda-stmt? (car e))
于 2013-05-24T00:47:55.557 回答
0

解释lambda本身是微不足道的。

(define (make-closure formals body env)
  `(CLOSURE ,formals ,body ,env))
(define closure-formals cadr)
(define closure-body    caddr)
(define closure-env     cadddr)

(define (procedure? thing)
  (and (pair? thing) (eq? 'CLOSURE (car thing))))

然后在解释器中:

((lambda-stmt? e) (make-closure (cadr e) (caddr) env))

然后,您必须更改函数/运算符(您的“else”子句)的应用程序以处理过程(除了数学运算之外)。而且,您需要在调用时将过程应用于其参数 - 但这很像let(将形式绑定到lambda参数,lambda在新环境中解释主体)。

[添加...]

我会开始这样想:

(define (make-primitive name)
  `(PRIMITIVE ,name))
(define primitive-name cadr)
(define (primitive? thing)
  (and (pair? thing) (eq? 'PRIMITIVE (car thing))))

(define top-level-env
  (map (lambda (op) (cons op (make-primitive op))) '(+ - * /)))

(define (interpret e env)
  (cond ((number? e) ...)
        ((symbol? e) ...)
        ((null?   e) (error "interpreter: cannot evaluate --> " e))
        ((if-stmt? e) ...)
        ;; other syntax (let, lambda, set!, ...)
        ...
        ;; function call
        ((list?   e)
         (let ((ie (map (lambda (e) (interpret e env)) e)
           (let ((operator (car ie))
                 (operands (cdr ie)))
             (cond ((primitive? operator)
                    (let ((function (get-operator (primitive-name operator))))
                      (apply function operands)))
                   ((procedure? operator)
                    ...)
                    (else 'error)))))
       (else 'error)))
于 2013-05-24T14:42:33.573 回答