<< Previous exercise (5.11) | Index | Next exercise (5.13) >>
; added ((machine 'gather-info) controller-text) in `make-machine ; added ((eq? message 'gather-info) (lambda (controller-text) ; (gather-info controller-text)) ; added ((eq? message 'get-info) (lambda (type) (assoc type information))) ; to `make-new-machine ; use: ; ((<machine> 'get-info) <info-type>) ; for example: ; ((recursive-fib-machine 'get-info) 'entry-points) ; ((<machine> 'get-info) <reg-name>)) ; to maintain abstraction. (define (get-info machine info) ((machine 'get-info) info)) (define (gather-info controller-text) (define (gather inst-type insts) (if debug (format #t "\n ~a \n" insts)) (define (gather-iter gathered left lst) (if debug (format #t "gather-iter: \n gatehered: ~a \n lst: ~a \n" gathered lst)) (cond ((null? lst) (list (cons inst-type gathered) left)) ((not (pair? (car lst))) (gather-iter gathered left (cdr lst))) ((eq? inst-type (caar lst)) (if (member (car lst) gathered) (gather-iter gathered left (cdr lst)) (gather-iter (cons (car lst) gathered) left (cdr lst)))) (else (gather-iter gathered (cons (car lst) left) (cdr lst))))) (gather-iter '() '() insts)) (define (gather-entry-points gotos) (define (gather-iter gathered lst) (if (null? lst) (list 'entry-points gathered) (let ((dest (goto-dest (car lst)))) (if (register-exp? dest) (gather-iter (cons (register-exp-reg dest) gathered) (cdr lst)) (gather-iter gathered (cdr lst)))))) (list (gather-iter '() gotos)) (define (gather-saved-reg saved) (list (cons 'stacked-ref (map (lambda (x) (stack-inst-reg-name x)) saved)))) (define (gather-sources assigns) (define (sources-iter reg gathered left lst) (cond ((null? lst) (list (list reg gathered) left)) ((eq? reg (assign-reg-name (car lst))) (sources-iter reg (cons (cddr (car lst)) gathered) left (cdr lst))) (else (sources-iter reg gathered (cons (car lst) left) (cdr lst))))) (define (sources-loop insts) (if (null? insts) '() (let* ((reg (assign-reg-name (car insts))) (srcs (sources-iter reg '() '() insts))) (cons (car srcs) (sources-loop (cadr srcs)))))) (sources-loop assigns)) (let* ((assigns (gather 'assign controller-text)) (tests (gather 'test (cadr assigns))) (branches (gather 'branch (cadr tests))) (gotos (gather 'goto (cadr branches))) (saves (gather 'save (cadr gotos))) (restores (gather 'restore (cadr saves))) (performs (gather 'perform (cadr restores))) (entry-points (gather-entry-points (cdar gotos))) (stacked (gather-saved-reg (cdar saves))) (sources (gather-sources (cdar assigns))) (registers (list (cons 'registers (map car sources))))) (append (map (lambda (x) (car x)) (list assigns tests branches gotos saves restores performs)) entry-points stacked sources registers)))
Sample results for Fibonacci machine: Instructions: ============= ((assign val (reg n)) (assign val (op +) (reg val) (reg n)) (assign n (reg val)) (assign continue (label afterfib-n-2)) (assign n (op -) (reg n) (const 2)) (assign n (op -) (reg n) (const 1)) (assign continue (label afterfib-n-1)) (assign continue (label fib-done)) (branch (label immediate-answer)) (goto (reg continue)) (goto (label fib-loop)) (restore val) (restore continue) (restore n) (save val) (save n) (save continue) (test (op <) (reg n) (const 2))) Entry Registers: ================ (continue) Stack Registers: ================ (n continue val) Register Sources: ================= ((continue ((label fib-done) (label afterfib-n-1) (label afterfib-n-2))) (n (((op -) (reg n) (const 1)) ((op -) (reg n) (const 2)) (reg val))) (val (((op +) (reg val) (reg n)) (reg n))))
code: https://github.com/codybartfast/sicp/blob/master/chapter5/machine-12.scm#L485
ypeels