Skip to content

Commit

Permalink
5.21
Browse files Browse the repository at this point in the history
  • Loading branch information
ananthakumaran committed Mar 6, 2011
1 parent 4102e24 commit 363713f
Showing 1 changed file with 105 additions and 0 deletions.
105 changes: 105 additions & 0 deletions chap-5/21.ss
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
;; *Exercise 5.21:* Implement register machines for the following
;; procedures. Assume that the list-structure memory operations are
;; available as machine primitives.

;; a. Recursive `count-leaves':

;; (define (count-leaves tree)
;; (cond ((null? tree) 0)
;; ((not (pair? tree)) 1)
;; (else (+ (count-leaves (car tree))
;; (count-leaves (cdr tree))))))

(define count-leaves-machine
(make-machine
(list (list 'car car) (list 'cdr cdr) (list '= eq?)
(list 'pair? pair?) (list '+ +))
'(count-leaves
(assign count (const 0))
(assign continue (label count-leaves-done))
count-loop
(test (op =) (reg tree) (const ()))
(branch (label expt-zero))
(test (op pair?) (reg tree))
(branch (label add-car-leaves))
(assign count (const 1))
(goto (reg continue))
expt-zero
(assign count (const 0))
(goto (reg continue))
add-car-leaves
(save continue)
(save tree)
(assign continue (label add-cdr-leaves))
(assign tree (op car) (reg tree))
(goto (label count-loop))
add-cdr-leaves
(restore tree)
(save count)
(assign continue (label add-leaves))
(assign tree (op cdr) (reg tree))
(goto (label count-loop))
add-leaves
(assign t (reg count)) ;; cdr count
(restore count)
(restore continue)
(assign count (op +) (reg t) (reg count))
(goto (reg continue))
count-leaves-done)))

(define (count-leaves tree)
(set-register-contents! count-leaves-machine 'tree tree)
(start count-leaves-machine)
(get-register-contents count-leaves-machine 'count))

(count-leaves '((1 . (2 . 3)) . (4 . (5 . 6))))

;; b. Recursive `count-leaves' with explicit counter:

;; (define (count-leaves tree)
;; (define (count-iter tree n)
;; (cond ((null? tree) n)
;; ((not (pair? tree)) (+ n 1))
;; (else (count-iter (cdr tree)
;; (count-iter (car tree) n)))))
;; (count-iter tree 0))


(define count-leaves-machine
(make-machine
(list (list 'car car) (list 'cdr cdr) (list '= eq?)
(list 'pair? pair?) (list '+ +) (list 'print display))
'(count-leaves
(assign n (const 0))
(assign continue (label count-leaves-done))
count-loop
(test (op =) (reg tree) (const ()))
(branch (label continue))
(test (op pair?) (reg tree))
(branch (label count-iter))
(assign n (op +) (reg n) (const 1))
(goto (reg continue))
count-iter
(save continue)
(save tree)
(assign tree (op car) (reg tree))
(assign continue (label count-iter-after))
(goto (label count-loop))
count-iter-after
(restore tree)
(assign continue (label count-iter-result))
(assign tree (op cdr) (reg tree))
(goto (label count-loop))
count-iter-result
(restore continue)
(goto (reg continue))
continue
(goto (reg continue))
count-leaves-done)))

(define (count-leaves tree)
(set-register-contents! count-leaves-machine 'tree tree)
(start count-leaves-machine)
(get-register-contents count-leaves-machine 'n))

(count-leaves '(1 . (2 . 3)))

0 comments on commit 363713f

Please sign in to comment.