Bläddra i källkod

edits from Carcaldi and company

Jeremy G. Siek 2 år sedan
förälder
incheckning
ece7adae04
2 ändrade filer med 94 tillägg och 82 borttagningar
  1. 93 81
      book.tex
  2. 1 1
      python.bib

+ 93 - 81
book.tex

@@ -26,7 +26,7 @@
 
 \def\racketEd{0}
 \def\pythonEd{1}
-\def\edition{0}
+\def\edition{1}
 
 % material that is specific to the Racket edition of the book
 \newcommand{\racket}[1]{{\if\edition\racketEd{#1}\fi}}
@@ -39,6 +39,20 @@
 % material that is specific to the Python edition of the book
 \newcommand{\python}[1]{{\if\edition\pythonEd\pythonColor #1\fi}}
 
+\makeatletter
+\newcommand{\captionabove}[2][]{%
+    \vskip-\abovecaptionskip
+    \vskip+\belowcaptionskip
+    \ifx\@nnil#1\@nnil
+        \caption{#2}%
+    \else
+        \caption[#1]{#2}%
+    \fi
+    \vskip+\abovecaptionskip
+    \vskip-\belowcaptionskip
+}
+
+
 %% For multiple indices:
 %\usepackage{multind}  moved this to the file TimesAPriori_MIT.cls. -Jeremy
 \makeindex{subject}
@@ -4351,7 +4365,7 @@ regular expressions.
 \end{itemize}
 
 In a Lark grammar file, each kind of token is specified by a
-\emph{terminal}\index{subject}{terminal} which is defined by a rule
+\emph{terminal}\index{subject}{terminal}, which is defined by a rule
 that consists of the name of the terminal followed by a colon followed
 by a sequence of literals.  The literals include strings such as
 \code{"abc"}, regular expressions surrounded by \code{/} characters,
@@ -4375,10 +4389,10 @@ NEWLINE: (/\r/? /\n/)+
 In section~\ref{sec:grammar} we learned how to use grammar rules to
 specify the abstract syntax of a language. We now take a closer look
 at using grammar rules to specify the concrete syntax. Recall that
-each rule has a left-hand side and a right-hand side where the
+each rule has a left-hand side and a right-hand side, where the
 left-hand side is a nonterminal and the right-hand side is a pattern
 that defines what can be parsed as that nonterminal.  For concrete
-syntax, each right-hand side expresses a pattern for a string, instead
+syntax, each right-hand side expresses a pattern for a string instead
 of a pattern for an abstract syntax tree. In particular, each
 right-hand side is a sequence of
 \emph{symbols}\index{subject}{symbol}, where a symbol is either a
@@ -4634,7 +4648,7 @@ excerpt from the \code{parse\_tree\_to\_ast} function for \LangInt{}.
 \end{lstlisting}
 Change your compiler from chapter~\ref{ch:Lvar} to use your
 Lark parser instead of using the \code{parse} function from
-the \code{ast} module. Test your compiler on all of the \LangVar{}
+the \code{ast} module. Test your compiler on all the \LangVar{}
 programs that you have created, and create four additional programs
 that test for ambiguities in your grammar.
 \end{exercise}
@@ -4655,7 +4669,7 @@ learn about the LALR(1) algorithm, which is more efficient but cannot
 handle all context-free grammars.
 
 Earley's algorithm can be viewed as an interpreter; it treats the
-grammar as the program being interpreted and it treats the concrete
+grammar as the program being interpreted, and it treats the concrete
 syntax of the program-to-be-parsed as its input.  Earley's algorithm
 uses a data structure called a \emph{chart}\index{subject}{chart} to
 keep track of its progress and to store its results. The chart is an
@@ -4670,10 +4684,10 @@ been parsed. For example, the dotted rule
    exp: exp "+" . exp_hi
 \end{lstlisting}
 represents a partial parse that has matched an \code{exp} followed by
-\code{+}, but has not yet parsed an \code{exp} to the right of
+\code{+} but has not yet parsed an \code{exp} to the right of
 \code{+}.
 %
-Earley's algorithm starts with an initialization phase, and then
+Earley's algorithm starts with an initialization phase and then
 repeats three actions---prediction, scanning, and completion---for as
 long as opportunities arise. We demonstrate Earley's algorithm on a
 running example, parsing the following program:
@@ -4852,7 +4866,7 @@ This triggers another completion action for \code{stmt\_list} in slot $0$
 which in turn completes \code{lang\_int}, the start symbol of the
 grammar, so the parsing of the input is complete.
 
-For reference, we now give a general description of Earley's
+For reference, we give a general description of Earley's
 algorithm.
 \begin{enumerate}
 \item The algorithm begins by initializing slot $0$ of the chart with the
@@ -4912,7 +4926,7 @@ respect to efficiency.
 %
 A particularly influential implementation of LALR(1) is the
 \texttt{yacc} parser generator by \citet{Johnson:1979qy};
-\texttt{yacc} stands for ``yet another compiler compiler''.
+\texttt{yacc} stands for ``yet another compiler compiler.''
 %
 The LALR(1) state machine uses a stack to record its progress in
 parsing the input string.  Each element of the stack is a pair: a
@@ -5802,7 +5816,7 @@ instructions.  \racket{The first instruction is \lstinline{movq $1, v},
   $\ttm{x}$ interferes with \ttm{w} and \ttm{rsp}.}
 %
 \python{The fourth instruction is \lstinline{addq $7, x}, and the
-  live-after set is $\{\ttm{w},\ttm{x}\}$. Rule 2 applies so
+  live-after set is $\{\ttm{w},\ttm{x}\}$. Rule 2 applies, so
   $\ttm{x}$ interferes with \ttm{w}.}
 %
 \racket{The next instruction is \lstinline{movq x, y}, and the
@@ -8442,7 +8456,7 @@ The output of \key{explicate\_control} is a language similar to the
 $C$ language~\citep{Kernighan:1988nx} in that it has labels and
 \code{goto} statements, so we name it \LangCIf{}.  
 %
-The \LangCIf{} language supports the same operators as \LangIf{} but
+The \LangCIf{} language supports the same operators as \LangIf{}, but
 the arguments of operators are restricted to atomic expressions. The
 \LangCIf{} language does not include \code{if} expressions, but it does
 include a restricted form of \code{if} statement. The condition must be
@@ -9255,9 +9269,9 @@ blocks.
 
 When the right-hand side is an \code{if} expression, there is some
 work to do. In particular, the two branches should be translated using
-\code{explicate\_assign} and the condition expression should be
+\code{explicate\_assign}, and the condition expression should be
 translated using \code{explicate\_pred}.  Otherwise we can simply
-generate an assignment statement, with the given left and right-hand
+generate an assignment statement, with the given left- and right-hand
 sides, concatenated with its continuation.
 
 \begin{figure}[tbp]
@@ -9449,11 +9463,11 @@ branch.  The \code{explicate\_pred} function should match on
 %
 {\if\edition\pythonEd\pythonColor
 
-The \code{explicate\_pred} function has four parameters: 1) the
-condition expression, 2) the generated statements for the ``then''
-branch, 3) the generated statements for the ``else'' branch, and 4)
+The \code{explicate\_pred} function has four parameters: (1) the
+condition expression, (2) the generated statements for the ``then''
+branch, (3) the generated statements for the ``else'' branch, and (4)
 the dictionary of basic blocks. The \code{explicate\_pred} function
-returns a list of \LangCIf{} statements and it may add to the
+returns a list of \LangCIf{} statements, and it may add to the
 dictionary of basic blocks.
 
 \fi}
@@ -10402,7 +10416,7 @@ function instead of recomputing it each time.  The following
          return self.cache
 \end{lstlisting}
 %
-However, in some cases of \code{explicate\_pred} we return a list
+However, in some cases of \code{explicate\_pred}, we return a list
 of statements, and in other cases we return a function that
 computes a list of statements.  To uniformly deal with both regular
 data and promises, we define the following \code{force} function that
@@ -11202,7 +11216,7 @@ that we introduce the changes necessary to the existing passes.
 At first glance, the translation of \code{while} loops to x86 seems
 straightforward because the \LangCIf{} intermediate language already
 supports \code{goto} and conditional branching. However, there are
-complications that arise which we discuss in the next section. After
+complications that arise, which we discuss in the next section. After
 that we introduce the changes necessary to the existing passes.
 %
 \fi}
@@ -17296,7 +17310,7 @@ print(f(0, 10)(32))
 
 Many of our compiler passes rely on being able to connect variable
 uses with their definitions using just the name of the
-variable. However, in the example above the name of the variable does
+variable. However, in the example above, the name of the variable does
 not uniquely determine its definition. To solve this problem we
 recommend implementing a pass named \code{uniquify} that renames every
 variable in the program to make sure that they are all unique.
@@ -17941,9 +17955,10 @@ instructions that access the tag from position $0$ of the tuple
 (representing a closure) and extract the $5$ bits starting at position
 $58$ from the tag.}
 
+Figure~\ref{fig:Llambda-passes} provides an overview of the passes
+needed for the compilation of \LangLam{}.
 
-
-\begin{figure}[p]
+\begin{figure}[bthp]
   \begin{tcolorbox}[colback=white]
 {\if\edition\racketEd    
 \begin{tikzpicture}[baseline=(current  bounding  box.center),scale=0.85]
@@ -18053,8 +18068,6 @@ $58$ from the tag.}
 \label{fig:Llambda-passes}
 \end{figure}
 
-Figure~\ref{fig:Llambda-passes} provides an overview of the passes
-needed for the compilation of \LangLam{}.
 
 \clearpage
 
@@ -19665,7 +19678,7 @@ bidirectional type checking because we no longer have an expected type
 to use for type checking the expression $e'$. Thus, we run into
 difficulty if $e'$ is a \code{Lambda} expression.  We recommend
 translating \code{Lambda} to a new AST class \code{AnnLambda} (for
-annotated lambda), that contains its return type and the types of its
+annotated lambda) that contains its return type and the types of its
 parameters.
 %
 \fi}
