In order to gain a good understanding of the design of register machines, we must test the machines we design to see if they perform as expected. One way to test a design is to hand-simulate the operation of the controller, as in exercise 5.5. But this is extremely tedious for all but the simplest machines. In this section we construct a simulator for machines described in the register-machine language. The simulator is a Source program with four interface functions. The first uses a description of a register machine to construct a model of the machine (a data structure whose parts correspond to the parts of the machine to be simulated), and the other three allow us to simulate the machine by manipulating the model:
As an example of how these functions are used, we can define gcd_machine() to be a model of the GCD machine of section 5.1.1 as follows:
function gcd_machine() { return make_machine(list("a", "b", "t"), list(list("rem", binary_function((a, b) => a % b)), list("=", binary_function((a, b) => a === b))), list("test-b", test(op("="), reg("b"), constant(0)), branch(label("gcd-done")), assign("t", list(op("rem"), reg("a"), reg("b"))), assign("a", list(reg("b"))), assign("b", list(reg("t"))), go_to(label("test-b")), "gcd-done")); }
To compute GCDs with this machine, we set the input registers, start the machine, and examine the result when the simulation terminates:
set_register_contents(gcd_machine, "a", 206); "done"
set_register_contents(gcd_machine, "b", 40); "done"
start(gcd_machine); "done"
get_register_contents(gcd_machine, "a"); 2
This computation will run much more slowly than a gcd function written in Scheme, because we will simulate low-level machine instructions, such as assign, by much more complex operations.