From 5b7e799f2f4f6a20046cc843b33b987d5f5cbf15 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Wed, 24 Mar 2021 13:04:52 -0400 Subject: [PATCH] Working on 5.11 --- ex-5_01-06.scm | 4 +-- ex-5_07-xx.scm | 86 +++++++++++++++++++++++++++++++++----------- misc/sicp-regsim.scm | 1 + 3 files changed, 69 insertions(+), 22 deletions(-) diff --git a/ex-5_01-06.scm b/ex-5_01-06.scm index c9deb40..03ded47 100644 --- a/ex-5_01-06.scm +++ b/ex-5_01-06.scm @@ -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)) diff --git a/ex-5_07-xx.scm b/ex-5_07-xx.scm index cbac4f8..984ef3e 100644 --- a/ex-5_07-xx.scm +++ b/ex-5_07-xx.scm @@ -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") diff --git a/misc/sicp-regsim.scm b/misc/sicp-regsim.scm index 525f67b..1bfb17c 100644 --- a/misc/sicp-regsim.scm +++ b/misc/sicp-regsim.scm @@ -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))