@@ -19704,8 +19717,8 @@ translated in a similar way:
 %
 The \code{any\_tuple\_load} operation combines the projection action
 with the load operation.  Also, the load operation allows arbitrary
-expressions for the index so the type checker for \LangAny{}
-(figure~\ref{fig:type-check-Lany}) cannot guarantee that the index, is
+expressions for the index, so the type checker for \LangAny{}
+(figure~\ref{fig:type-check-Lany}) cannot guarantee that the index is
 within bounds. Thus, we insert code to perform bounds checking at
 runtime. The translation for \code{any\_tuple\_load} is as follows.
 
@@ -20053,7 +20066,7 @@ movq 0(%r11) |$\itm{lhs'}$|
 %% analogous to the above translation for reading from a tuple.
 
 
-\section{Register Allocation for \LangAny{}}
+\section{Register Allocation for \LangAny{} }
 \label{sec:register-allocation-Lany}
 \index{subject}{register allocation}
 
@@ -20103,8 +20116,10 @@ nevertheless they should be valid \LangDyn{} programs that run to
 completion without error.
 \end{exercise}
 
+Figure~\ref{fig:Ldyn-passes} provides an overview of the passes needed
+for the compilation of \LangDyn{}.
 
-\begin{figure}[p]
+\begin{figure}[bthp]
 \begin{tcolorbox}[colback=white]
 {\if\edition\racketEd    
 \begin{tikzpicture}[baseline=(current  bounding  box.center),scale=0.85]
@@ -20228,8 +20243,6 @@ completion without error.
 \label{fig:Ldyn-passes}
 \end{figure}
 
-Figure~\ref{fig:Ldyn-passes} provides an overview of the passes needed
-for the compilation of \LangDyn{}.
 
 % Further Reading
 
@@ -20416,7 +20429,7 @@ next two sections.
 
 %\clearpage
 
-\section{Type Checking \LangGrad{}}
+\section{Type Checking \LangGrad{} \vspace{-2pt}}
 \label{sec:gradual-type-check}
 
 We begin by discussing the type checking of a partially typed variant
@@ -20516,6 +20529,7 @@ def consistent(self, t1, t2):
       return t1 == t2
 \end{lstlisting}  
   \fi}
+\vspace{-5pt}
   \end{tcolorbox}
 
   \caption{The consistency method on types.}
@@ -20575,7 +20589,6 @@ and \ref{fig:type-check-Lgradual-3}.
 \begin{lstlisting}
 def map(f : Callable[[int], int], v : tuple[int,int]) -> tuple[int,int]:
   return f(v[0]), f(v[1])
-
 def inc(x):
   return x + 1
 def true():
@@ -20587,6 +20600,7 @@ t = map(maybe_inc, (0, 41))
 print(t[1])
 \end{lstlisting}
 \fi}
