Impelement till 4.5
parent
d48c389429
commit
c958d52f50
101
ex-4_01-xx.scm
101
ex-4_01-xx.scm
|
@ -51,20 +51,21 @@
|
|||
env)))
|
||||
(put 'begin (lambda (exp env) (eval-sequence (begin-actions exp) env)))
|
||||
(put 'cond (lambda (exp env) (eval (cond->if exp) env)))
|
||||
(put 'and (lambda (exp env) 'TODO))
|
||||
(put 'or (lambda (exp env) 'TODO))
|
||||
(put 'let (lambda (exp env) (eval (let->lambda exp) env)))
|
||||
(put 'and (lambda (exp env) (eval-and (clauses exp) env)))
|
||||
(put 'or (lambda (exp env) (eval-or (clauses exp) env)))
|
||||
(display "[install-eval-package]\n")
|
||||
'done)
|
||||
|
||||
(install-eval-package)
|
||||
|
||||
(define (eval exp env)
|
||||
; (display "(EVAL ") (display exp) (display ")") (newline)
|
||||
(cond
|
||||
((self-evaluating? exp) exp)
|
||||
((variable? exp) (lookup-variable-value exp env))
|
||||
((and (not (null? exp))
|
||||
(get (car exp)))
|
||||
((get (car exp)) exp env))
|
||||
((and (not (null? exp)) (get (car exp)))
|
||||
((get (car exp)) exp env))
|
||||
((application? exp)
|
||||
(apply (eval (operator exp) env)
|
||||
(list-of-values (operands exp) env)))
|
||||
|
@ -72,7 +73,93 @@
|
|||
|
||||
(display "[done]\n")
|
||||
|
||||
(display "\nex-4.5 - and/or\n")
|
||||
(display "\nex-4.4 - and/or\n")
|
||||
|
||||
(display "\nex-4.6\n")
|
||||
(define (clauses exp) (cdr exp))
|
||||
(define (no-clauses? exp) (null? exp))
|
||||
(define (first-clause exp) (car exp))
|
||||
(define (rest-clauses exp) (cdr exp))
|
||||
|
||||
(define (eval-and exp env)
|
||||
(if (no-clauses? exp)
|
||||
#t
|
||||
(if (true? (eval (first-clause exp) env))
|
||||
(eval-and (rest-clauses exp) env)
|
||||
#f)))
|
||||
|
||||
(define (eval-or exp env)
|
||||
(if (no-clauses? exp)
|
||||
#f
|
||||
(if (true? (eval (first-clause exp) env))
|
||||
#t
|
||||
(eval-or (rest-clauses exp) env))))
|
||||
|
||||
(define (true? a) a)
|
||||
|
||||
(assert (eval '(or) '()) #f)
|
||||
(assert (eval '(and) '()) #t)
|
||||
(assert (eval '(and 0 0 0 #f) '()) #f)
|
||||
(assert (eval '(or #f #f #t) '()) #t)
|
||||
|
||||
(display "\nex-4.5 - modified-cond\n")
|
||||
|
||||
; Exercise 4.5. Scheme allows an additional syntax for cond clauses, (<test> =>
|
||||
; <recipient>).
|
||||
; If <test> evaluates to a true value, then <recipient> is evaluated. Its value
|
||||
; must be a procedure of one argument; this procedure is then invoked on the
|
||||
; value of the <test>, and the result is returned as the value of the cond
|
||||
; expression. For example
|
||||
|
||||
; (cond ((assoc 'b '((a 1) (b 2))) => cadr)
|
||||
; (else false))
|
||||
|
||||
; returns 2. Modify the handling of cond so that it supports this extended syntax.
|
||||
|
||||
(define (cond-test exp) (car exp))
|
||||
(define (cond-recipient exp) (caddr exp))
|
||||
(define (cond-test-recipient-clause? exp)
|
||||
(eq? (cadr exp) '=>))
|
||||
|
||||
(define (expand-clauses clauses)
|
||||
(if (null? clauses)
|
||||
'false ; no else clause
|
||||
(let ((first (car clauses))
|
||||
(rest (cdr clauses)))
|
||||
(cond
|
||||
((cond-else-clause? first)
|
||||
(if (null? rest)
|
||||
(sequence->exp (cond-actions first))
|
||||
(error "ELSE clause isn't last -- COND->IF"
|
||||
clauses)))
|
||||
((cond-test-recipient-clause? first)
|
||||
(let ((test-evaluated (eval (cond-test exp) env)))
|
||||
(if test-evaluated
|
||||
(eval (list (cond-recipient exp) test-evaluated) env)
|
||||
(expand-clauses rest))))
|
||||
(else
|
||||
(make-if (cond-predicate first)
|
||||
(sequence->exp (cond-actions first))
|
||||
(expand-clauses rest)))))))
|
||||
|
||||
(display "[done]\n")
|
||||
|
||||
(display "\nex-4.6 - let-expression\n")
|
||||
|
||||
(define (let->lambda exp) 0)
|
||||
|
||||
; (let ((<var1> <exp1>) ... (<varn> <expn>))
|
||||
; <body>)
|
||||
;
|
||||
; ((lambda (<var1> ... <varn>)
|
||||
; <body>)
|
||||
; <exp1>
|
||||
;
|
||||
; <expn>)
|
||||
|
||||
; Implement a syntactic transformation let->combination that reduces evaluating
|
||||
; let expressions to evaluating combinations of the type shown above, and add the
|
||||
; appropriate clause to eval to handle let expressions
|
||||
|
||||
|
||||
(display "\nex-4.7")
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
(define (self-evaluating? exp)
|
||||
(cond ((number? exp) true)
|
||||
((string? exp) true)
|
||||
((eq? exp #t) true)
|
||||
((eq? exp #f) true)
|
||||
(else false)))
|
||||
|
||||
(define (variable? exp) (symbol? exp))
|
||||
|
|
Loading…
Reference in New Issue