Exercise 5.44: In this section we have focused
on the use of the compile-time environment to produce lexical addresses. But
there are other uses for compile-time environments. For instance, in
Exercise 5.38 we increased the efficiency of compiled code by open-coding
primitive procedures. Our implementation treated the names of open-coded
procedures as reserved words. If a program were to rebind such a name, the
mechanism described in Exercise 5.38 would still open-code it as a
primitive, ignoring the new binding. For example, consider the procedure
(lambda (+ * a b x y)
(+ (* a x) (* b y)))
which computes a linear combination of x and y. We might call it
with arguments +matrix, *matrix, and four matrices, but the
open-coding compiler would still open-code the + and the * in
(+ (* a x) (* b y)) as primitive + and *. Modify the
open-coding compiler to consult the compile-time environment in order to
compile the correct code for expressions involving the names of primitive
procedures. (The code will work correctly as long as the program does not
define or set! these names.)
练习 5.44:本节重点讨论了编译时环境在生成词法地址方面的用途。但编译时环境还有其他用途。例如,在练习 5.38 中,我们通过对基本过程进行开放式编码来提高编译代码的效率,而那个实现将开放式编码过程的名称视为保留字。如果程序重新绑定了这样的名称,练习 5.38 所描述的机制仍会将其开放式编码为基本过程,而忽略新的绑定。例如,考虑如下过程:
(lambda (+ * a b x y)
(+ (* a x) (* b y)))
它计算 x 和 y 的线性组合。我们可能以 +matrix、*matrix 和四个矩阵为参数调用它,但开放式编码编译器仍会将 (+ (* a x) (* b y)) 中的 + 和 * 开放式编码为基本的 + 和 *。修改开放式编码编译器,使其查阅编译时环境,从而为涉及基本过程名称的表达式生成正确的代码。(只要程序不对这些名称执行 define 或 set!,代码便能正确运行。)
(lambda (+ * a b x y)
(+ (* a x) (* b y)))