diff options
Diffstat (limited to 'chap5/part3.rkt')
-rw-r--r-- | chap5/part3.rkt | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/chap5/part3.rkt b/chap5/part3.rkt new file mode 100644 index 0000000..2fad35d --- /dev/null +++ b/chap5/part3.rkt @@ -0,0 +1,219 @@ +#lang sicp +(#%require (only racket/base print-as-expression print-mpair-curly-braces)) +(print-as-expression #f) +(print-mpair-curly-braces #f) + +;; Chapter 5 +;; Computing with Register Machines + +;; 5.3 +;; Storage Allocation and Garbage Collection + +;; Memory as Vectors + +#| 5.20 |# + +#| (define x (cons 1 2)) |# +#| (define y (list x x)) |# + +#| | 0 | 1 | 2 | 3 | 4 | |# +#| ---------|----|----|----|----|----| |# +#| the-cars | n1 | p0 | p0 | |# +#| the-cdrs | n2 | e0 | p1 | |# + +#| x = p0 |# +#| y = p2 |# +#| free = 3 |# + +#| 5.21 |# + +(define (count-leaves tree) + (cond + ((null? tree) 0) + ((not (pair? tree)) 1) + (else + (+ + (count-leaves (car tree)) + (count-leaves (cdr tree)))))) + +(define count-leaves-controller + '(controller + (assign continue (label count-leaves-done)) + (assign tree (op read)) + count-leaves + (test (op null?) (reg tree)) + (branch (label if-null)) + (assign t (op pair?) (reg tree)) + (test (op not) (reg t)) + (branch (label if-leaf)) + (save continue) + (save tree) + (assign continue (label after-car-tree)) + (assign tree (op car) (reg tree)) + (goto (label count-leaves)) + after-car-tree + (restore tree) + (save tree) + (save val) + (assign tree (op cdr) (reg tree)) + (assign continue (label after-cdr-tree)) + (goto (label count-leaves)) + after-cdr-tree + (assign t (reg val)) + (restore val) + (restore tree) + (restore continue) + (assign val (op +) (reg t) (reg val)) + (goto (reg continue)) + if-null + (assign val (const 0)) + (goto (reg continue)) + if-leaf + (assign val (const 1)) + (goto (reg continue)) + count-leaves-done)) + +(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-iter-controller + '(controller + (assign continue (label count-leaves-done)) + (assign tree (op read)) + (assign n (const 0)) + count-iter + (test (op null?) (reg tree)) + (branch (label if-null)) + (assign t (op pair?) (reg tree)) + (test (op not) (reg t)) + (branch (label if-leaf)) + (save tree) + (save continue) + (assign tree (car tree)) + (assign continue (label after-car-tree)) + (goto (label count-iter)) + after-car-tree + (restore continue) + (restore tree) + (assign tree (cdr tree)) + (goto (label count-iter)) + if-null + (goto (reg continue)) + if-leaf + (assign n (op +) (reg n) (const 1)) + (goto (reg continue)) + count-leaves-done)) + +#| 5.22 |# + +(define (append x y) + (if (null? x) + y + (cons (car x) (append (cdr x) y)))) + +(define append-controller + '(controller + (assign x (op read)) + (assign y (op read)) + (assign continue (label append-done)) + append + (test (op null?) (reg x)) + (branch (label if-null)) + (save x) + (save continue) + (assign x (op cdr) (reg x)) + (assign continue (label after-append)) + (goto (label append)) + after-append + (restore continue) + (restore x) + (assign x (op car) (reg x)) + (assign val (op cons) (reg x) (reg val)) + (goto (reg continue)) + if-null + (assign val (reg y)) + (goto (reg continue)) + append-done)) + +(#%provide append!) +(define (append! x y) + (set-cdr! (last-pair x) y) + x) + +(define append!-controller + '(controller + (assign x (op read)) + (assign y (op read)) + (assign head (reg x)) + (assign rest (op cdr) (reg x)) + last-pair + (test (op null?) (reg rest)) + (branch (label found-last-pair)) + (assign head (reg rest)) + (assign rest (op cdr) (reg rest)) + (goto (label last-pair)) + found-last-pair + (perform (op set-cdr!) (reg head) (reg y)))) + +;; Maintaining the Illusion of Infinite Memory + +(define gc-controller + '(begin-garbage-collection + (assign free (const 0)) + (assign scan (const 0)) + (assign old (reg root)) + (assign relocate-continue (label reassign-root)) + (goto (label relocate-old-result-in-new)) + reassign-root + (assign root (reg new)) + (goto (label gc-loop)) + gc-loop + (test (op =) (reg scan) (reg free)) + (branch (label gc-flip)) + (assign old (op vector-ref) (reg new-cars) (reg scan)) + (assign relocate-continue (label update-car)) + (goto (label relocate-old-result-in-new)) + update-car + (perform (op vector-set!) (reg new-cars) (reg scan) (reg new)) + (assign old (op vector-ref) (reg new-cdrs) (reg scan)) + (assign relocate-continue (label update-cdr)) + (goto (label relocate-old-result-in-new)) + update-cdr + (perform (op vector-set!) (reg new-cdrs) (reg scan) (reg new)) + (assign scan (op +) (reg scan) (const 1)) + (goto (label gc-loop)) + relocate-old-result-in-new + (test (op pointer-to-pair?) (reg old)) + (branch (label pair)) + (assign new (reg old)) + (goto (reg relocate-continue)) + pair + (assign oldcr (op vector-ref) (reg the-cars) (reg old)) + (test (op broken-heart?) (reg oldcr)) + (branch (label already-moved)) + (assign new (reg free)) + (assign free (op +) (reg free) (const 1)) + (perform (op vector-set!) (reg new-cars) (reg new) (reg olcr)) + (assign oldcr (op vector-ref) (reg the-cdrs) (reg old)) + (perform (op vector-set!) (reg new-cdrs) (reg new) (reg olcr)) + (perform (op vector-set!) (reg the-cars) (reg old) (const broken-heart)) + (perform (op vector-set!) (reg the-cdrs) (reg old) (reg new)) + (goto (reg relocate-continue)) + already-moved + (assign new (op vector-ref) (reg the-cdrs) (reg old)) + (goto (reg relocate-continue)) + gc-flip + (assign temp (reg the-cdrs)) + (assign the-cdrs (reg new-cdrs)) + (assign new-cdrs (reg temp)) + (assign temp (reg the-cars)) + (assign the-cars (reg new-cars)) + (assign new-cars (reg temp)))) |