We will often define a machine to include primitive
operations that are actually very complex. For example, in
sections 5.4 and 5.5
we will treat
Scheme's
Python's
environment manipulations as primitive. Such abstraction is valuable
because it allows us to ignore the details of parts of a machine so that we
can concentrate on other aspects of the design. The fact that we have
swept a lot of complexity under the rug, however, does not mean that a
machine design is unrealistic. We can always replace the complex
primitives
by simpler primitive operations.
Consider the GCD machine. The machine has an instruction that computes the remainder of the contents of registers a and b and assigns the result to register t. If we want to construct the GCD machine without using a primitive remainder operation, we must specify how to compute remainders in terms of simpler operations, such as subtraction. Indeed, we can write a Scheme procedure Python function that finds remainders in this way:
| Original | Python |
| (define (remainder n d) (if (< n d) n (remainder (- n d) d))) | def remainder(n, d): return n if n < d else remainder(n - d, d) |
| Original | Python |
| (assign t (op rem) (reg a) (reg b)) | assign("t", llist(op("rem"), reg("a"), reg("b"))) |
| Original | Python |
| (controller test-b (test (op =) (reg b) (const 0)) (branch (label gcd-done)) (assign t (reg a)) rem-loop (test (op <) (reg t) (reg b)) (branch (label rem-done)) (assign t (op -) (reg t) (reg b)) (goto (label rem-loop)) rem-done (assign a (reg b)) (assign b (reg t)) (goto (label test-b)) gcd-done) | controller( llist( "test_b", test(llist(op("="), reg("b"), constant(0))), branch(label("gcd_done")), assign("t", reg("a")), "rem_loop", test(llist(op("<"), reg("t"), reg("b"))), branch(label("rem_done")), assign("t", llist(op("-"), reg("t"), reg("b"))), go_to(label("rem_loop")), "rem_done", assign("a", reg("b")), assign("b", reg("t")), go_to(label("test_b")), "gcd_done")) |
| Original | Python |
| (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (sqrt-iter 1.0)) | def sqrt(x): def is_good_enough(guess): return math_abs(square(guess) - x) < 0.001 def improve(guess): return average(guess, x / guess) def sqrt_iter(guess): return guess if is_good_enough(guess) else sqrt_iter(improve(guess)) return sqrt_iter(1) |