Working on 5.11

main
Felix Martin 2021-03-24 13:04:52 -04:00
parent 8a2ce473be
commit 5b7e799f2f
3 changed files with 69 additions and 22 deletions

View File

@ -210,10 +210,10 @@
(goto (label fib-loop)) ; perform recursive call (goto (label fib-loop)) ; perform recursive call
afterfib-n-1 ; upon return, val contains Fib(n - 1) afterfib-n-1 ; upon return, val contains Fib(n - 1)
(restore n) (restore n)
;(restore continue) ;(restore continue) ; uneeded restore
;; set up to compute Fib(n - 2) ;; set up to compute Fib(n - 2)
(assign n (op -) (reg n) (const 2)) (assign n (op -) (reg n) (const 2))
;(save continue) ;(save continue) ; uneeded continue
(assign continue (label afterfib-n-2)) (assign continue (label afterfib-n-2))
(save val) ; save Fib(n - 1) (save val) ; save Fib(n - 1)
(goto (label fib-loop)) (goto (label fib-loop))

View File

@ -103,38 +103,84 @@
(start triple-inc-machine) (start triple-inc-machine)
(assert (get-register-contents triple-inc-machine 'a) 11) (assert (get-register-contents triple-inc-machine 'a) 11)
(display "\nex-5.11\n") (display "\nex-5.11 - stack-behavior\n")
;Exercise 5.11. When we introduced save and restore in section 5.1.4, we ; a
;didn't specify what would happen if you tried to restore a register that was (define fib-machine
;not the last one saved, as in the sequence (make-machine
'(n val continue)
(list (list '< <) (list '- -) (list '= +) (list '+ +))
'(controller
(assign continue (label fib-done))
fib-loop
(test (op <) (reg n) (const 2))
(branch (label immediate-answer))
;; set up to compute Fib(n - 1)
(save continue)
(assign continue (label afterfib-n-1))
(save n) ; save old value of n
(assign n (op -) (reg n) (const 1)); clobber n to n - 1
(goto (label fib-loop)) ; perform recursive call
afterfib-n-1 ; upon return, val contains Fib(n - 1)
(restore n)
;; set up to compute Fib(n - 2)
(assign n (op -) (reg n) (const 2))
(assign continue (label afterfib-n-2))
(save val) ; save Fib(n - 1)
(goto (label fib-loop))
afterfib-n-2 ; upon return, val contains Fib(n - 2)
; (assign n (reg val)) ; n now contains Fib(n - 2)
; (restore val) ; val now contains Fib(n - 1)
(restore n) ; ex-5.11 - save one instruction
(assign val ; Fib(n - 1) + Fib(n - 2)
(op +) (reg val) (reg n))
(restore continue)
(goto (reg continue)) ; return to caller, answer is in val
immediate-answer
(assign val (reg n)) ; base case: Fib(n) = n
(goto (reg continue))
fib-done)))
;(save y) ; We can replace ((assign n (reg val)) (restore val)) with (restore n) because
;(save x) ; we add up n and val anyway. It does not matter which is in which register.
;(restore y)
;There are several reasonable possibilities for the meaning of restore: (set-register-contents! fib-machine 'n 8)
(start fib-machine)
(display "a. ")
(assert (get-register-contents fib-machine 'val) 21)
;a. (restore y) puts into y the last value saved on the stack, regardless of ; b.
;what register that value came from. This is the way our simulator behaves. (define stack-content car)
;Show how to take advantage of this behavior to eliminate one instruction from (define stack-register cadr)
;the Fibonacci machine of section 5.1.4 (figure 5.12).
;b. (restore y) puts into y the last value saved on the stack, but only if (define (make-save inst machine stack pc)
;that value was saved from y; otherwise, it signals an error. Modify the (let ((reg (get-register machine
;simulator to behave this way. You will have to change save to put the register (stack-inst-reg-name inst))))
;name on the stack along with the value. (lambda ()
(push stack (list (get-contents reg) reg))
(advance-pc pc))))
(define (make-restore inst machine stack pc)
(let ((reg (get-register machine
(stack-inst-reg-name inst))))
(lambda ()
(let ((stack-element (pop stack)))
(if (not (eq? reg (stack-register stack-element)))
(error "restore from different reg -- MAKE-RESTORE"
(reg 'name?)
((stack-register stack-element) 'name?)))
(set-contents! reg (stack-content stack-element))
(advance-pc pc)))))
(display "b. [implemented]\n")
(display "c. ACTIVE!!!\n")
;c. (restore y) puts into y the last value saved from y regardless of what ;c. (restore y) puts into y the last value saved from y regardless of what
;other registers were saved after y and not restored. Modify the simulator to ;other registers were saved after y and not restored. Modify the simulator to
;behave this way. You will have to associate a separate stack with each ;behave this way. You will have to associate a separate stack with each
;register. You should make the initialize-stack operation initialize all the ;register. You should make the initialize-stack operation initialize all the
;register stacks. ;register stacks.
; Extend the message-passing interface to the machine to provide access to
; this new information. To test your analyzer, define the Fibonacci machine
; from figure 5.12 and examine the lists you constructed.
(display "\nex-5.12\n") (display "\nex-5.12\n")
; (display "\nex-5.13\n") ; (display "\nex-5.13\n")

View File

@ -29,6 +29,7 @@
(cond ((eq? message 'get) contents) (cond ((eq? message 'get) contents)
((eq? message 'set) ((eq? message 'set)
(lambda (value) (set! contents value))) (lambda (value) (set! contents value)))
((eq? message 'name?) name)
(else (else
(error "Unknown request -- REGISTER" message)))) (error "Unknown request -- REGISTER" message))))
dispatch)) dispatch))