SICP 読み (150) 4.1.2 式の表現
ナチュラル全開だったらどうしようと思いつつ、そのまま進めてしまう。
問題 4.10
誤読かもしれませんがとりあえず問題 4.3 なソレを作ってみます。以下が現時点での問題 4.3 な解。
(define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((not (pair? exp)) (error "Unknown expression type -- EVAL" exp)) (else (let ((x (get (car exp) 'eval))) (if x (x exp env) (apply (eval (operator exp) env) (list-of-values (operands exp) env)))))))
ちょっと長くなりそう。試験ってできるのかなぁ。
(define (make-if predicate consequent alternative) (list 'if predicate consequent alternative)) (define (make-lambda parameters body) (cons 'lambda (cons parameters body))) (define (make-procedure parameters body env) ) (define (make-begin seq) (cons 'begin seq)) (define (install-quote) (define (eval-quote exp env) (cadr exp)) (put 'quote 'eval eval-quote) 'done) (define (install-assignment) (define (assignment-variable exp) (cadr exp)) (define (assignment-value exp) (caddr exp)) (define (eval-assignment exp env) (set-variable-value! (assignment-variable exp) (eval (assignment-value exp) env) env)) (put 'set! 'eval eval-assignment) 'done) (define (install-definition) (define (definition-variable exp) (if (symbol? (cadr exp)) (cadr exp) (caadr exp))) (define (definition-value exp) (if (symbol? (cadr exp)) (caddr exp) (make-lambda (cdadr exp) (cddr exp)))) (define (eval-definition exp env) (define-variable! (definition-variable exp) (eval (definition-value exp) env) env)) (put 'define 'eval eval-definition) 'done) (define (install-if) (define (if-predicate exp) (cadr exp)) (define (if-consequent exp) (caddr exp)) (define (if-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false)) (define (eval-if exp env) (if (true? (eval (if-predicate exp) env)) (eval (if-consequent exp) env) (eval (if-alternative exp) env))) (put 'if 'eval eval-if) 'done) (define (install-lambda) (define (lambda-parameters exp) (cadr exp)) (define (lambda-body exp) (cddr exp)) (define (eval-lambda exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) (put 'lambda 'eval eval-lambda) 'done) (define (install-begin) (define (begin-actions exp) (cdr exp)) (define (last-exp? seq) (null? (cdr seq))) (define (first-exp seq) (car seq)) (define (rest-exps seq) (cdr seq)) (define (eval-sequence exps env) (cond ((last-exp? exps) (eval (first-exp exps) env)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) (define (eval-begin exp env) (eval-sequence (begin-actions exp) env)) (put 'begin 'eval eval-begin) 'done) (define (install-cond) (define (cond->clauses exp) (cdr exp)) (define (cond-else-clause? clause) (eq? (cond-predicate clause) 'else)) (define (cond-predicate clause) (car clause)) (define (cond-actions clause) (cdr clause)) (define (expand-clauses clauses) (if (null? clauses) 'false (let ((first (car clauses)) (rest (cdr clauses))) (if (cond-else-clause? first) (if (null? rest) (sequence->exp (cond-actions first)) (error "ELSE clause isn't last -- COND->IF" clauses)) (make-if (cond-predicate first) (sequence->exp (cond-actions first)) (expand-clauses rest)))))) (define (sequence->exp seq) (cond ((null? seq) seq) ((last-exp? seq) (first-exp seq)) (else (make-begin seq)))) (define (cond->if exp) (expand-clause (cond-clauses exp))) (define (eval-cond exp env) (eval (cond->if exp) env)) (put 'cond 'eval eval-cond) 'done)
eval をもう一度。
(define (eval exp env) (define (list-of-values exps env) (if (no-operands? exps) '() (cons (eval (first-operand exps) env) (list-of-values (rest-operands exps) env)))) (define (operator exp) (car exp)) (define (operands exp) (cdr exp)) (define (no-operands? ops) (null? ops)) (define (first-operand ops) (car ops)) (define (rest-operands ops) (cdr ops)) (define (self-evaluating? exp) (cond ((number? exp) true) ((string? exp) true) (else false))) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((not (pair? exp)) (error "Unknown expression type -- EVAL" exp)) (else (let ((x (get (car exp) 'eval))) (if x (x exp env) (apply (eval (operator exp) env) (list-of-values (operands exp) env)))))))
とりあえず上記のソレをどう試験したものか。
試験
って試験を書きかけたんですが、eval がきちんとデキないと駄目じゃん。