+\vspace{-5pt}
 \end{tcolorbox}
 
 \caption{A variant of the \code{map} example with an error.}
@@ -20644,7 +20658,6 @@ In the next section we see how to interpret the \code{Cast} node.
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 def map(f : Callable[[int], int], v : tuple[int,int]) -> tuple[int,int]:
   return f(v[0]), f(v[1])
-
 def inc(x : Any) -> Any:
   return Cast(Cast(x, Any, int) + 1, int, Any)
 def true() -> Any:
@@ -20657,6 +20670,7 @@ t = map(Cast(maybe_inc, Callable[[Any], Any], Callable[[int], int]),
 print(t[1])
 \end{lstlisting}
 \fi}
+\vspace{-5pt}
 \end{tcolorbox}
 
 \caption{Output of the \code{cast\_insert} pass for the \code{map}
@@ -21012,10 +21026,9 @@ def check_consistent(self, t1, t2, e):
 
 \fi}
 
-
 \clearpage
 
-\section{Interpreting \LangCast{}}
+\section{Interpreting \LangCast{} \vspace{-2pt}}
 \label{sec:interp-casts}
 
 The runtime behavior of casts involving simple types such as
@@ -21069,13 +21082,45 @@ to
 A naive way for the \LangCast{} interpreter to cast between
 \racket{tuple}\python{array} types would be to build a new
 \racket{tuple}\python{array} whose elements are the result
