1 (make-machine <regs> <ops> <controller>)
3 (set-register-contents! <machine> <reg> <value>)
4 (get-register-contents <machine> <reg>)
6 (define (make-register name)
7 (let ((contents '*unassigned*))
8 (define (dispatch message)
9 (cond ((eq? message 'get) contents)
11 (lambda (val) (set! contents val)))
13 (error "Unknown request -- REGISTER"
17 (define (get-contents reg)
19 (define (set-contents! reg val)
29 (set! number-pushes (+ number-pushes 1))
30 (set! current-depth (+ current-depth 1))
31 (set! max-depth (max max-depth current-depth)))
34 (error "Empty stack -- POP")
37 (set! current-depth (- current-depth 1))
41 (set! number-pushes 0)
42 (set! current-depth 0)
44 (define (print-statistics)
45 `(total-pushes = ,number-pushes
46 max-depth = ,max-depth))
47 (define (dispatch message)
48 (cond ((eq? message 'push) push)
49 ((eq? message 'pop) (pop))
50 ((eq? message 'initialize) (initialize))
51 ((eq? message 'print-statistics) (print-statistics))
53 (error "Unknown request -- STACK"
56 (define (push stack val)
61 (define (make-machine regs ops controller)
62 (let ((machine (make-new-machine)))
65 ((machine 'allocate-register) reg))
67 ((machine 'install-operations) ops)
68 ((machine 'install-instruction-sequence)
69 (assemble controller machine))
72 (define (make-new-machine)
73 (let* ((pc (make-register 'pc))
74 (flag (make-register 'flag))
76 (the-instruction-sequence '())
82 ,(lambda () (stack 'initialize)))
84 ,(lambda () (stack 'print-statistics))))))
86 (let ((insts (get-contents pc)))
89 (begin ((instruction-proc (car insts)))
91 (define (allocate-register name)
92 (let ((val (assoc name register-table)))
94 (error "Multiply defined register: " name)
96 (cons (list name (make-register name))
98 (define (lookup-register name)
99 (let ((val (assoc name register-table)))
102 (error "Undefined register: " name))))
103 (define (dispatch message)
104 (cond ((eq? message 'start)
105 (set-contents! pc the-instruction-sequence)
107 ((eq? message 'allocate-register) allocate-register)
108 ((eq? message 'get-register) lookup-register)
109 ((eq? message 'install-operations)
110 (lambda (ops) (set! the-ops (append the-ops ops))))
111 ((eq? message 'install-instruction-sequence)
112 (lambda (seq) (set! the-instruction-sequence seq)))
113 ((eq? message 'stack) stack)
114 ((eq? message 'operations) the-ops)))
117 (define (make-instruction text)
119 (define (instruction-proc inst)
121 (define (instruction-text inst)
123 (define (set-instruction-proc! inst proc)
124 (set-cdr! inst proc))
126 (define (start machine)
128 (define (get-register machine reg-name)
129 ((machine 'get-register) reg-name))
130 (define (set-register-contents! machine reg val)
131 (set-contents! (get-register machine reg) val)
133 (define (get-register-contents machine reg)
134 (get-contents (get-register machine reg)))
136 (define (assemble controller-text machine)
139 (lambda (insts labels)
140 (update-insts! insts labels machine)
142 (define (extract-labels text receive)
147 (lambda (insts labels)
148 (let ((next-inst (car text)))
149 (if (symbol? next-inst)
152 (cons (make-label-entry next-inst insts) labels))
154 (cons (make-instruction next-inst) insts)
157 (define (update-insts! insts labels machine)
160 (define (make-label-entry label insts)
162 (define (lookup labels label-name)