浏览代码

minor tweaks and fixes

Jeremy Siek 4 年之前
父节点
当前提交
3953d537d3
共有 1 个文件被更改,包括 72 次插入66 次删除
  1. 72 66
      book.tex

+ 72 - 66
book.tex

@@ -3343,8 +3343,7 @@ shown in Figure~\ref{fig:reg-alloc-passes}.
 \node (R1) at (0,2)  {\large $R_1$};
 \node (R1) at (0,2)  {\large $R_1$};
 \node (R1-2) at (3,2)  {\large $R_1$};
 \node (R1-2) at (3,2)  {\large $R_1$};
 \node (R1-3) at (6,2)  {\large $R_1$};
 \node (R1-3) at (6,2)  {\large $R_1$};
-\node (C0-1) at (6,0)  {\large $C_0$};
-\node (C0-2) at (3,0)  {\large $C_0$};
+\node (C0-1) at (3,0)  {\large $C_0$};
 
 
 \node (x86-2) at (3,-2)  {\large $\text{x86}^{*}$};
 \node (x86-2) at (3,-2)  {\large $\text{x86}^{*}$};
 \node (x86-3) at (6,-2)  {\large $\text{x86}^{*}$};
 \node (x86-3) at (6,-2)  {\large $\text{x86}^{*}$};
@@ -3357,8 +3356,7 @@ shown in Figure~\ref{fig:reg-alloc-passes}.
 \path[->,bend left=15] (R1) edge [above] node {\ttfamily\footnotesize uniquify} (R1-2);
 \path[->,bend left=15] (R1) edge [above] node {\ttfamily\footnotesize uniquify} (R1-2);
 \path[->,bend left=15] (R1-2) edge [above] node {\ttfamily\footnotesize remove-complex.} (R1-3);
 \path[->,bend left=15] (R1-2) edge [above] node {\ttfamily\footnotesize remove-complex.} (R1-3);
 \path[->,bend left=15] (R1-3) edge [right] node {\ttfamily\footnotesize explicate-control} (C0-1);
 \path[->,bend left=15] (R1-3) edge [right] node {\ttfamily\footnotesize explicate-control} (C0-1);
-\path[->,bend right=15] (C0-1) edge [above] node {\ttfamily\footnotesize uncover-locals} (C0-2);
-\path[->,bend right=15] (C0-2) edge [left] node {\ttfamily\footnotesize select-instr.} (x86-2);
+\path[->,bend right=15] (C0-1) edge [left] node {\ttfamily\footnotesize select-instr.} (x86-2);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize\color{red} uncover-live} (x86-2-1);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize\color{red} uncover-live} (x86-2-1);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize\color{red} build-inter.} (x86-2-2);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize\color{red} build-inter.} (x86-2-2);
 \path[->,bend right=15] (x86-2-2) edge [right] node {\ttfamily\footnotesize\color{red} allocate-reg.} (x86-3);
 \path[->,bend right=15] (x86-2-2) edge [right] node {\ttfamily\footnotesize\color{red} allocate-reg.} (x86-3);
@@ -3738,7 +3736,6 @@ conclusion:
 
 
 
 
 
 
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Booleans and Control Flow}
 \chapter{Booleans and Control Flow}
 \label{ch:bool-types}
 \label{ch:bool-types}
@@ -4816,7 +4813,6 @@ conclusion:
 \path[->,bend left=15] (R2-3) edge [above] node {\ttfamily\footnotesize uniquify} (R2-4);
 \path[->,bend left=15] (R2-3) edge [above] node {\ttfamily\footnotesize uniquify} (R2-4);
 \path[->,bend left=15] (R2-4) edge [above] node {\ttfamily\footnotesize remove-complex.} (R2-5);
 \path[->,bend left=15] (R2-4) edge [above] node {\ttfamily\footnotesize remove-complex.} (R2-5);
 \path[->,bend left=15] (R2-5) edge [right] node {\ttfamily\footnotesize\color{red} explicate-control} (C1-1);
 \path[->,bend left=15] (R2-5) edge [right] node {\ttfamily\footnotesize\color{red} explicate-control} (C1-1);
-%\path[->,bend right=15] (C1-1) edge [above] node {\ttfamily\footnotesize uncover-locals} (C1-2);
 \path[->,bend right=15] (C1-1) edge [left] node {\ttfamily\footnotesize\color{red} select-instructions} (x86-2);
 \path[->,bend right=15] (C1-1) edge [left] node {\ttfamily\footnotesize\color{red} select-instructions} (x86-2);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize\color{red} uncover-live} (x86-2-1);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize\color{red} uncover-live} (x86-2-1);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize build-inter.} (x86-2-2);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize build-inter.} (x86-2-2);
