Browse Source

proof reading

Jeremy Siek 4 years ago
parent
commit
3e015e62e0
1 changed files with 257 additions and 193 deletions
  1. 257 193
      book.tex

+ 257 - 193
book.tex

@@ -1331,7 +1331,7 @@ extensible way.
 Having justified the use of classes and methods to implement
 Having justified the use of classes and methods to implement
 interpreters, we turn to the definitional interpreter for \LangVar{}
 interpreters, we turn to the definitional interpreter for \LangVar{}
 in Figure~\ref{fig:interp-Rvar}. It is similar to the interpreter for
 in Figure~\ref{fig:interp-Rvar}. It is similar to the interpreter for
-\LangInt{} but adds two new \key{match} clauses for variables and
+\LangInt{} but adds two new \key{match} cases for variables and
 \key{let}.  For \key{let} we need a way to communicate the value bound
 \key{let}.  For \key{let} we need a way to communicate the value bound
 to a variable to all the uses of the variable. To accomplish this, we
 to a variable to all the uses of the variable. To accomplish this, we
 maintain a mapping from variables to values. Throughout the compiler
 maintain a mapping from variables to values. Throughout the compiler
@@ -1973,8 +1973,8 @@ for the alist.
 The skeleton of the \code{uniquify-exp} function is shown in
 The skeleton of the \code{uniquify-exp} function is shown in
 Figure~\ref{fig:uniquify-Rvar}.  The function is curried so that it is
 Figure~\ref{fig:uniquify-Rvar}.  The function is curried so that it is
 convenient to partially apply it to an alist and then apply it to
 convenient to partially apply it to an alist and then apply it to
-different expressions, as in the last clause for primitive operations
-in Figure~\ref{fig:uniquify-Rvar}.  The
+different expressions, as in the last case for primitive operations in
+Figure~\ref{fig:uniquify-Rvar}.  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}}
 %
 %
@@ -1985,7 +1985,7 @@ produce a new list.\index{for/list}
 \normalfont % I don't like the italics for exercises. -Jeremy
 \normalfont % I don't like the italics for exercises. -Jeremy
 
 
 Complete the \code{uniquify} pass by filling in the blanks in
 Complete the \code{uniquify} pass by filling in the blanks in
-Figure~\ref{fig:uniquify-Rvar}, that is, implement the clauses for
+Figure~\ref{fig:uniquify-Rvar}, that is, implement the cases for
 variables and for the \key{let} form in the file \code{compiler.rkt}
 variables and for the \key{let} form in the file \code{compiler.rkt}
 in the support code.
 in the support code.
 \end{exercise}
 \end{exercise}
@@ -2012,17 +2012,29 @@ in the support code.
 \begin{exercise}
 \begin{exercise}
 \normalfont % I don't like the italics for exercises. -Jeremy
 \normalfont % I don't like the italics for exercises. -Jeremy
 
 
-Creating five \LangVar{} programs to test the most interesting parts
-of the \key{uniquify} pass, that is, the programs should include
+Create five \LangVar{} programs that exercise the most interesting
+parts of the \key{uniquify} pass, that is, the programs should include
 \key{let} forms, variables, and variables that overshadow each other.
 \key{let} forms, variables, and variables that overshadow each other.
 The five programs should be placed in the subdirectory named
 The five programs should be placed in the subdirectory named
 \key{tests} and the file names should start with \code{var\_test\_}
 \key{tests} and the file names should start with \code{var\_test\_}
 followed by a unique integer and end with the file extension
 followed by a unique integer and end with the file extension
-\key{.rkt}. Run the \key{run-tests.rkt} script in the support code to
-check whether the output programs produce the same result as the input
-programs. The script uses the \key{interp-tests} function
+\key{.rkt}.
+%
+The \key{run-tests.rkt} script in the support code checks whether the
+output programs produce the same result as the input programs.  The
+script uses the \key{interp-tests} function
 (Appendix~\ref{appendix:utilities}) from \key{utilities.rkt} to test
 (Appendix~\ref{appendix:utilities}) from \key{utilities.rkt} to test
-your \key{uniquify} pass on the example programs.
+your \key{uniquify} pass on the example programs.  The \code{passes}
+parameter of \key{interp-tests} is a list that should have one entry
+for each pass in your compiler.  For now, define \code{passes} to
+contain just one entry for \code{uniquify} as follows.
+\begin{lstlisting}
+(define passes 
+  (list (list "uniquify" uniquify interp-Rvar type-check-Rvar)))
+\end{lstlisting}
+Run the \key{run-tests.rkt} script in the support code to check
+whether the output programs produce the same result as the input
+programs.
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2040,7 +2052,7 @@ operand, as shown in the output of \code{remove-complex-opera*} on the
 right.\\
 right.\\
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.4\textwidth}
 \begin{minipage}{0.4\textwidth}
-% s0_19.rkt
+% var_test_19.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (+ 52 (- 10))
 (+ 52 (- 10))
 \end{lstlisting}
 \end{lstlisting}