-of casting each of the original elements to the appropriate target
+of casting each of the original elements to the target
 type. However, this approach is not valid for mutable data structures.
 In the example of figure~\ref{fig:map-bang},
 if the cast created a new \racket{tuple}\python{array}, then the updates inside
 \code{map\_inplace} would happen to the new \racket{tuple}\python{array} and not
 the original one.
 
+Instead the interpreter needs to create a new kind of value, a
+\emph{proxy}, that intercepts every \racket{tuple}\python{array} operation.
+On a read, the proxy reads from the underlying \racket{tuple}\python{array}
+and then applies a
+cast to the resulting value.  On a write, the proxy casts the argument
+value and then performs the write to the underlying \racket{tuple}\python{array}.
+\racket{
+For the first \code{(vector-ref v 0)} in \code{map\_inplace}, the proxy casts
+\code{0} from \INTTY{} to \CANYTY{}.
+For the first \code{vector-set!}, the proxy casts a tagged \code{1}
+from \CANYTY{} to \INTTY{}.
+}
+\python{
+  For the subscript \code{v[i]} in \code{f(v[i])} of \code{map\_inplace},
+  the proxy casts the integer from \INTTY{} to \CANYTY{}.
+  For the subscript on the left of the assignment,
+  the proxy casts the tagged value from \CANYTY{} to \INTTY{}.
+}
+
+Finally we consider casts between the \CANYTY{} type and higher-order types
+such as functions and \racket{tuples}\python{lists}. Figure~\ref{fig:map-any}
+shows a variant of \code{map\_inplace} in which parameter \code{v} does not
+have a type annotation, so it is given type \CANYTY{}. In the call to
+\code{map\_inplace}, the \racket{tuple}\python{list} has type
+\racket{\code{(Vector Integer Integer)}}\python{\code{list[int]}},
+so the type checker inserts a cast to \CANYTY{}. A first thought is to use
+\code{Inject}, but that doesn't work because
+\racket{\code{(Vector Integer Integer)}}\python{\code{list[int]}} is not
+a flat type. Instead, we must first cast to
+\racket{\code{(Vector Any Any)}}\python{\code{list[Any]}}, which is flat,
+and then inject to \CANYTY{}.
+
 \begin{figure}[tbp]
   \begin{tcolorbox}[colback=white]
     % gradual_test_11.rkt
@@ -21115,39 +21160,7 @@ print(v[1])
 \label{fig:map-bang}
 \end{figure}
 
