Exercise 4.33: transform quoted pairs into cons for lazy lists
This turns a quoted expression into one or more conses. If these are defined to be the lazy versions, then we will get lazy lists.
This commit is contained in:
parent
01cb1c69dd
commit
51d71bbfb5
|
@ -22,7 +22,11 @@
|
|||
(define (lazy-eval exp env)
|
||||
(cond ((self-evaluating? exp) exp)
|
||||
((variable? exp) (lookup-variable-value exp env))
|
||||
((quoted? exp) (text-of-quotation exp))
|
||||
((quoted? exp) (let ((text (text-of-quotation exp)))
|
||||
(if (pair? text)
|
||||
(lazy-eval (quoted-exp->cons-quoted text)
|
||||
env)
|
||||
text)))
|
||||
((assignment? exp) (eval-assignment exp env lazy-eval))
|
||||
((definition? exp) (eval-definition exp env lazy-eval))
|
||||
((if? exp) (lazy-eval-if exp env))
|
||||
|
|
|
@ -1,25 +1,84 @@
|
|||
#lang sicp
|
||||
|
||||
(#%provide (all-defined))
|
||||
(#%require racket/trace)
|
||||
(#%require racket/trace
|
||||
rackunit
|
||||
(only racket/base module+))
|
||||
|
||||
(trace-define (self-evaluating? exp)
|
||||
(define (self-evaluating? exp)
|
||||
(cond ((number? exp) true)
|
||||
((string? exp) true)
|
||||
((eq? exp '*unassigned*) true) ; Special symbol that can
|
||||
; never be a variable.
|
||||
(else false)))
|
||||
|
||||
(trace-define (quoted? exp)
|
||||
(define (quoted? exp)
|
||||
(tagged-list? exp 'quote))
|
||||
(define (text-of-quotation exp) (cadr exp))
|
||||
|
||||
;; Exercise 4.33
|
||||
;; Transform quoted list to (cons a (cons b ...)). This will be
|
||||
;; evaluated by whichever version of cons (lazy or strict) is in scope
|
||||
;; in the evaluator.
|
||||
|
||||
|
||||
;; (quote (a b c)) -> (cons (quote a) (cons (quote b) (cons (quote c) (quote ()))))
|
||||
|
||||
;; (eval 'a) -> a
|
||||
;; (eval '(a))
|
||||
;; -> (eval `(cons ,(car '(a)) ,(cdr '(a))))
|
||||
;; -> (eval (cons 'a '()))
|
||||
|
||||
;; (eval '(a . b))
|
||||
;; -> (eval `(cons ,(car '(a . b)) ,(cdr '(a . b))))
|
||||
;; -> (eval `(cons 'a 'b))
|
||||
|
||||
;; (eval '(a b))
|
||||
;; -> (eval `(cons ,(car '(a b)) (cons ,(cadr '(a b)) ,(cdr (cdr '(a
|
||||
;; b))))))
|
||||
;; -> (eval `(cons 'a (cons 'b ())))
|
||||
|
||||
;; (eval '(a b))
|
||||
;; -> (eval (eval-quoted '(a b)))
|
||||
;; -> (eval `(cons 'a ,(eval-quoted '(b))))
|
||||
;; -> (eval `(cons 'a (cons 'b ,eval-quoted('()))))
|
||||
;; -> (eval `(cons 'a (cons 'b '())))
|
||||
|
||||
(define (quoted-exp->cons-quoted exp)
|
||||
(cond ((null? exp) (list 'quote '()))
|
||||
((pair? exp)
|
||||
(list 'cons
|
||||
(cond ((pair? (car exp))
|
||||
(quoted-exp->cons-quoted (car exp)))
|
||||
(else
|
||||
(list 'quote (car exp))))
|
||||
(quoted-exp->cons-quoted (cdr exp))))
|
||||
(else (list 'quote exp))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (quoted-exp->cons-quoted '(a b))
|
||||
'(cons 'a (cons 'b '())))
|
||||
(check-equal? (quoted-exp->cons-quoted '(a (b c) d))
|
||||
'(cons 'a
|
||||
(cons (cons 'b (cons 'c '()))
|
||||
(cons 'd '()))))
|
||||
(check-equal? (quoted-exp->cons-quoted '(a . b))
|
||||
'(cons 'a 'b))
|
||||
(check-equal? (quoted-exp->cons-quoted '((a . b) c))
|
||||
'(cons (cons 'a 'b) (cons 'c '())))
|
||||
(check-equal? (quoted-exp->cons-quoted '((a . b) . c))
|
||||
'(cons (cons 'a 'b) 'c))
|
||||
(check-equal? (quoted-exp->cons-quoted 'a)
|
||||
(list 'quote 'a))
|
||||
(check-equal? (quoted-exp->cons-quoted '1)
|
||||
(list 'quote 1)))
|
||||
|
||||
(define (tagged-list? exp tag)
|
||||
(if (pair? exp)
|
||||
(eq? (car exp) tag)
|
||||
false))
|
||||
|
||||
(trace-define (variable? exp) (symbol? exp))
|
||||
(define (variable? exp) (symbol? exp))
|
||||
|
||||
;; Assignment
|
||||
(define (assignment? exp)
|
||||
|
|
Loading…
Reference in New Issue