Exercise 5.13. Modify the simulator so that it uses the controller sequence to determine what registers the machine has rather than requiring a list of registers as an argument to make-machine. Instead of pre-allocating the registers in make-machine, you can allocate them one at a time when they are first seen during assembly of the instructions. ———————————————————————————————————————————————————————————————————————— Code is in 5.13.scm, tested with the example machines from Exercise 5.7, with the explicit register definitions removed from the make-machine calls. Test output: 1 ]=> (test-expt-recur) ;Value: 343 1 ]=> (test-expt-iter) ;Value: 343 The following changes were made: --- ch5-regsim.scm 2010-03-16 02:00:34.000000000 -0600 +++ 5.13.scm 2010-03-16 01:55:12.000000000 -0600 @@ -1,12 +1,9 @@ ;;;;REGISTER-MACHINE SIMULATOR FROM SECTION 5.2 OF ;;;; STRUCTURE AND INTERPRETATION OF COMPUTER PROGRAMS -(define (make-machine register-names ops controller-text) +(define (make-machine ops controller-text) (let ((machine (make-new-machine))) - (for-each (lambda (register-name) - ((machine 'allocate-register) register-name)) - register-names) - ((machine 'install-operations) ops) + ((machine 'install-operations) ops) ((machine 'install-instruction-sequence) (assemble controller-text machine)) machine)) @@ -116,11 +113,12 @@ (cons (list name (make-register name)) register-table))) 'register-allocated) - (define (lookup-register name) + (define (lookup-or-assign-register name) (let ((val (assoc name register-table))) (if val (cadr val) - (error "Unknown register:" name)))) + (begin (allocate-register name) + (lookup-or-assign-register name))))) (define (execute) (let ((insts (get-contents pc))) (if (null? insts) @@ -135,7 +133,7 @@ ((eq? message 'install-instruction-sequence) (lambda (seq) (set! the-instruction-sequence seq))) ((eq? message 'allocate-register) allocate-register) - ((eq? message 'get-register) lookup-register) + ((eq? message 'get-register) lookup-or-assign-register) ((eq? message 'install-operations) (lambda (ops) (set! the-ops (append the-ops ops)))) ((eq? message 'stack) stack)