@@ -5048,6 +5044,7 @@ copying live objects back and forth between two halves of the
 heap. The garbage collector requires coordination with the compiler so
 heap. The garbage collector requires coordination with the compiler so
 that it can see all of the \emph{root} pointers, that is, pointers in
 that it can see all of the \emph{root} pointers, that is, pointers in
 registers or on the procedure call stack.
 registers or on the procedure call stack.
+
 Sections~\ref{sec:expose-allocation} through \ref{sec:print-x86-gc}
 Sections~\ref{sec:expose-allocation} through \ref{sec:print-x86-gc}
 discuss all the necessary changes and additions to the compiler
 discuss all the necessary changes and additions to the compiler
 passes, including a new compiler pass named \code{expose-allocation}.
 passes, including a new compiler pass named \code{expose-allocation}.
@@ -5057,28 +5054,16 @@ passes, including a new compiler pass named \code{expose-allocation}.
 
 
 Figure~\ref{fig:r3-concrete-syntax} defines the concrete syntax for
 Figure~\ref{fig:r3-concrete-syntax} defines the concrete syntax for
 $R_3$ and Figure~\ref{fig:r3-syntax} defines the abstract syntax.  The
 $R_3$ and Figure~\ref{fig:r3-syntax} defines the abstract syntax.  The
