0

スキームでラムダを解釈しようとしています。これが私のコードです:

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

input を試すと、 「引数として渡されたオブジェクトはペアではありません((lambda (n) (+ n 2)) 5)」というエラーが表示されます。なぜこれが当てはまるのでしょうか。関数はうまく機能すると確信しているので、ここには書きませんでした。解釈に問題がありますが、見つけることができません。()safe-carlambda-stmt?apply-lambda

4

2 に答える 2

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」句) の適用を変更して、手続き (数学演算以外) を処理する必要があります。そして、呼び出されたときにプロシージャをその引数に適用する必要がありますが、これは(フォーマルを引数にバインドし、新しい環境で本体を解釈する)とよく似ています。letlambdalambda

[追加...]

私は次のように考え始めます。

(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 に答える