Exercise 5.10. Design a new syntax for register-machine instructions and modify the simulator to use your new syntax. Can you implement your new syntax without changing any part of the simulator except the syntax procedures in this section?
在 S 表达式的范围内,我们可以随便改动 controller 的语法而不需要改动其它地方。
比如我们使用 mov 代替 assign;使用 cmp 代替 test,那仅仅只需要改动 make-execution-procedure 就可以了,不需要改动之前的代码。
下面的代码中 mov 和 assign 可以同时使用,cmp 和 test 也可以同时使用
(load "machine-stack-module.scm")
(load "machine-register-module.scm")
(load "machine-machine-module.scm")
(load "machine-assemble-module.scm")
(define (make-execution-procedure inst labels machine
pc flag stack ops)
(cond ((or (eq? (car inst) 'assign) (eq? (car inst) 'mov))
(make-assign inst machine labels ops pc))
((or (eq? (car inst) 'test) (eq? (car inst) 'cmp))
(make-test inst machine labels ops flag pc))
((eq? (car inst) 'branch)
(make-branch inst machine labels flag pc))
((eq? (car inst) 'goto)
(make-goto inst machine labels pc))
((eq? (car inst) 'save)
(make-save inst machine stack pc))
((eq? (car inst) 'restore)
(make-restore inst machine stack pc))
((eq? (car inst) 'perform)
(make-perform inst machine labels ops pc))
(else (error "Unknown instruction type -- ASSEMBLE"
inst))))
(define iterative-machine
(make-machine
'(n b counter product)
(list (list '= =)
(list '- -)
(list '* *))
'((mov counter (reg n))
(mov product (const 1))
expt-loop
(cmp (op =) (reg counter) (const 0))
(branch (label expt-done))
(assign counter (op -) (reg counter) (const 1))
(assign product (op *) (reg product) (reg b))
(goto (label expt-loop))
expt-done)))
(set-register-contents! iterative-machine 'n 3)
(set-register-contents! iterative-machine 'b 12)
(start iterative-machine)
(assert= (get-register-contents iterative-machine 'product)
(* 12 12 12))
其它的改动,比如 goto 可以自动检测之后是 register 还是 label,也可以简单地在 make-goto 的过程中加入相应的功能。此处省略。