-$R_3$ language includes three new forms for creating a tuple, reading
-an element of a tuple, and writing to an element of a tuple. The
-program in Figure~\ref{fig:vector-eg} shows the usage of tuples in
-Racket. We create a 3-tuple \code{t} and a 1-tuple. The 1-tuple is
-stored at index $2$ of the 3-tuple, demonstrating that tuples are
-first-class values.  The element at index $1$ of \code{t} is
-\code{\#t}, so the ``then'' branch of the \key{if} is taken.  The
-element at index $0$ of \code{t} is $40$, to which we add $2$, the
-element at index $0$ of the 1-tuple. So the result of the program is
-$42$.
-
-\begin{figure}[tbp]
-\begin{lstlisting}
-    (let ([t (vector 40 #t (vector 2))])
-      (if (vector-ref t 1)
-          (+ (vector-ref t 0)
-             (vector-ref (vector-ref t 2) 0))
-          44))
-\end{lstlisting}
-\caption{Example program that creates tuples and reads from them.}
-\label{fig:vector-eg}
-\end{figure}
+$R_3$ language includes three new forms: \code{vector} for creating a
+tuple, \code{vector-ref} for reading an element of a tuple, and
+\code{vector-set!} for writing to an element of a tuple. The program
+in Figure~\ref{fig:vector-eg} shows the usage of tuples in Racket. We
+create a 3-tuple \code{t} and a 1-tuple that is stored at index $2$ of
+the 3-tuple, demonstrating that tuples are first-class values.  The
+element at index $1$ of \code{t} is \code{\#t}, so the ``then'' branch
+of the \key{if} is taken.  The element at index $0$ of \code{t} is
+\code{40}, to which we add \code{2}, the element at index $0$ of the
+1-tuple. So the result of the program is \code{42}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \centering
 \centering
@@ -5111,6 +5096,18 @@ $42$.
 \label{fig:r3-concrete-syntax}
 \label{fig:r3-concrete-syntax}
 \end{figure}
 \end{figure}
 
 
+\begin{figure}[tbp]
+\begin{lstlisting}
+    (let ([t (vector 40 #t (vector 2))])
+      (if (vector-ref t 1)
+          (+ (vector-ref t 0)
+             (vector-ref (vector-ref t 2) 0))
+          44))
+\end{lstlisting}
+\caption{Example program that creates tuples and reads from them.}
+\label{fig:vector-eg}
+\end{figure}
+
 \begin{figure}[tp]
 \begin{figure}[tp]
 \centering
 \centering
 \fbox{
 \fbox{
@@ -5146,11 +5143,11 @@ $42$.
 Tuples are our first encounter with heap-allocated data, which raises
 Tuples are our first encounter with heap-allocated data, which raises
 several interesting issues. First, variable binding performs a
 several interesting issues. First, variable binding performs a
 shallow-copy when dealing with tuples, which means that different
 shallow-copy when dealing with tuples, which means that different
-variables can refer to the same tuple, i.e., different variables can
-be \emph{aliases} for the same thing. Consider the following example
-in which both \code{t1} and \code{t2} refer to the same tuple.  Thus,
-the mutation through \code{t2} is visible when referencing the tuple
-from \code{t1}, so the result of this program is \code{42}.
+variables can refer to the same tuple, that is, different variables
+can be \emph{aliases} for the same entity. Consider the following
+example in which both \code{t1} and \code{t2} refer to the same tuple.
+Thus, the mutation through \code{t2} is visible when referencing the
+tuple from \code{t1}, so the result of this program is \code{42}.
 \begin{center}
 \begin{center}
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
@@ -5164,11 +5161,11 @@ from \code{t1}, so the result of this program is \code{42}.
 
 
 The next issue concerns the lifetime of tuples. Of course, they are
 The next issue concerns the lifetime of tuples. Of course, they are
 created by the \code{vector} form, but when does their lifetime end?
 created by the \code{vector} form, but when does their lifetime end?
-Notice that the grammar in Figure~\ref{fig:r3-syntax} does not include
-an operation for deleting tuples. Furthermore, the lifetime of a tuple
-is not tied to any notion of static scoping. For example, the
-following program returns \code{3} even though the variable \code{t}
-goes out of scope prior to accessing the vector.
+Notice that $R_3$ does not include an operation for deleting
+tuples. Furthermore, the lifetime of a tuple is not tied to any notion
+of static scoping. For example, the following program returns \code{3}
+even though the variable \code{t} goes out of scope prior to accessing
+the vector.
 \begin{center}
 \begin{center}
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
@@ -5183,7 +5180,7 @@ goes out of scope prior to accessing the vector.
 From the perspective of programmer-observable behavior, tuples live
 From the perspective of programmer-observable behavior, tuples live
 forever. Of course, if they really lived forever, then many programs
 forever. Of course, if they really lived forever, then many programs
 would run out of memory.\footnote{The $R_3$ language does not have
 would run out of memory.\footnote{The $R_3$ language does not have
-  looping or recursive function, so it is nigh impossible to write a
+  looping or recursive functions, so it is nigh impossible to write a
   program in $R_3$ that will run out of memory. However, we add
   program in $R_3$ that will run out of memory. However, we add
   recursive functions in the next Chapter!} A Racket implementation
   recursive functions in the next Chapter!} A Racket implementation
 must therefore perform automatic garbage collection.
 must therefore perform automatic garbage collection.
@@ -5193,30 +5190,37 @@ $R_3$ language. We define the \code{vector}, \code{vector-ref}, and
 \code{vector-set!} operations for $R_3$ in terms of the corresponding
 \code{vector-set!} operations for $R_3$ in terms of the corresponding
 operations in Racket. One subtle point is that the \code{vector-set!}
 operations in Racket. One subtle point is that the \code{vector-set!}
 operation returns the \code{\#<void>} value. The \code{\#<void>} value
 operation returns the \code{\#<void>} value. The \code{\#<void>} value
-can be passed around just like other values inside an $R_3$ program,
-but there are no operations specific to the the \code{\#<void>} value
-in $R_3$. In contrast, Racket defines the \code{void?} predicate that
-returns \code{\#t} when applied to \code{\#<void>} and \code{\#f}
-otherwise.
+can be passed around just like other values inside an $R_3$ program
+and a \code{\#<void>} value can be compared for equality with another
+\code{\#<void>} value. However, there are no other operations specific
+to the the \code{\#<void>} value in $R_3$. In contrast, Racket defines
+the \code{void?} predicate that returns \code{\#t} when applied to
+\code{\#<void>} and \code{\#f} otherwise.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}
 \begin{lstlisting}
-    (define primitives (set ... 'vector 'vector-ref 'vector-set!))
+(define primitives (set ... 'vector 'vector-ref 'vector-set!))
+
+(define (interp-op op)
+  (match op
+     ...
+     ['vector vector]
+     ['vector-ref vector-ref]
+     ['vector-set! vector-set!]
+     [else (error 'interp-op "unknown operator")]))
 
 
-    (define (interp-op op)
-      (match op
-         ...
-         ['vector vector]
-         ['vector-ref vector-ref]
-	 ['vector-set! vector-set!]
-	 [else (error 'interp-op "unknown operator")]))
+(define (interp-exp env)
+  (lambda (e)
+    (define recur (interp-exp env))
+    (match e
+       ...
+       )))
 
 
-   (define (interp-R3 env)
-     (lambda (e)
-       (match e
-         ...
-         [else (error 'interp-R3 "unrecognized expression")]
-         )))
+(define (interp-R3 p)
+ (match p
+   [(Program '() e)
+    ((interp-exp '()) e)]
+   ))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for the $R_3$ language.}
 \caption{Interpreter for the $R_3$ language.}
 \label{fig:interp-R3}
 \label{fig:interp-R3}
@@ -5224,10 +5228,10 @@ otherwise.
 
 
 Figure~\ref{fig:typecheck-R3} shows the type checker for $R_3$, which
 Figure~\ref{fig:typecheck-R3} shows the type checker for $R_3$, which
 deserves some explanation. As we shall see in Section~\ref{sec:GC}, we
 deserves some explanation. As we shall see in Section~\ref{sec:GC}, we
-need to know which variables are pointers into the heap, that is,
-which variables are vectors. Also, when allocating a vector, we need
-to know which elements of the vector are pointers. We can obtain this
-information during type checking. The type checker in
+need to know which variables contain pointers into the heap, that is,
+which variables contain vectors. Also, when allocating a vector, we
+need to know which elements of the vector are pointers. We can obtain
+this information during type checking. The type checker in
 Figure~\ref{fig:typecheck-R3} not only computes the type of an
 Figure~\ref{fig:typecheck-R3} not only computes the type of an
 expression, it also wraps every sub-expression $e$ with the form
 expression, it also wraps every sub-expression $e$ with the form
 $(\key{HasType}~e~T)$, where $T$ is $e$'s type.
 $(\key{HasType}~e~T)$, where $T$ is $e$'s type.
@@ -6148,6 +6152,7 @@ _conclusion:
 \node (R3-3) at (6,2)  {\large $R_3$};
 \node (R3-3) at (6,2)  {\large $R_3$};
 \node (R3-4) at (9,2)  {\large $R_3$};
 \node (R3-4) at (9,2)  {\large $R_3$};
 \node (R3-5) at (12,2)  {\large $R_3$};
 \node (R3-5) at (12,2)  {\large $R_3$};
+\node (R3-6) at (12,0)  {\large $R_3$};
 \node (C2-4) at (3,0)  {\large $C_2$};
 \node (C2-4) at (3,0)  {\large $C_2$};
 \node (C2-3) at (6,0)  {\large $C_2$};
 \node (C2-3) at (6,0)  {\large $C_2$};
 
 
@@ -6160,10 +6165,11 @@ _conclusion:
 \node (x86-2-2) at (6,-4)  {\large $\text{x86}^{*}_2$};
 \node (x86-2-2) at (6,-4)  {\large $\text{x86}^{*}_2$};
 
 
 \path[->,bend left=15] (R3) edge [above] node {\ttfamily\footnotesize\color{red} typecheck} (R3-2);
 \path[->,bend left=15] (R3) edge [above] node {\ttfamily\footnotesize\color{red} typecheck} (R3-2);
-\path[->,bend left=15] (R3-2) edge [above] node {\ttfamily\footnotesize uniquify} (R3-3);
-\path[->,bend left=15] (R3-3) edge [above] node {\ttfamily\footnotesize\color{red} expose-alloc.} (R3-4);
-\path[->,bend left=15] (R3-4) edge [above] node {\ttfamily\footnotesize remove-complex.} (R3-5);
-\path[->,bend left=20] (R3-5) edge [right] node {\ttfamily\footnotesize explicate-control} (C2-3);
+\path[->,bend left=15] (R3-2) edge [above] node {\ttfamily\footnotesize shrink} (R3-3);
+\path[->,bend left=15] (R3-3) edge [above] node {\ttfamily\footnotesize uniquify} (R3-4);
+\path[->,bend left=15] (R3-4) edge [above] node {\ttfamily\footnotesize\color{red} expose-alloc.} (R3-5);
+\path[->,bend left=15] (R3-5) edge [right] node {\ttfamily\footnotesize remove-complex.} (R3-6);
+\path[->,bend right=20] (R3-6) edge [above] node {\ttfamily\footnotesize explicate-control} (C2-3);
 \path[->,bend right=15] (C2-3) edge [above] node {\ttfamily\footnotesize\color{red} uncover-locals} (C2-4);
 \path[->,bend right=15] (C2-3) edge [above] node {\ttfamily\footnotesize\color{red} uncover-locals} (C2-4);
 \path[->,bend right=15] (C2-4) edge [left] node {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
 \path[->,bend right=15] (C2-4) edge [left] node {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize uncover-live} (x86-2-1);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize uncover-live} (x86-2-1);