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
afterfib-n-1 ; upon return, val contains Fib(n - 1)
(restore n)
;(restore continue)
;(restore continue) ; uneeded restore
;; set up to compute Fib(n - 2)
(assign n (op -) (reg n) (const 2))
;(save continue)
;(save continue) ; uneeded continue
(assign continue (label afterfib-n-2))
(save val) ; save Fib(n - 1)
(goto (label fib-loop))

View File

@ -103,38 +103,84 @@
(start triple-inc-machine)
(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
;didn't specify what would happen if you tried to restore a register that was
;not the last one saved, as in the sequence
; a
(define fib-machine
(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)
;(save x)
;(restore y)
; We can replace ((assign n (reg val)) (restore val)) with (restore n) because
; we add up n and val anyway. It does not matter which is in which register.
;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
;what register that value came from. This is the way our simulator behaves.
;Show how to take advantage of this behavior to eliminate one instruction from
;the Fibonacci machine of section 5.1.4 (figure 5.12).
; b.
(define stack-content car)
(define stack-register cadr)
;b. (restore y) puts into y the last value saved on the stack, but only if
;that value was saved from y; otherwise, it signals an error. Modify the
;simulator to behave this way. You will have to change save to put the register
;name on the stack along with the value.
(define (make-save inst machine stack pc)
(let ((reg (get-register machine
(stack-inst-reg-name inst))))
(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
;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
;register. You should make the initialize-stack operation initialize all the
;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.13\n")

View File

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