Bläddra i källkod

edits thru 2.4

Jeremy Siek 3 år sedan
förälder
incheckning
d296c99cd2
1 ändrade filer med 71 tillägg och 65 borttagningar
  1. 71 65
      book.tex

+ 71 - 65
book.tex

@@ -1963,9 +1963,9 @@ following code uses method overriding to interpret \LangInt{} and
 %
 %
 \racket{the
 \racket{the
   \href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
   \href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
-  \index{subject}{class} feature of Racket}
+  \index{subject}{class} feature of Racket.}
 %
 %
-\python{a Python \code{class} definition}.
+\python{a Python \code{class} definition.}
 %
 %
 We define one class for each language and define a method for
 We define one class for each language and define a method for
 interpreting expressions inside each class. The class for \LangVar{}
 interpreting expressions inside each class. The class for \LangVar{}
@@ -2125,11 +2125,11 @@ value bound to a variable to all the uses of the variable. To
 accomplish this, we maintain a mapping from variables to values
 accomplish this, we maintain a mapping from variables to values
 called an \emph{environment}\index{subject}{environment}.
 called an \emph{environment}\index{subject}{environment}.
 %
 %
-We use%
+We use
 %
 %
-\racket{an association list (alist)}
+\racket{an association list (alist) }%
 %
 %