@@ -2126,7 +2138,7 @@ variable to an atomic expression. You should leave such variable
 bindings unchanged, as shown in to the program on the right \\
 bindings unchanged, as shown in to the program on the right \\
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.4\textwidth}
 \begin{minipage}{0.4\textwidth}
-% s0_20.rkt
+% var_test_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([a 42])
 (let ([a 42])
   (let ([b a])
   (let ([b a])
@@ -2156,14 +2168,20 @@ produce the following output with unnecessary temporary variables.\\
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
 
 
-\begin{exercise}
-  \normalfont Implement the \code{remove-complex-opera*} in
-  \code{compiler.rkt}.  Create three new \LangInt{} programs that are
-  designed to exercise the interesting code in the
-  \code{remove-complex-opera*} pass (Following the same file name
-  guidelines as before.). In the \code{run-tests.rkt} script,
-  uncomment the line for this pass in the list of \code{passes} and
-  then run the script to test your compiler.
+\begin{exercise}\normalfont
+%
+Implement the \code{remove-complex-opera*} function in
+\code{compiler.rkt}.
+%
+Create three new \LangInt{} programs that exercise the interesting
+code in the \code{remove-complex-opera*} pass (Following the same file
+name guidelines as before.).
+%
+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.
+\begin{lstlisting}
+(list "remove complex" remove-complex-opera* interp-Rvar type-check-Rvar)
+\end{lstlisting}
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2175,7 +2193,7 @@ programs that make the order of execution explicit in their
 syntax. For now this amounts to flattening \key{let} constructs into a
 syntax. For now this amounts to flattening \key{let} constructs into a
 sequence of assignment statements. For example, consider the following
 sequence of assignment statements. For example, consider the following
 \LangVar{} program.\\
 \LangVar{} program.\\
-% s0_11.rkt
+% var_test_11.rkt
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([y (let ([x 20])
 (let ([y (let ([x 20])
@@ -2274,6 +2292,18 @@ statements. We warn against that alternative because the
 accumulator-passing style is key to how we generate high-quality code
 accumulator-passing style is key to how we generate high-quality code
 for conditional expressions in Chapter~\ref{ch:bool-types}.
 for conditional expressions in Chapter~\ref{ch:bool-types}.
 
 
+\begin{exercise}\normalfont
+%
+Implement the \code{explicate-control} function in
+\code{compiler.rkt}.  Create three new \LangInt{} programs that
+exercise the code in \code{explicate-control}.
+%
+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.
+\begin{lstlisting}
+(list "explicate control" explicate-control interp-Cvar type-check-Cvar)  
+\end{lstlisting}
+\end{exercise}
 
 
 \section{Select Instructions}
 \section{Select Instructions}
 \label{sec:select-r1}
 \label{sec:select-r1}
@@ -2376,10 +2406,13 @@ recursively and then append the resulting instructions.
 \begin{exercise}
 \begin{exercise}
 \normalfont Implement the \key{select-instructions} pass in
 \normalfont Implement the \key{select-instructions} pass in
 \code{compiler.rkt}. Create three new example programs that are
 \code{compiler.rkt}. Create three new example programs that are
-designed to exercise all of the interesting cases in this pass.  In
-the \code{run-tests.rkt} script, uncomment the line for this pass in
-the list of \code{passes} and then run the script to test your
-compiler.
+designed to exercise all of the interesting cases in this pass.
+%
+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.
+\begin{lstlisting}
+(list "instruction selection" select-instructions interp-pseudo-x86-0)
+\end{lstlisting}
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2399,7 +2432,7 @@ Chapter~\ref{ch:register-allocation-r1}.
 
 
 Consider again the following \LangVar{} program from
 Consider again the following \LangVar{} program from
 Section~\ref{sec:remove-complex-opera-Rvar}.
 Section~\ref{sec:remove-complex-opera-Rvar}.
-% s0_20.rkt
+% var_test_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([a 42])
 (let ([a 42])
   (let ([b a])
   (let ([b a])
@@ -2455,9 +2488,13 @@ Implement the \key{assign-homes} pass in \code{compiler.rkt}, defining
 auxiliary functions for the non-terminals \Arg{}, \Instr{}, and
 auxiliary functions for the non-terminals \Arg{}, \Instr{}, and
 \Block{}.  We recommend that the auxiliary functions take an extra
 \Block{}.  We recommend that the auxiliary functions take an extra
 parameter that is an alist mapping variable names to homes (stack
 parameter that is an alist mapping variable names to homes (stack
-locations for now).  In the \code{run-tests.rkt} script, uncomment the
-line for this pass in the list of \code{passes} and then run the
-script to test your compiler.
+locations for now).
+%
+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.
+\begin{lstlisting}
+(list "assign homes" assign-homes interp-x86-0)
+\end{lstlisting}
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2470,7 +2507,7 @@ restriction that at most one argument of an instruction may be a
 memory reference.
 memory reference.
 
 
 We return to the following example.
 We return to the following example.
-% s0_20.rkt
+% var_test_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
    (let ([a 42])
    (let ([a 42])
      (let ([b a])
      (let ([b a])
@@ -2500,10 +2537,13 @@ from \key{rax} to the destination location, as follows.
 \begin{exercise}
 \begin{exercise}
 \normalfont Implement the \key{patch-instructions} pass in
 \normalfont Implement the \key{patch-instructions} pass in
 \code{compiler.rkt}. Create three new example programs that are
 \code{compiler.rkt}. Create three new example programs that are
-designed to exercise all of the interesting cases in this pass.  In
-the \code{run-tests.rkt} script, uncomment the line for this pass in
-the list of \code{passes} and then run the script to test your
-compiler.
+designed to exercise all of the interesting cases in this pass.
+%
+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.
+\begin{lstlisting}
+(list "patch instructions" patch-instructions interp-x86-0)
+\end{lstlisting}
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2527,15 +2567,21 @@ labels like \key{main}. The Racket call \code{(system-type 'os)} is
 useful for determining which operating system the compiler is running
 useful for determining which operating system the compiler is running
 on. It returns \code{'macosx}, \code{'unix}, or \code{'windows}.
 on. It returns \code{'macosx}, \code{'unix}, or \code{'windows}.
 
 
-\begin{exercise}
-  \normalfont Implement the \key{print-x86} pass in
-  \code{compiler.rkt}. Uncomment the line for this pass in the list of
-  \code{passes} in the \code{run-tests.rkt} script. Also uncomment the
-  call to the \key{compiler-tests} function
-  (Appendix~\ref{appendix:utilities}), which tests your complete
-  compiler by executing the generated x86 code. Compile the provided
-  \key{runtime.c} file to \key{runtime.o} using \key{gcc}. Run the
-  script to test your compiler.
+\begin{exercise}\normalfont
+%
+Implement the \key{print-x86} pass in \code{compiler.rkt}.
+%
+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.
+\begin{lstlisting}
+(list "print x86" print-x86 #f)
+\end{lstlisting}
+%  
+Uncomment the call to the \key{compiler-tests} function
+(Appendix~\ref{appendix:utilities}), which tests your complete
+compiler by executing the generated x86 code. Compile the provided
+\key{runtime.c} file to \key{runtime.o} using \key{gcc}. Run the
+script to test your compiler.
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -2614,7 +2660,7 @@ in the x86 assembly language but it still uses variables.
 \begin{figure}
 \begin{figure}
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
 Example \LangVar{} program:
 Example \LangVar{} program:
-% s0_28.rkt
+% var_test_28.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([v 1])
 (let ([v 1])
   (let ([w 42])
   (let ([w 42])
@@ -2818,7 +2864,7 @@ instruction.  \index{prelude}\index{conclusion}
 \begin{figure}[tp]
 \begin{figure}[tp]
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
 Example \LangVar{} program:
 Example \LangVar{} program:
-%s0_14.rkt
+%var_test_14.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x (read)])
 (let ([x (read)])
   (let ([y (read)])
   (let ([y (read)])
@@ -4173,7 +4219,7 @@ done in the prelude. We move the stack pointer up by \code{8} bytes
 
 
   
   
 \begin{figure}[tbp]
 \begin{figure}[tbp]
-  % s0_28.rkt
+  % var_test_28.rkt
   % (use-minimal-set-of-registers! #t)
   % (use-minimal-set-of-registers! #t)
   % and only rbx rcx
   % and only rbx rcx
 % tmp 0 rbx
 % tmp 0 rbx
@@ -4359,7 +4405,7 @@ evaluated if $e_1$ evaluates to \code{\#f}.
 
 
 With the increase in the number of primitive operations, the
 With the increase in the number of primitive operations, the
 interpreter would become repetitive without some care.  We refactor
 interpreter would become repetitive without some care.  We refactor
-the clause for \code{Prim}, moving the code that differs with each
+the case for \code{Prim}, moving the code that differs with each
 operation into the \code{interp-op} method shown in in
 operation into the \code{interp-op} method shown in in
 Figure~\ref{fig:interp-op-Rif}. We handle the \code{and} operation
 Figure~\ref{fig:interp-op-Rif}. We handle the \code{and} operation
 separately because of its short-circuiting behavior.
 separately because of its short-circuiting behavior.
@@ -4479,10 +4525,10 @@ error or returns an expression and its type (\key{Integer} or
 \key{Boolean}). It returns an expression because there are situations
 \key{Boolean}). It returns an expression because there are situations
 in which we want to change or update the expression.
 in which we want to change or update the expression.
 
 
-Next we discuss the \code{match} clauses in \code{type-check-exp} of
+Next we discuss the \code{match} cases in \code{type-check-exp} of
 Figure~\ref{fig:type-check-Rvar}.  The type of an integer constant is
 Figure~\ref{fig:type-check-Rvar}.  The type of an integer constant is
 \code{Integer}.  To handle variables, the type checker uses the
 \code{Integer}.  To handle variables, the type checker uses the
-environment \code{env} to map variables to types. Consider the clause
+environment \code{env} to map variables to types. Consider the case
 for \key{let}.  We type check the initializing expression to obtain
 for \key{let}.  We type check the initializing expression to obtain
 its type \key{T} and then associate type \code{T} with the variable
 its type \key{T} and then associate type \code{T} with the variable
 \code{x} in the environment used to type check the body of the
 \code{x} in the environment used to type check the body of the
@@ -4892,9 +4938,9 @@ interfere with the generation of high-quality output in the
 \Exp &::=& \gray{ \Atm \mid \READ{} } \\
 \Exp &::=& \gray{ \Atm \mid \READ{} } \\
      &\mid& \gray{ \NEG{\Atm} \mid \ADD{\Atm}{\Atm} } \\
      &\mid& \gray{ \NEG{\Atm} \mid \ADD{\Atm}{\Atm} } \\
      &\mid& \gray{ \LET{\Var}{\Exp}{\Exp} } \\
      &\mid& \gray{ \LET{\Var}{\Exp}{\Exp} } \\
-     &\mid& \UNIOP{\key{'not}}{\Atm} \\
+     &\mid& \UNIOP{\key{not}}{\Atm} \\
       &\mid& \BINOP{\itm{cmp}}{\Atm}{\Atm} \mid \IF{\Exp}{\Exp}{\Exp} \\
       &\mid& \BINOP{\itm{cmp}}{\Atm}{\Atm} \mid \IF{\Exp}{\Exp}{\Exp} \\
-R^{\dagger}_2  &::=& \PROGRAM{\code{'()}}{\Exp}
+R^{\dagger}_2  &::=& \PROGRAM{\code{()}}{\Exp}
 \end{array}
 \end{array}
 \]
 \]
 \end{minipage}
 \end{minipage}
@@ -4913,7 +4959,7 @@ addition of \key{if} this get more interesting.
 
 
 As a motivating example, consider the following program that has an
 As a motivating example, consider the following program that has an
 \key{if} expression nested in the predicate of another \key{if}.
 \key{if} expression nested in the predicate of another \key{if}.
-% s1_41.rkt
+% cond_test_41.rkt
 \begin{center}
 \begin{center}
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
@@ -5025,7 +5071,7 @@ comparison \lstinline{(eq? x 0)} and then branch to \code{block38} or
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.4\textwidth}
 \begin{minipage}{0.4\textwidth}
-% s1_41.rkt
+% cond_test_41.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x (read)])
 (let ([x (read)])
    (let ([y (read)])
    (let ([y (read)])
@@ -5095,50 +5141,61 @@ the \key{if}. We need another function, \code{explicate-pred}, that
 takes an \LangIf{} expression and two blocks for the then-branch and
 takes an \LangIf{} expression and two blocks for the then-branch and
 else-branch. The output of \code{explicate-pred} is a block.
 else-branch. The output of \code{explicate-pred} is a block.
 %
 %
-%% Note that the three explicate functions need to construct a
-%% control-flow graph, which we recommend they do via updates to a global
-%% variable.
-%
 In the following paragraphs we discuss specific cases in the
 In the following paragraphs we discuss specific cases in the
 \code{explicate-pred} function as well as additions to the
 \code{explicate-pred} function as well as additions to the
 \code{explicate-tail} and \code{explicate-assign} functions.
 \code{explicate-tail} and \code{explicate-assign} functions.
 
 
-The function \code{explicate-pred} will need a case for every
-expression that can have type \code{Boolean}. We detail a few cases
-here and leave the rest for the reader. The input to this function is
-an expression and two blocks, $B_1$ and $B_2$, for the two branches of
-the enclosing \key{if}. Suppose the expression is the Boolean
-\code{\#t}.  Then we can perform a kind of partial evaluation
-\index{partial evaluation} and translate it to the ``then'' branch
-$B_1$. Likewise, we translate \code{\#f} to the ``else`` branch $B_2$.
-\[
-\key{\#t} \quad\Rightarrow\quad B_1,
-\qquad\qquad\qquad
-\key{\#f} \quad\Rightarrow\quad B_2
-\]
-These two cases demonstrate that we sometimes discard one of the
-blocks that are input to \code{explicate-pred}. We want the blocks
-that we actually use to appear in the resulting control-flow graph,
-but not the discarded blocks. We return to this issue later.
+\begin{figure}[tbp]
+\begin{lstlisting}
+(define (explicate-pred cnd thn els)
+  (match cnd
+    [(Var x) ___]
+    [(Let x rhs body) ___]
+    [(Prim 'not (list e)) ___]
+    [(Prim op es) #:when (or (eq? op 'eq?) (eq? op '<))
+     (IfStmt (Prim op arg*) (force (block->goto thn))
+              (force (block->goto els)))]
+    [(Bool b) (if b thn els)]
+    [(If cnd^ thn^ els^) ___]
+    [else (error "explicate-pred unhandled case" cnd)]))
+\end{lstlisting}
+\caption{Skeleton for the \key{explicate-pred} auxiliary function.}
+\label{fig:explicate-pred}
+\end{figure}
+
+The skeleton for the \code{explicate-pred} function is given in
+Figure~\ref{fig:explicate-pred}. It has a case for every expression
+that can have type \code{Boolean}.  We detail a few cases here and
+leave the rest for the reader. The input to this function is an
+expression and two blocks, \code{thn} and \code{els}, for the two
+branches of the enclosing \key{if}.
+%
+Consider the case for Boolean constants in
+Figure~\ref{fig:explicate-pred}.  We perform a kind of partial
+evaluation\index{partial evaluation} and output either the \code{thn}
+or \code{els} branch depending on whether the constant is true or
+false. This case demonstrates that we sometimes discard the \code{thn}
+or \code{els} blocks that are input to \code{explicate-pred}.
 
 
 The case for \key{if} in \code{explicate-pred} is particularly
 The case for \key{if} in \code{explicate-pred} is particularly
 illuminating because it deals with the challenges we discussed above
 illuminating because it deals with the challenges we discussed above
-regarding the example of the nested \key{if} expressions.  The
-``then'' and ``else'' branches of the current \key{if} inherit their
-context from the current one, that is, predicate context. So we
-recursively apply \code{explicate-pred} to the ``then'' and ``else''
-branches. For both of those recursive calls, we pass the blocks $B_1$
-and $B_2$. Thus, $B_1$ may get used twice, once inside each recursive
-call, and likewise for $B_2$. As discussed above, to avoid duplicating
-code, we need to add these blocks to the control-flow graph so that we
-can instead refer to them by name and execute them with a
-\key{goto}. However, as we saw in the cases above for \key{\#t} and
-\key{\#f}, the blocks $B_1$ or $B_2$ may not get used at all and we
-don't want to prematurely add them to the control-flow graph if they
-end up being discarded.
+regarding nested \key{if} expressions
+(Figure~\ref{fig:explicate-control-s1-38}).  The \lstinline{thn^} and
+\lstinline{els^} branches of the \key{if} inherit their context from
+the current one, that is, predicate context. So you should recursively
+apply \code{explicate-pred} to the \lstinline{thn^} and
+\lstinline{els^} branches. For both of those recursive calls, pass
+\code{thn} and \code{els} as the extra parameters. Thus, \code{thn}
+and \code{els} may get used twice, once inside each recursive call. As
+discussed above, to avoid duplicating code, we need to add them to the
+control-flow graph so that we can instead refer to them by name and
+execute them with a \key{goto}. However, as we saw in the cases above
+for Boolean constants, the blocks \code{thn} and \code{els} may not
+get used at all and we don't want to prematurely add them to the
+control-flow graph if they end up being discarded.
 
 
 The solution to this conundrum is to use \emph{lazy
 The solution to this conundrum is to use \emph{lazy
-  evaluation}\index{lazy evaluation} \citep{Friedman:1976aa} to delay
+  evaluation}\index{lazy evaluation}\citep{Friedman:1976aa} to delay
 adding the blocks to the control-flow graph until the points where we
 adding the blocks to the control-flow graph until the points where we
 know they will be used. Racket provides support for lazy evaluation
 know they will be used. Racket provides support for lazy evaluation
 with the
 with the
@@ -5150,21 +5207,24 @@ $p$\key{)}\index{force} is applied to a promise $p$ for the first
 time, the expressions $e_1 \ldots e_n$ are evaluated and the result of
 time, the expressions $e_1 \ldots e_n$ are evaluated and the result of
 $e_n$ is cached in the promise and returned. If \code{force} is
 $e_n$ is cached in the promise and returned. If \code{force} is
 applied again to the same promise, then the cached result is returned.
 applied again to the same promise, then the cached result is returned.
+If \code{force} is applied to an argument that is not a promise,
+\code{force} simply returns the argument.
 
 
 We use lazy evaluation for the input and output blocks of the
 We use lazy evaluation for the input and output blocks of the
 functions \code{explicate-pred} and \code{explicate-assign} and for
 functions \code{explicate-pred} and \code{explicate-assign} and for
 the output block of \code{explicate-tail}. So instead of taking and
 the output block of \code{explicate-tail}. So instead of taking and
-returning blocks, they take and return promised blocks. Furthermore,
-when we come to a situation in which we a block might be used more
-than once, as in the case for \code{if} above, we transform the
-promise into a new promise that will add the block to the control-flow
-graph and return a \code{goto}.  The following auxiliary function
-accomplishes this task. It begins with \code{delay} to create a
-promise. When forced, this promise will force the input block. If that
-block is already a \code{goto} (because it was already added to the
-control-flow graph), then we return that \code{goto}. Otherwise we add
-the block to the control-flow graph with another auxiliary function
-named \code{add-node} that returns the new label, and then return the
+returning blocks, they take and return promises. Furthermore, when we
+come to a situation in which we a block might be used more than once,
+as in the case for \code{if} in \code{explicate-pred}, we transform
+the promise into a new promise that will add the block to the
+control-flow graph and return a \code{goto}.  The following auxiliary
+function named \code{block->goto} accomplishes this task. It begins
+with \code{delay} to create a promise. When forced, this promise will
+force the original promise. If that returns a \code{goto} (because the
+block was already added to the control-flow graph), then we return the
+\code{goto}. Otherwise we add the block to the control-flow graph with
+another auxiliary function named \code{add-node}. That function
+returns the label for the new block, which we use to create a
 \code{goto}.
 \code{goto}.
 \begin{lstlisting}
 \begin{lstlisting}
 (define (block->goto block)
 (define (block->goto block)
@@ -5172,63 +5232,60 @@ named \code{add-node} that returns the new label, and then return the
     (define b (force block))
     (define b (force block))
     (match b
     (match b
       [(Goto label) (Goto label)]
       [(Goto label) (Goto label)]
-      [else (Goto (add-node b))]
-      )))
-\end{lstlisting}
-
-Getting back to the case for \code{if} in \code{explicate-pred}, we
-make the recursive calls to \code{explicate-pred} on the ``then'' and
-``else'' branches with the arguments \code{(block->goto} $B_1$\code{)}
-and \code{(block->goto} $B_2$\code{)}. Let $B_3$ and $B_4$ be the
-results from the two recursive calls.  We complete the case for
-\code{if} by recursively apply \code{explicate-pred} to the condition
-of the \code{if} with the promised blocks $B_3$ and $B_4$ to obtain
-the result $B_5$.
-\[
-(\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els})
-\quad\Rightarrow\quad
-B_5
-\]
-
-Next, consider the case for a less-than comparison in
-\code{explicate-pred}. We translate it to an \code{if} statement,
-whose two branches are required to be \code{goto}'s.  So we apply
-\code{block->goto} to $B_1$ and $B_2$ to obtain two promised goto's,
-which we can \code{force} to obtain the two actual goto's $G_1$ and
-$G_2$. The translation of the less-than comparison is as follows.
-\[
-(\key{<}~e_1~e_2) \quad\Rightarrow\quad
-\begin{array}{l}
-\key{if}~(\key{<}~e_1~e_2) \; G_1\\
-\key{else} \; G_2
-\end{array}
-\]
+      [else (Goto (add-node b))])))
+\end{lstlisting}
+
+Returning to the discussion of \code{explicate-pred}
+(Figure~\ref{fig:explicate-pred}), consider the case for comparison
+operators. This is one of the base cases of the recursive function so
+we translate the comparison to an \code{if} statement. We apply
+\code{block->goto} to \code{thn} and \code{els} to obtain two promises
+that will add then to the control-flow graph, which we can immediately
+\code{force} to obtain the two goto's that form the branches of the
+\code{if} statement.
+
+%% Getting back to the case for \code{if} in \code{explicate-pred}, we
+%% make the recursive calls to \code{explicate-pred} on the ``then'' and
+%% ``else'' branches with the arguments \code{(block->goto} $B_1$\code{)}
+%% and \code{(block->goto} $B_2$\code{)}. Let $B_3$ and $B_4$ be the
+%% results from the two recursive calls.  We complete the case for
+%% \code{if} by recursively apply \code{explicate-pred} to the condition
+%% of the \code{if} with the promised blocks $B_3$ and $B_4$ to obtain
+%% the result $B_5$.
+%% \[
+%% (\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els})
+%% \quad\Rightarrow\quad
+%% B_5
+%% \]
+
+The \code{explicate-tail} and \code{explicate-assign} functions need
+additional cases for Boolean constants and \key{if}.
+%
+In the cases for \code{if}, the two branches inherit the current
+context, so in \code{explicate-tail} they are in tail position and in
+\code{explicate-assign} they are in assignment position. The
+\code{cont} parameter of \code{explicate-assign} is used in both
+recursive calls, so make sure to use \code{block->goto} on it.
+
+%% In the case for \code{if} in \code{explicate-tail}, the two branches
+%% inherit the current context, so they are in tail position. Thus, the
+%% recursive calls on the ``then'' and ``else'' branch should be calls to
+%% \code{explicate-tail}.
+%% %
+%% We need to pass $B_0$ as the accumulator argument for both of these
+%% recursive calls, but we need to be careful not to duplicate $B_0$.
+%% Thus, we first apply \code{block->goto} to $B_0$ so that it gets added
+%% to the control-flow graph and obtain a promised goto $G_0$.
+%% %
+%% Let $B_1$ be the result of \code{explicate-tail} on the ``then''
+%% branch and $G_0$ and let $B_2$ be the result of \code{explicate-tail}
+%% on the ``else'' branch and $G_0$.  Let $B_3$ be the result of applying
+%% \code{explicate-pred} to the condition of the \key{if}, $B_1$, and
+%% $B_2$.  Then the \key{if} as a whole translates to promise $B_3$.
+%% \[
+%%     (\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_3
+%% \]
 
 
-The \code{explicate-tail} function needs to be updated to use lazy
-evaluation and it needs an additional case for \key{if}.  Each of the
-cases that return an AST node need use \code{delay} to instead return
-a promise of an AST node. Recall that \code{explicate-tail} has an
-accumulator parameter that is a block, which now becomes a promise of
-a block, which we refer to as $B_0$.
-
-In the case for \code{if} in \code{explicate-tail}, the two branches
-inherit the current context, so they are in tail position. Thus, the
-recursive calls on the ``then'' and ``else'' branch should be calls to
-\code{explicate-tail}.
-%
-We need to pass $B_0$ as the accumulator argument for both of these
-recursive calls, but we need to be careful not to duplicate $B_0$.
-Thus, we first apply \code{block->goto} to $B_0$ so that it gets added
-to the control-flow graph and obtain a promised goto $G_0$.
-%
-Let $B_1$ be the result of \code{explicate-tail} on the ``then''
-branch and $G_0$ and let $B_2$ be the result of \code{explicate-tail}
-on the ``else'' branch and $G_0$.  Let $B_3$ be the result of applying
-\code{explicate-pred} to the condition of the \key{if}, $B_1$, and
-$B_2$.  Then the \key{if} as a whole translates to promise $B_3$.
-\[
-    (\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_3
-\]
 %% In the above discussion, we use the metavariables $B_1$, $B_2$, and
 %% In the above discussion, we use the metavariables $B_1$, $B_2$, and
 %% $B_3$ to refer to blocks for the purposes of our discussion, but they
 %% $B_3$ to refer to blocks for the purposes of our discussion, but they
 %% should not be confused with the labels for the blocks that appear in
 %% should not be confused with the labels for the blocks that appear in
@@ -5236,30 +5293,31 @@ $B_2$.  Then the \key{if} as a whole translates to promise $B_3$.
 %% attach labels to blocks when we add them to the control-flow graph, as
 %% attach labels to blocks when we add them to the control-flow graph, as
 %% we see in the next case.
 %% we see in the next case.
 
 
-Next consider the case for \key{if} in the \code{explicate-assign}
-function. The context of the \key{if} is an assignment to some
-variable $x$ and then the control continues to some promised block
-$B_1$.  The code that we generate for both the ``then'' and ``else''
-branches needs to continue to $B_1$, so to avoid duplicating $B_1$ we
-apply \code{block->goto} to it and obtain a promised goto $G_1$.  The
-branches of the \key{if} inherit the current context, so they are in
-assignment positions.  Let $B_2$ be the result of applying
-\code{explicate-assign} to the ``then'' branch, variable $x$, and
-$G_1$.  Let $B_3$ be the result of applying \code{explicate-assign} to
-the ``else'' branch, variable $x$, and $G_1$. Finally, let $B_4$ be
-the result of applying \code{explicate-pred} to the predicate
-$\itm{cnd}$ and the promises $B_2$ and $B_3$. The \key{if} as a whole
-translates to the promise $B_4$.
-\[
-(\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_4
-\]
-This completes the description of \code{explicate-control} for \LangIf{}.
+%% Next consider the case for \key{if} in the \code{explicate-assign}
+%% function. The context of the \key{if} is an assignment to some
+%% variable $x$ and then the control continues to some promised block
+%% $B_1$.  The code that we generate for both the ``then'' and ``else''
+%% branches needs to continue to $B_1$, so to avoid duplicating $B_1$ we
+%% apply \code{block->goto} to it and obtain a promised goto $G_1$.  The
+%% branches of the \key{if} inherit the current context, so they are in
+%% assignment positions.  Let $B_2$ be the result of applying
+%% \code{explicate-assign} to the ``then'' branch, variable $x$, and
+%% $G_1$.  Let $B_3$ be the result of applying \code{explicate-assign} to
+%% the ``else'' branch, variable $x$, and $G_1$. Finally, let $B_4$ be
+%% the result of applying \code{explicate-pred} to the predicate
+%% $\itm{cnd}$ and the promises $B_2$ and $B_3$. The \key{if} as a whole
+%% translates to the promise $B_4$.
+%% \[
+%% (\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_4
+%% \]
+%% This completes the description of \code{explicate-control} for \LangIf{}.
+
 
 
 The way in which the \code{shrink} pass transforms logical operations
 The way in which the \code{shrink} pass transforms logical operations
 such as \code{and} and \code{or} can impact the quality of code
 such as \code{and} and \code{or} can impact the quality of code
 generated by \code{explicate-control}. For example, consider the
 generated by \code{explicate-control}. For example, consider the
 following program.
 following program.
-% s1_21.rkt
+% cond_test_21.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (if (and (eq? (read) 0) (eq? (read) 1))
 (if (and (eq? (read) 0) (eq? (read) 1))
     0
     0
@@ -5274,16 +5332,12 @@ following for the above program.
 \begin{lstlisting}
 \begin{lstlisting}
 start:
 start:
     tmp1 = (read);
     tmp1 = (read);
-    if (eq? tmp1 0)
-       goto block40;
-    else
-       goto block39;
+    if (eq? tmp1 0) goto block40;
+    else goto block39;
 block40:
 block40:
     tmp2 = (read);
     tmp2 = (read);
-    if (eq? tmp2 1)
-       goto block38;
-    else
-       goto block39;
+    if (eq? tmp2 1) goto block38;
+    else goto block39;
 block38:
 block38:
     return 0;
     return 0;
 block39:
 block39:
@@ -5292,10 +5346,20 @@ block39:
 \end{center}
 \end{center}
 
 
 \begin{exercise}\normalfont
 \begin{exercise}\normalfont
-  Implement the pass \code{explicate-control} by adding the cases for
-  \key{if} to the functions for tail and assignment contexts, and
-  implement \code{explicate-pred} for predicate contexts. Create test
-  cases that exercise all of the new cases in the code for this pass.
+Implement the pass \code{explicate-control} by adding the cases for
+Boolean constants and \key{if} to the \code{explicate-tail} and
+\code{explicate-assign}. Implement the auxiliary function
+\code{explicate-pred} for predicate contexts.
+%
+Create test cases that exercise all of the new cases in the code for
+this pass.
+%
+Add the following entry to the list of \code{passes} in
+\code{run-tests.rkt}
+\begin{lstlisting}
+(list "explicate-control" explicate-control interp-Cif type-check-Cif)
+\end{lstlisting}
+
 \end{exercise}
 \end{exercise}
 
 
 
 
@@ -5566,7 +5630,7 @@ x86 assembly code.
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.5\textwidth}
 \begin{minipage}{0.5\textwidth}
-% s1_20.rkt
+% cond_test_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 (if (eq? (read) 1) 42 0)
 (if (eq? (read) 1) 42 0)
 \end{lstlisting}
 \end{lstlisting}
@@ -5775,7 +5839,7 @@ optimization on the right.
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{tabular}{lll}
 \begin{tabular}{lll}
 \begin{minipage}{0.5\textwidth}
 \begin{minipage}{0.5\textwidth}
-% s1_20.rkt
+% cond_test_20.rkt
 \begin{lstlisting}
 \begin{lstlisting}
 start:
 start:
     callq read_int
     callq read_int
@@ -8576,8 +8640,8 @@ syntax for function application.
 \label{sec:interp-Rlambda}
 \label{sec:interp-Rlambda}
 
 
 Figure~\ref{fig:interp-Rlambda} shows the definitional interpreter for
 Figure~\ref{fig:interp-Rlambda} shows the definitional interpreter for
-\LangLam{}. The clause for \key{lambda} saves the current environment
-inside the returned \key{lambda}. Then the clause for \key{Apply} uses
+\LangLam{}. The case for \key{lambda} saves the current environment
+inside the returned \key{lambda}. Then the case for \key{Apply} uses
 the environment from the \key{lambda}, the \code{lam-env}, when
 the environment from the \key{lambda}, the \code{lam-env}, when
 interpreting the body of the \key{lambda}.  The \code{lam-env}
 interpreting the body of the \key{lambda}.  The \code{lam-env}
 environment is extended with the mapping of parameters to argument
 environment is extended with the mapping of parameters to argument
@@ -8685,7 +8749,7 @@ that comes after \code{reveal-functions} and before
 \code{limit-functions}. 
 \code{limit-functions}. 
 
 
 As usual, we implement the pass as a recursive function over the
 As usual, we implement the pass as a recursive function over the
-AST. All of the action is in the clauses for \key{Lambda} and
+AST. All of the action is in the cases for \key{Lambda} and
 \key{Apply}. We transform a \key{Lambda} expression into an expression
 \key{Apply}. We transform a \key{Lambda} expression into an expression
 that creates a closure, that is, a vector whose first element is a
 that creates a closure, that is, a vector whose first element is a
 function pointer and the rest of the elements are the free variables
 function pointer and the rest of the elements are the free variables
@@ -9195,7 +9259,7 @@ typed language (it's dynamically typed!).
 
 
 The definitional interpreter for \LangDyn{} is presented in
 The definitional interpreter for \LangDyn{} is presented in
 Figure~\ref{fig:interp-Rdyn} and its auxiliary functions are defined in
 Figure~\ref{fig:interp-Rdyn} and its auxiliary functions are defined in
-Figure~\ref{fig:interp-Rdyn-aux}. Consider the match clause for
+Figure~\ref{fig:interp-Rdyn-aux}. Consider the match case for
 \code{(Int n)}.  Instead of simply returning the integer \code{n} (as
 \code{(Int n)}.  Instead of simply returning the integer \code{n} (as
 in the interpreter for \LangVar{} in Figure~\ref{fig:interp-Rvar}), the
 in the interpreter for \LangVar{} in Figure~\ref{fig:interp-Rvar}), the
 interpreter for \LangDyn{} creates a \emph{tagged value}\index{tagged
 interpreter for \LangDyn{} creates a \emph{tagged value}\index{tagged
@@ -9212,7 +9276,7 @@ example, a vector of type \code{(Vector Any Any)} is tagged with
 \code{Vector} and a procedure of type \code{(Any Any -> Any)}
 \code{Vector} and a procedure of type \code{(Any Any -> Any)}
 is tagged with \code{Procedure}.
 is tagged with \code{Procedure}.
 
 
-Next consider the match clause for \code{vector-ref}.  The
+Next consider the match case for \code{vector-ref}.  The
 \code{check-tag} auxiliary function (Figure~\ref{fig:interp-Rdyn-aux})
 \code{check-tag} auxiliary function (Figure~\ref{fig:interp-Rdyn-aux})
 is used to ensure that the first argument is a vector and the second
 is used to ensure that the first argument is a vector and the second
 is an integer. If they are not, a \code{trapped-error} is raised.
 is an integer. If they are not, a \code{trapped-error} is raised.