-Instead the interpreter needs to create a new kind of value, a
-\emph{proxy}, that intercepts every \racket{tuple}\python{array} operation.
-On a read, the proxy reads from the underlying \racket{tuple}\python{array}
-and then applies a
-cast to the resulting value.  On a write, the proxy casts the argument
-value and then performs the write to the underlying \racket{tuple}\python{array}.
-\racket{
-For the first \code{(vector-ref v 0)} in \code{map\_inplace}, the proxy casts
-\code{0} from \INTTY{} to \CANYTY{}.
-For the first \code{vector-set!}, the proxy casts a tagged \code{1}
-from \CANYTY{} to \INTTY{}.
-}
-\python{
-  For the subscript \code{v[i]} in \code{f(v[i])} of \code{map\_inplace},
-  the proxy casts the integer from \INTTY{} to \CANYTY{}.
-  For the subscript on the left of the assignment,
-  the proxy casts the tagged value from \CANYTY{} to \INTTY{}.
-}
-
-Finally we consider casts between the \CANYTY{} type and higher-order types
-such as functions and \racket{tuples}\python{lists}. Figure~\ref{fig:map-any}
-shows a variant of \code{map\_inplace} in which parameter \code{v} does not
-have a type annotation, so it is given type \CANYTY{}. In the call to
-\code{map\_inplace}, the \racket{tuple}\python{list} has type
-\racket{\code{(Vector Integer Integer)}}\python{\code{list[int]}},
-so the type checker inserts a cast to \CANYTY{}. A first thought is to use
-\code{Inject}, but that doesn't work because
-\racket{\code{(Vector Integer Integer)}}\python{\code{list[int]}} is not
-a flat type. Instead, we must first cast to
-\racket{\code{(Vector Any Any)}}\python{\code{list[Any]}}, which is flat,
-and then inject to \CANYTY{}.
-
-\begin{figure}[tbp]
+\begin{figure}[btp]
   \begin{tcolorbox}[colback=white]
 {\if\edition\racketEd
 \begin{lstlisting}
@@ -21410,7 +21423,7 @@ class InterpLcast(InterpLany):
 \fi}
 
 {\if\edition\pythonEd\pythonColor
-\section{Overload Resolution}
+\section{Overload Resolution \vspace{-2pt}}
 \label{sec:gradual-resolution}
 
 Recall that when we added support for arrays in
@@ -21429,7 +21442,7 @@ access and length operations to the primitives \code{any\_load},
 
 \fi}
 
-\section{Cast Insertion}
+\section{Cast Insertion \vspace{-2pt}}
 \label{sec:gradual-insert-casts}
 
 In our discussion of type checking of \LangGrad{}, we mentioned how
@@ -21487,7 +21500,7 @@ tuples of type \CANYTY{}: \code{any-vector-length},
 \fi}
 
 
-\section{Lower Casts}
+\section{Lower Casts \vspace{-2pt}}
 \label{sec:lower_casts}
 
 The next step in the journey toward x86 is the \code{lower\_casts}
@@ -21662,7 +21675,7 @@ def main() -> int:
 \end{figure}
 
 
-\section{Differentiate Proxies}
+\section{Differentiate Proxies \vspace{-2pt}}
 \label{sec:differentiate-proxies}
 
 So far, the responsibility of differentiating tuples and tuple proxies
@@ -21904,7 +21917,7 @@ from the tuple.
 The translation of array operations is similar to the ones for tuples.
 
 
-\section{Reveal Casts}
+\section{Reveal Casts \vspace{-2pt}}
 \label{sec:reveal-casts-gradual}
 
 {\if\edition\racketEd    
@@ -21939,7 +21952,7 @@ decimal), just like the tuple and array types.
 Otherwise, the only other changes are adding cases that copy the new AST nodes.
 
 
-\section{Closure Conversion}
+\section{Closure Conversion \vspace{-2pt}}
 \label{sec:closure-conversion-gradual}
 
 The auxiliary function that translates type annotations needs to be
@@ -21949,7 +21962,7 @@ updated to handle the \PTUPLETYNAME{}
 Otherwise, the only other changes are adding cases that copy the new
 AST nodes.
 
-\section{Select Instructions}
+\section{Select Instructions \vspace{-2pt}}
 \label{sec:select-instructions-gradual}
 \index{subject}{select instructions}
 
@@ -23638,6 +23651,8 @@ reference per instruction.  Other operands must be immediates or
 registers.
 
 \begin{table}[tbp]
+  \captionabove{Quick reference for the x86 instructions used in this book.}
+  \label{tab:x86-instr}
   \centering
 \begin{tabular}{l|l}
 \textbf{Instruction} & \textbf{Operation} \\ \hline
@@ -23684,9 +23699,6 @@ registers.
 \texttt{setg} $A$ & \\
 \texttt{setge} $A$ &
 \end{tabular}
-\vspace{5pt}
-  \caption{Quick reference for the x86 instructions used in this book.}
-  \label{tab:x86-instr}
 \end{table}
 
 

+ 1 - 1
python.bib

@@ -97,7 +97,7 @@ pages = {1--44}
 
 @misc{shinan20:_lark_docs,
   author = 	 {Erez Shinan},
-  title = 	 {Welcome to Lark's Documentation},
+  title = 	 {Welcome to Lark's Documentation!},
   url = {https://lark-parser.readthedocs.io/en/latest/index.html},
   year = 	 2020}