-\python{a Python \href{https://docs.python.org/3.10/library/stdtypes.html\#mapping-types-dict}{dictionary}}
+\python{a Python \href{https://docs.python.org/3.10/library/stdtypes.html\#mapping-types-dict}{dictionary} }%
 %
 %
 to represent the environment.
 to represent the environment.
 %
 %
@@ -2165,7 +2165,9 @@ variable, it looks up the corresponding value in the dictionary.
                [else (error 'interp_exp "expected an integer" r)])]
                [else (error 'interp_exp "expected an integer" r)])]
         [(Prim '- (list e)) (fx- 0 ((interp_exp env) e))]
         [(Prim '- (list e)) (fx- 0 ((interp_exp env) e))]
         [(Prim '+ (list e1 e2))
         [(Prim '+ (list e1 e2))
-         (fx+ ((interp_exp env) e1) ((interp_exp env) e2))]))
+         (fx+ ((interp_exp env) e1) ((interp_exp env) e2))]
+        [(Prim '- (list e1 e2))
+         (fx- ((interp_exp env) e1) ((interp_exp env) e2))]))
 
 
     (define/public (interp_program p)
     (define/public (interp_program p)
       (match p
       (match p
@@ -2180,6 +2182,8 @@ class InterpLint:
     match e:
     match e:
       case BinOp(left, Add(), right):
       case BinOp(left, Add(), right):
         return self.interp_exp(left, env) + self.interp_exp(right, env)
         return self.interp_exp(left, env) + self.interp_exp(right, env)
+      case BinOp(left, Sub(), right):
+        return self.interp_exp(left, env) - self.interp_exp(right, env)
       case UnaryOp(USub(), v):
       case UnaryOp(USub(), v):
         return - self.interp_exp(v, env)
         return - self.interp_exp(v, env)
       case Constant(value):
       case Constant(value):
@@ -2276,8 +2280,8 @@ criteria in the following diagram.
  \path[->] (p2) edge [right] node {\footnotesize\code{interp\_x86int}} (o);
  \path[->] (p2) edge [right] node {\footnotesize\code{interp\_x86int}} (o);
 \end{tikzpicture}
 \end{tikzpicture}
 \]
 \]
-In the next section we introduce the \LangXInt{} subset of x86 that
-suffices for compiling \LangVar{}.
+Next we introduce the \LangXInt{} subset of x86 that suffices for
+compiling \LangVar{}.
 
 
 \section{The \LangXInt{} Assembly Language}
 \section{The \LangXInt{} Assembly Language}
 \label{sec:x86}
 \label{sec:x86}
@@ -2398,7 +2402,7 @@ puts $10$ into register \key{rax} and then \lstinline{addq $32, %rax}
 adds $32$ to the $10$ in \key{rax} and
 adds $32$ to the $10$ in \key{rax} and
 puts the result, $42$, back into \key{rax}.
 puts the result, $42$, back into \key{rax}.
 %
 %
-The last instruction, \key{retq}, finishes the \key{main} function by
+The last instruction \key{retq} finishes the \key{main} function by
 returning the integer in \key{rax} to the operating system. The
 returning the integer in \key{rax} to the operating system. The
 operating system interprets this integer as the program's exit
 operating system interprets this integer as the program's exit
 code. By convention, an exit code of 0 indicates that a program
 code. By convention, an exit code of 0 indicates that a program
@@ -2436,13 +2440,13 @@ term \emph{pointer}\index{subject}{pointer} for something that
 contains an address. The stack grows downward in memory, so we
 contains an address. The stack grows downward in memory, so we
 increase the size of the stack by subtracting from the stack pointer.
 increase the size of the stack by subtracting from the stack pointer.
 In the context of a procedure call, the \emph{return
 In the context of a procedure call, the \emph{return
-address}\index{subject}{return address} is the instruction after the
+  address}\index{subject}{return address} is the instruction after the
 call instruction on the caller side. The function call instruction,
 call instruction on the caller side. The function call instruction,
 \code{callq}, pushes the return address onto the stack prior to
 \code{callq}, pushes the return address onto the stack prior to
 jumping to the procedure.  The register \key{rbp} is the \emph{base
 jumping to the procedure.  The register \key{rbp} is the \emph{base
-pointer}\index{subject}{base pointer} and is used to access variables
-that are stored in the frame of the current procedure call.  The base
-pointer of the caller is store after the return address. In
+  pointer}\index{subject}{base pointer} and is used to access
+variables that are stored in the frame of the current procedure call.
+The base pointer of the caller is stored after the return address. In
 Figure~\ref{fig:frame} we number the variables from $1$ to
 Figure~\ref{fig:frame} we number the variables from $1$ to
 $n$. Variable $1$ is stored at address $-8\key{(\%rbp)}$, variable $2$
 $n$. Variable $1$ is stored at address $-8\key{(\%rbp)}$, variable $2$
 at $-16\key{(\%rbp)}$, etc.
 at $-16\key{(\%rbp)}$, etc.
@@ -2515,19 +2519,20 @@ which pushes its return address on the stack and then jumps to
 by 16 bytes prior to the execution of any \code{callq} instruction, so
 by 16 bytes prior to the execution of any \code{callq} instruction, so
 when control arrives at \code{main}, the \code{rsp} is 8 bytes out of
 when control arrives at \code{main}, the \code{rsp} is 8 bytes out of
 alignment (because the \code{callq} pushed the return address).  The
 alignment (because the \code{callq} pushed the return address).  The
-first three instructions are the typical \emph{prelude}\index{subject}{prelude}
-for a procedure.  The instruction \code{pushq \%rbp} first subtracts $8$ from the stack
-pointer and then saves the base pointer of the caller at address
-\code{rsp} on the stack. The next instruction \code{movq \%rsp, \%rbp} sets the
-base pointer to the current stack pointer, which is pointing at the location
-of the old base pointer. The instruction \code{subq \$16, \%rsp} moves the stack
-pointer down to make enough room for storing variables.  This program
-needs one variable ($8$ bytes) but we round up to 16 bytes so that
-\code{rsp} is 16-byte aligned and we're ready to make calls to other
-functions.
-\racket{The last instruction of the prelude is \code{jmp start},
-which transfers control to the instructions that were generated from
-the expression \racket{\code{(+ 52 (- 10))}}\python{52 + -10}.}
+first three instructions are the typical
+\emph{prelude}\index{subject}{prelude} for a procedure.  The
+instruction \code{pushq \%rbp} first subtracts $8$ from the stack
+pointer \code{rsp} and then saves the base pointer of the caller at
+address \code{rsp} on the stack. The next instruction \code{movq
+  \%rsp, \%rbp} sets the base pointer to the current stack pointer,
+which is pointing at the location of the old base pointer. The
+instruction \code{subq \$16, \%rsp} moves the stack pointer down to
+make enough room for storing variables.  This program needs one
+variable ($8$ bytes) but we round up to 16 bytes so that \code{rsp} is
+16-byte aligned and we're ready to make calls to other functions.
+\racket{The last instruction of the prelude is \code{jmp start}, which
+  transfers control to the instructions that were generated from the
+  expression \racket{\code{(+ 52 (- 10))}}\python{52 + -10}.}
 
 
 \racket{The first instruction under the \code{start} label is}
 \racket{The first instruction under the \code{start} label is}
 %
 %
@@ -2535,7 +2540,8 @@ the expression \racket{\code{(+ 52 (- 10))}}\python{52 + -10}.}
 %
 %
 \code{movq \$10, -8(\%rbp)}, which stores $10$ in variable $1$.
 \code{movq \$10, -8(\%rbp)}, which stores $10$ in variable $1$.
 %
 %
-The instruction \code{negq -8(\%rbp)} changes variable $1$ to $-10$.
+The instruction \code{negq -8(\%rbp)} changes the contents of variable
+$1$ to $-10$.
 %
 %
 The next instruction moves the $-10$ from variable $1$ into the
 The next instruction moves the $-10$ from variable $1$ into the
 \code{rax} register.  Finally, \code{addq \$52, \%rax} adds $52$ to
 \code{rax} register.  Finally, \code{addq \$52, \%rax} adds $52$ to
@@ -2550,7 +2556,7 @@ the value in \code{rax}, updating its contents to $42$.
 The first two restore the \code{rsp} and \code{rbp} registers to the
 The first two restore the \code{rsp} and \code{rbp} registers to the
 state they were in at the beginning of the procedure. In particular,
 state they were in at the beginning of the procedure. In particular,
 \key{addq \$16, \%rsp} moves the stack pointer back to point at the
 \key{addq \$16, \%rsp} moves the stack pointer back to point at the
-old base pointer. Then \key{popq \%rbp} returns the old base pointer
+old base pointer. Then \key{popq \%rbp} restores the old base pointer
 to \key{rbp} and adds $8$ to the stack pointer.  The last instruction,
 to \key{rbp} and adds $8$ to the stack pointer.  The last instruction,
 \key{retq}, jumps back to the procedure that called this one and adds
 \key{retq}, jumps back to the procedure that called this one and adds
 $8$ to the stack pointer.
 $8$ to the stack pointer.
@@ -2574,7 +2580,7 @@ label associated with every block, which is why the \key{X86Program}
 struct includes an alist mapping labels to blocks. The reason for this
 struct includes an alist mapping labels to blocks. The reason for this
 organization becomes apparent in Chapter~\ref{ch:Lif} when we
 organization becomes apparent in Chapter~\ref{ch:Lif} when we
 introduce conditional branching. The \code{Block} structure includes
 introduce conditional branching. The \code{Block} structure includes
-an $\itm{info}$ field that is not needed for this chapter, but becomes
+an $\itm{info}$ field that is not needed for this chapter but becomes
 useful in Chapter~\ref{ch:register-allocation-Lvar}.  For now, the
 useful in Chapter~\ref{ch:register-allocation-Lvar}.  For now, the
 $\itm{info}$ field should contain an empty list.
 $\itm{info}$ field should contain an empty list.
 \fi}
 \fi}
@@ -2676,8 +2682,8 @@ down the problem into several steps, dealing with the above
 differences one at a time. Each of these steps is called a \emph{pass}
 differences one at a time. Each of these steps is called a \emph{pass}
 of the compiler.\index{subject}{pass}\index{subject}{compiler pass}
 of the compiler.\index{subject}{pass}\index{subject}{compiler pass}
 %
 %
-This terminology comes from the way each step passes over, that is,
-traverses the AST of the program.
+This terminology comes from the way each step passes over, or
+traverses, the AST of the program.
 %
 %
 Furthermore, we follow the nanopass approach, which means we strive
 Furthermore, we follow the nanopass approach, which means we strive
 for each pass to accomplish one clear objective (not two or three at
 for each pass to accomplish one clear objective (not two or three at
@@ -2712,10 +2718,10 @@ Our compiler for \LangVar{} consists of the following passes.
   
   
 {\if\edition\racketEd
 {\if\edition\racketEd
 \item[\key{explicate\_control}] makes the execution order of the
 \item[\key{explicate\_control}] makes the execution order of the
-  program explicit. It converts the abstract syntax tree representation
-  into a control-flow graph in which each node contains a sequence of
-  statements and the edges between nodes say which nodes contain jumps
-  to other nodes.
+  program explicit. It converts the abstract syntax tree
+  representation into a graph in which each node contains a sequence
+  of statements and the edges between nodes say which nodes contain
+  jumps to other nodes.
 \fi}
 \fi}
 
 
 \item[\key{select\_instructions}] handles the difference between
 \item[\key{select\_instructions}] handles the difference between
@@ -2742,8 +2748,8 @@ The next question is: in what order should we apply these passes? This
 question can be challenging because it is difficult to know ahead of
 question can be challenging because it is difficult to know ahead of
 time which orderings will be better (easier to implement, produce more
 time which orderings will be better (easier to implement, produce more
 efficient code, etc.) so oftentimes trial-and-error is
 efficient code, etc.) so oftentimes trial-and-error is
-involved. Nevertheless, we can try to plan ahead and make educated
-choices regarding the ordering.
+involved. Nevertheless, we can plan ahead and make educated choices
+regarding the ordering.
 
 
 \racket{What should be the ordering of \key{explicate\_control} with respect to
 \racket{What should be the ordering of \key{explicate\_control} with respect to
 \key{uniquify}? The \key{uniquify} pass should come first because
 \key{uniquify}? The \key{uniquify} pass should come first because
@@ -2751,12 +2757,12 @@ choices regarding the ordering.
 become local variables whose scope is the entire program, which would
 become local variables whose scope is the entire program, which would
 confuse variables with the same name.}
 confuse variables with the same name.}
 %
 %
-\racket{We place \key{remove\_complex\_opera*} before \key{explicate\_control}
+\racket{We place \key{remove\_complex\_operands} before \key{explicate\_control}
 because the later removes the \key{let} form, but it is convenient to
 because the later removes the \key{let} form, but it is convenient to
-use \key{let} in the output of \key{remove\_complex\_opera*}.}
+use \key{let} in the output of \key{remove\_complex\_operands}.}
 %
 %
 \racket{The ordering of \key{uniquify} with respect to
 \racket{The ordering of \key{uniquify} with respect to
-\key{remove\_complex\_opera*} does not matter so we arbitrarily choose
+\key{remove\_complex\_operands} does not matter so we arbitrarily choose
 \key{uniquify} to come first.}
 \key{uniquify} to come first.}
 
 
 The \key{select\_instructions} and \key{assign\_homes} passes are
 The \key{select\_instructions} and \key{assign\_homes} passes are
@@ -2836,13 +2842,13 @@ The last pass, \key{prelude\_and\_conclusion}, places the program
 instructions inside a \code{main} function with instructions for the
 instructions inside a \code{main} function with instructions for the
 prelude and conclusion.
 prelude and conclusion.
 %
 %
-\racket{In the following section we discuss the \LangCVar{}
-  intermediate language.}
+\racket{In the next section we discuss the \LangCVar{} intermediate
+  language that serves as the output of \code{explicate\_control}.}
 %
 %
 The remainder of this chapter provides guidance on the implementation
 The remainder of this chapter provides guidance on the implementation
 of each of the compiler passes in Figure~\ref{fig:Lvar-passes}.
 of each of the compiler passes in Figure~\ref{fig:Lvar-passes}.
 
 
-%% The output of \key{uniquify} and \key{remove-complex-opera*}
+%% The output of \key{uniquify} and \key{remove-complex-operands}
 %% are programs that are still in the \LangVar{} language, though the
 %% are programs that are still in the \LangVar{} language, though the
 %% output of the later is a subset of \LangVar{} named \LangVarANF{}
 %% output of the later is a subset of \LangVar{} named \LangVarANF{}
 %% (Section~\ref{sec:remove-complex-opera-Lvar}).
 %% (Section~\ref{sec:remove-complex-opera-Lvar}).
@@ -2882,8 +2888,8 @@ language~\citep{Kernighan:1988nx} in that it has separate syntactic
 categories for expressions and statements, so we name it \LangCVar{}.
 categories for expressions and statements, so we name it \LangCVar{}.
 This style of intermediate language is also known as
 This style of intermediate language is also known as
 \emph{three-address code}, to emphasize that the typical form of a
 \emph{three-address code}, to emphasize that the typical form of a
-statement is \CASSIGN{\key{x}}{\CADD{\key{y}}{\key{z}}} involves three
-addresses~\citep{Aho:2006wb}.
+statement such as \CASSIGN{\key{x}}{\CADD{\key{y}}{\key{z}}} involves three
+addresses: \code{x}, \code{y}, and \code{z}~\citep{Aho:2006wb}.
 
 
 The concrete syntax for \LangCVar{} is defined in
 The concrete syntax for \LangCVar{} is defined in
 Figure~\ref{fig:c0-concrete-syntax} and the abstract syntax for
 Figure~\ref{fig:c0-concrete-syntax} and the abstract syntax for
@@ -2897,7 +2903,8 @@ assignment statements which can be executed in sequence using the
 \key{Return}, a guarantee that is baked into the grammar rules for
 \key{Return}, a guarantee that is baked into the grammar rules for
 \itm{tail}. The naming of this non-terminal comes from the term
 \itm{tail}. The naming of this non-terminal comes from the term
 \emph{tail position}\index{subject}{tail position}, which refers to an
 \emph{tail position}\index{subject}{tail position}, which refers to an
-expression that is the last one to execute within a function.
+expression that is the last one to execute within a function or
+program.
 
 
 A \LangCVar{} program consists of an alist mapping labels to
 A \LangCVar{} program consists of an alist mapping labels to
 tails. This is more general than necessary for the present chapter, as
 tails. This is more general than necessary for the present chapter, as
@@ -2990,40 +2997,42 @@ with a \key{let} nested inside the initializing expression of another
 \end{transformation}
 \end{transformation}
 
 
 We recommend implementing \code{uniquify} by creating a structurally
 We recommend implementing \code{uniquify} by creating a structurally
-recursive function named \code{uniquify-exp} that mostly just copies
+recursive function named \code{uniquify\_exp} that mostly just copies
 an expression. However, when encountering a \key{let}, it should
 an expression. However, when encountering a \key{let}, it should
 generate a unique name for the variable and associate the old name
 generate a unique name for the variable and associate the old name
 with the new name in an alist.\footnote{The Racket function
 with the new name in an alist.\footnote{The Racket function
   \code{gensym} is handy for generating unique variable names.} The
   \code{gensym} is handy for generating unique variable names.} The
-\code{uniquify-exp} function needs to access this alist when it gets
-to a variable reference, so we add a parameter to \code{uniquify-exp}
+\code{uniquify\_exp} function needs to access this alist when it gets
+to a variable reference, so we add a parameter to \code{uniquify\_exp}
 for the alist.
 for the alist.
 
 
-The skeleton of the \code{uniquify-exp} function is shown in
-Figure~\ref{fig:uniquify-Lvar}.  The function is curried so that it is
-convenient to partially apply it to an alist and then apply it to
-different expressions, as in the last case for primitive operations in
-Figure~\ref{fig:uniquify-Lvar}.  The
+The skeleton of the \code{uniquify\_exp} function is shown in
+Figure~\ref{fig:uniquify-Lvar}.
+%% The function is curried so that it is
+%% convenient to partially apply it to an alist and then apply it to
+%% different expressions, as in the last case for primitive operations in
+%% Figure~\ref{fig:uniquify-Lvar}.
+The
 %
 %
 \href{https://docs.racket-lang.org/reference/for.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%2Flist%29%29}{\key{for/list}}
 \href{https://docs.racket-lang.org/reference/for.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%2Flist%29%29}{\key{for/list}}
 %
 %
-form of Racket is useful for transforming each element of a list to
+form of Racket is useful for transforming the element of a list to
 produce a new list.\index{subject}{for/list}
 produce a new list.\index{subject}{for/list}
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}
 \begin{lstlisting}
-(define (uniquify-exp env)
+(define (uniquify_exp env)
   (lambda (e)
   (lambda (e)
     (match e
     (match e
       [(Var x) ___]
       [(Var x) ___]
       [(Int n) (Int n)]
       [(Int n) (Int n)]
       [(Let x e body) ___]
       [(Let x e body) ___]
       [(Prim op es)
       [(Prim op es)
-       (Prim op (for/list ([e es]) ((uniquify-exp env) e)))])))
+       (Prim op (for/list ([e es]) ((uniquify_exp env) e)))])))
 
 
 (define (uniquify p)
 (define (uniquify p)
   (match p
   (match p
-    [(Program '() e) (Program '() ((uniquify-exp '()) e))]))
+    [(Program '() e) (Program '() ((uniquify_exp '()) e))]))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Skeleton for the \key{uniquify} pass.}
 \caption{Skeleton for the \key{uniquify} pass.}
 \label{fig:uniquify-Lvar}
 \label{fig:uniquify-Lvar}
@@ -3328,7 +3337,7 @@ regarding file names described in Exercise~\ref{ex:Lvar}.
 In the \code{run-tests.rkt} script, add the following entry to the
 In the \code{run-tests.rkt} script, add the following entry to the
 list of \code{passes} and then run the script to test your compiler.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \begin{lstlisting}
-(list "remove-complex" remove-complex-opera* interp_Lvar type-check-Lvar)
+(list "remove-complex" remove-complex-operands interp_Lvar type-check-Lvar)
 \end{lstlisting}
 \end{lstlisting}
 While debugging your compiler, it is often useful to see the
 While debugging your compiler, it is often useful to see the
 intermediate programs that are output from each pass. To print the
 intermediate programs that are output from each pass. To print the
@@ -6529,7 +6538,6 @@ respectively. The \LangIf{} language includes all of
 \FALSE{},\racket{ and} the \code{if} expression\python{, and the
 \FALSE{},\racket{ and} the \code{if} expression\python{, and the
   \code{if}  statement}. We expand the set of operators to include
   \code{if}  statement}. We expand the set of operators to include
 \begin{enumerate}
 \begin{enumerate}
-\item subtraction on integers,
 \item the logical operators \key{and}, \key{or}, and \key{not},
 \item the logical operators \key{and}, \key{or}, and \key{not},
 \item the \racket{\key{eq?} operation}\python{\key{==} and \key{!=} operations}
 \item the \racket{\key{eq?} operation}\python{\key{==} and \key{!=} operations}
   for comparing integers or Booleans for equality, and
   for comparing integers or Booleans for equality, and
@@ -6550,7 +6558,7 @@ respectively. The \LangIf{} language includes all of
    \Type &::=& \key{Boolean} \\
    \Type &::=& \key{Boolean} \\
     \itm{bool} &::=& \TRUE \MID \FALSE \\  
     \itm{bool} &::=& \TRUE \MID \FALSE \\  
     \itm{cmp} &::= & \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=} \\
     \itm{cmp} &::= & \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=} \\
-    \Exp &::=& \CSUB{\Exp}{\Exp} \MID \itm{bool}
+    \Exp &::=& \itm{bool}
         \MID (\key{and}\;\Exp\;\Exp) \MID (\key{or}\;\Exp\;\Exp)
         \MID (\key{and}\;\Exp\;\Exp) \MID (\key{or}\;\Exp\;\Exp)
         \MID (\key{not}\;\Exp) \\
         \MID (\key{not}\;\Exp) \\
         &\MID& (\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} 
         &\MID& (\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} 
@@ -6736,8 +6744,6 @@ class InterpLif(InterpLvar):
           return self.interp_exp(body, env)
           return self.interp_exp(body, env)
         else:
         else:
           return self.interp_exp(orelse, env)
           return self.interp_exp(orelse, env)
-      case BinOp(left, Sub(), right):
-        return self.interp_exp(left, env) - self.interp_exp(right, env)
       case UnaryOp(Not(), v):
       case UnaryOp(Not(), v):
         return not self.interp_exp(v, env)
         return not self.interp_exp(v, env)
       case BoolOp(And(), values):
       case BoolOp(And(), values):
@@ -7623,7 +7629,7 @@ Run the script to test your compiler on all the test programs.
 \section{Uniquify Variables}
 \section{Uniquify Variables}
 \label{sec:uniquify-Lif}
 \label{sec:uniquify-Lif}
 
 
-Add cases to \code{uniquify-exp} to handle Boolean constants and
+Add cases to \code{uniquify\_exp} to handle Boolean constants and
 \code{if} expressions.
 \code{if} expressions.
 
 
 \begin{exercise}\normalfont
 \begin{exercise}\normalfont
@@ -7728,7 +7734,7 @@ code in this pass.
 In the \code{run-tests.rkt} script, add the following entry to the
 In the \code{run-tests.rkt} script, add the following entry to the
 list of \code{passes} and then run the script to test your compiler.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \begin{lstlisting}
-(list "remove-complex" remove-complex-opera* interp-Lif type-check-Lif)
+(list "remove-complex" remove-complex-operands interp-Lif type-check-Lif)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 \end{exercise}
 \end{exercise}