Преглед изворни кода

proof reading and spell check

Jeremy Siek пре 4 година
родитељ
комит
e26c3cfa5c
1 измењених фајлова са 86 додато и 71 уклоњено
  1. 86 71
      book.tex

+ 86 - 71
book.tex

@@ -638,22 +638,21 @@ choice).
 \section{Recursion}
 \label{sec:recursion}
 
-Programs are inherently recursive. For example, an $R_0$ expression
-($\Exp$) is often made of smaller expressions. Thus, the natural way
-to process an entire program is with a recursive function.  As a first
-example of such a recursive function, we define \texttt{exp?} below,
-which takes an arbitrary S-expression, {\tt sexp}, and determines
-whether or not {\tt sexp} is an $R_0$ expression. As discussed in the
-previous section, each match clause corresponds to one grammar rule.
-The body of each clause makes a recursive call for each child
-node. This kind of recursive function is so common that it has a name:
-\emph{structural recursion}.  In general, when a recursive function is
-defined using a sequence of match clauses that correspond to a
-grammar, and the body of each clause makes a recursive call on each
-child node, then we say the function is defined by structural
-recursion\footnote{This principle of structuring code according to the
-  data definition is advocated in the book \emph{How to Design
-    Programs}
+Programs are inherently recursive. For example, an $R_0$ expression is
+often made of smaller expressions. Thus, the natural way to process an
+entire program is with a recursive function.  As a first example of
+such a recursive function, we define \texttt{exp?} below, which takes
+an arbitrary S-expression and determines whether or not it is an $R_0$
+expression. As discussed in the previous section, each match clause
+corresponds to one grammar rule.  The body of each clause makes a
+recursive call for each child node. This kind of recursive function is
+so common that it has a name: \emph{structural recursion}.  In
+general, when a recursive function is defined using a sequence of
+match clauses that correspond to a grammar, and the body of each
+clause makes a recursive call on each child node, then we say the
+function is defined by structural recursion\footnote{This principle of
+  structuring code according to the data definition is advocated in
+  the book \emph{How to Design Programs}
   \url{http://www.ccs.neu.edu/home/matthias/HtDP2e/}.}. Below we also
 define a second function, named \code{R0?}, that determines whether an
 S-expression is an $R_0$ program.  In general we can expect to write
@@ -740,13 +739,15 @@ defined in the report by \cite{SPERBER:2009aa}. The Racket language is
 defined in its reference manual~\citep{plt-tr}. In this book we use an
 interpreter to define the meaning of each language that we consider,
 following Reynolds' advice in this
-regard~\citep{reynolds72:_def_interp}. Here we warm up by writing an
-interpreter for the $R_0$ language, which serves as a second example
-of structural recursion. The \texttt{interp-R0} function is defined in
-Figure~\ref{fig:interp-R0}. The body of the function is a match on the
-input program \texttt{p} and then a call to the \lstinline{interp-exp}
-helper function, which in turn has one match clause per grammar rule
-for $R_0$ expressions.
+regard~\citep{reynolds72:_def_interp}. An interpreter that is
+designated (by some people) as the definition of a language is called
+a \emph{definitional interpreter}.  Here we warm up by creating a
+definitional interpreter for the $R_0$ language, which serves as a
+second example of structural recursion. The \texttt{interp-R0}
+function is defined in Figure~\ref{fig:interp-R0}. The body of the
+function is a match on the input program followed by a call to the
+\lstinline{interp-exp} helper function, which in turn has one match
+clause per grammar rule for $R_0$ expressions.
 
 \begin{figure}[tbp]
 \begin{lstlisting}
@@ -770,13 +771,12 @@ for $R_0$ expressions.
 \end{figure}
 
 Let us consider the result of interpreting a few $R_0$ programs. The
-following program simply adds two integers.
+following program adds two integers.
 \begin{lstlisting}
    (+ 10 32)
 \end{lstlisting}
-The result is \key{42}, as you might have expected.  Here we have written the
-program in concrete syntax, whereas the parsed abstract syntax would be the
-slightly different: \lstinline{(program (+ 10 32))}.
+The result is \key{42}.  (We wrote the above program in concrete syntax,
+whereas the parsed abstract syntax is \lstinline{(program (+ 10 32))}.)
 
 The next example demonstrates that expressions may be nested within
 each other, in this case nesting several additions and negations.
@@ -785,10 +785,10 @@ each other, in this case nesting several additions and negations.
 \end{lstlisting}
 What is the result of the above program?
 
-As mentioned previously, the $R0$ language does not support
+As mentioned previously, the $R_0$ language does not support
 arbitrarily-large integers, but only $63$-bit integers, so we
-interpret the arithmetic operations of $R0$ using fixnum arithmetic.
-What happens when we run the following program?
+interpret the arithmetic operations of $R_0$ using fixnum arithmetic
+in Racket.  What happens when we run the following program?
 \begin{lstlisting}
    (define large 999999999999999999)
    (interp-R0 `(program (+ (+ (+ ,large ,large) (+ ,large ,large))
@@ -798,16 +798,20 @@ It produces an error:
 \begin{lstlisting}
    fx+: result is not a fixnum
 \end{lstlisting}
-We shall use the convention that if the interpreter for a language
-produces an error when run on a program, then the meaning of the
-program is unspecified. The compiler for the language is under no
-obligation for such a program; it can produce an executable that does
-anything.
+We establish the convention that if running the definitional
+interpreter on a program produces an error, then the meaning of the
+program is \emph{unspecified}. That means the compiler for the
+language is under no obligation for such a program; it may or may not
+produce an executable, and if it does, that executable can do
+anything. This convention applies to the languages defined in this
+book, as a way to simplify the student's task of implementing them,
+but this convention does not generally hold for real programming
+languages.
 
-\noindent
-Moving on, the \key{read} operation prompts the user of the program
-for an integer. If we interpret the AST \eqref{eq:arith-prog} and give
-it the input \texttt{50}
+Moving on to the next feature of the $R_0$ language, the \key{read}
+operation prompts the user of the program for an integer. If we
+interpret the AST \eqref{eq:arith-prog} and give it the input
+\texttt{50}
 \begin{lstlisting}
    (interp-R0 ast1.1)
 \end{lstlisting}
@@ -1325,7 +1329,7 @@ x86 programs, so we define an abstract syntax for x86 in
 Figure~\ref{fig:x86-ast-a}. We refer to this language as $x86_0$ with
 a subscript $0$ because later we introduce extended versions of this
 assembly language. The main difference compared to the concrete syntax
-of x86 (Figure~\ref{fig:x86-a}) is that it does nto allow labelled
+of x86 (Figure~\ref{fig:x86-a}) is that it does not allow labeled
 instructions to appear anywhere, but instead organizes instructions
 into groups called \emph{blocks} and a label is associated with every
 block, which is why the \key{program} form includes an association
@@ -1561,7 +1565,7 @@ having to change the syntax of the program construct in
 Chapter~\ref{ch:bool-types}.  For now there will be just one label,
 \key{start}, and the whole program will be it's tail.
 %
-The $\itm{info}$ field of the program construt, after the
+The $\itm{info}$ field of the program construct, after the
 \key{uncover-locals} pass, will contain a mapping from the symbol
 \key{locals} to a list of variables, that is, a list of all the
 variables used in the program. At the start of the program, these
@@ -1940,7 +1944,7 @@ translating from $C_0$ to x86. The target language of this pass is a
 pseudo-x86 language that still uses variables, so we add an AST node
 of the form $\VAR{\itm{var}}$ to the x86 abstract syntax.  We
 recommend implementing the \code{select-instructions} in terms of
-three auxilliary functions, one for each of the non-terminals of
+three auxiliary functions, one for each of the non-terminals of
 $C_0$: $\Arg$, $\Stmt$, and $\Tail$.
 
 The cases for $\itm{arg}$ are straightforward, simply putting
@@ -2249,7 +2253,7 @@ Section~\ref{sec:liveness-analysis-r1} is how we compute where a variable
 is needed.  Once we have that information, we compute which variables
 are needed at the same time, i.e., which ones \emph{interfere}, and
 represent this relation as graph whose vertices are variables and
-edges indicate when two variables interfere with eachother
+edges indicate when two variables interfere with each other
 (Section~\ref{sec:build-interference}). We then model register
 allocation as a graph coloring problem, which we discuss in
 Section~\ref{sec:graph-coloring}.
@@ -3604,7 +3608,7 @@ in the EFLAGS register matches the condition code \itm{cc}, otherwise
 the \key{jmp-if} instruction falls through to the next
 instruction. Because the \key{jmp-if} instruction relies on the EFLAGS
 register, it is quite common for the \key{jmp-if} to be immediately
-preceeded by a \key{cmpq} instruction, to set the EFLAGS regsiter.
+preceded by a \key{cmpq} instruction, to set the EFLAGS register.
 Our abstract syntax for \key{jmp-if} differs from the concrete syntax
 for x86 to separate the instruction name from the condition code. For
 example, \code{(jmp-if le foo)} corresponds to \code{jle foo}.
@@ -3804,7 +3808,7 @@ function, \code{explicate-control-pred}, that takes an $R_2$
 expression and two pieces of $C_1$ code (two $\Tail$'s) for the
 then-branch and else-branch. The output of
 \code{explicate-control-pred} is a $C_1$ $\Tail$.  However, these
-three functions also need to contruct the control-flow graph, which we
+three functions also need to construct the control-flow graph, which we
 recommend they do via updates to a global variable. Next we consider
 the specific additions to the tail and assign functions, and some of
 cases for the pred function.
@@ -3845,7 +3849,7 @@ 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 branches of the
 enclosing \key{if}. One of the base cases of this function is when the
-expression is a less-than comparision. We translate it to a
+expression is a less-than comparison. We translate it to a
 conditional \code{goto}. We need labels for the two branches $B_1$ and
 $B_2$, so we add them to the control flow graph and obtain some labels
 $\ell_1$ and $\ell_2$. The translation of the less-than comparison is
@@ -3888,7 +3892,7 @@ B_5
 Recall that the \code{select-instructions} pass lowers from our
 $C$-like intermediate representation to the pseudo-x86 language, which
 is suitable for conducting register allocation. The pass is
-implemented using three auxilliary functions, one for each of the
+implemented using three auxiliary functions, one for each of the
 non-terminals $\Arg$, $\Stmt$, and $\Tail$.
 
 For $\Arg$, we have new cases for the Booleans.  We take the usual
@@ -4392,7 +4396,7 @@ In this chapter we study the implementation of mutable tuples (called
 ``vectors'' in Racket). This language feature is the first to use the
 computer's \emph{heap} because the lifetime of a Racket tuple is
 indefinite, that is, a tuple lives forever from the programmer's
-viewpoint. Of course, from an implementor's viewpoint, it is important
+viewpoint. Of course, from an implementer's viewpoint, it is important
 to reclaim the space associated with a tuple when it is no longer
 needed, which is why we also study \emph{garbage collection}
 techniques in this chapter.
@@ -4608,7 +4612,7 @@ garbage collector goes to work to make more room.
 
 The garbage collector must be careful not to reclaim tuples that will
 be used by the program in the future. Of course, it is impossible in
-general to predict what a program will do, but we can overapproximate
+general to predict what a program will do, but we can over approximate
 the will-be-used tuples by preserving all tuples that could be
 accessed by \emph{any} program given the current computer state.  A
 program could access any tuple whose address is in a register or on
@@ -4637,7 +4641,7 @@ pointer relationships. For example, the pointer in the register still
 points to a 2-tuple whose first element is a 3-tuple and second
 element is a 2-tuple.  There are four tuples that are not reachable
 from the root set and therefore do not get copied into the ToSpace.
-(The sitation in Figure~\ref{fig:copying-collector}, with a
+(The situation in Figure~\ref{fig:copying-collector}, with a
 cycle, cannot be created by a well-typed program in $R_3$. However,
 creating cycles will be possible once we get to $R_6$.  We design
 the garbage collector to deal with cycles to begin with, so we will
@@ -4772,7 +4776,7 @@ in on the tags for two of the tuples in the example from
 Figure~\ref{fig:copying-collector}. Note that we have drawn the bits
 in a big-endian way, from right-to-left, with bit location 0 (the
 least significant bit) on the far right, which corresponds to the
-directionality of the x86 shifting instructions \key{salq} (shift
+directional of the x86 shifting instructions \key{salq} (shift
 left) and \key{sarq} (shift right). Part of each tag is dedicated to
 specifying which elements of the tuple are pointers, the part labeled
 ``pointer mask''. Within the pointer mask, a 1 bit indicates there is
@@ -4898,7 +4902,7 @@ before \code{flatten} because \code{expose-allocation} introduces new
 variables, which can be done locally with \code{let}, but \code{let}
 is gone after \code{flatten}.  In the following, we show the
 transformation for the \code{vector} form into let-bindings for the
-intializing expressions, by a conditional \code{collect}, an
+initializing expressions, by a conditional \code{collect}, an
 \code{allocate}, and the initialization of the vector.
 (The \itm{len} is the length of the vector and \itm{bytes} is how many
 total bytes need to be allocated for the vector, which is 8 for the
@@ -5121,7 +5125,7 @@ bytes (64 bits) and we use 8 bytes for the tag. Last but not least, we
 initialize the \itm{tag}. Refer to Figure~\ref{fig:tuple-rep} to see
 how the tag is organized. We recommend using the Racket operations
 \code{bitwise-ior} and \code{arithmetic-shift} to compute the tag.
-The type annoation in the \code{vector} form is used to determine the
+The type annotation in the \code{vector} form is used to determine the
 pointer mask region of the tag.
 \begin{lstlisting}
    (assign |$\itm{lhs}$| (allocate |$\itm{len}$| (Vector |$\itm{type} \ldots$|)))
@@ -5317,7 +5321,7 @@ bytes. In the conclusion we decrement \code{r15} by 8 bytes.
 One issue that deserves special care is that there may be a call to
 \code{collect} prior to the initializing assignments for all the
 variables in the root stack. We do not want the garbage collector to
-accidentaly think that some uninitialized variable is a pointer that
+accidentally think that some uninitialized variable is a pointer that
 needs to be followed. Thus, we zero-out all locations on the root
 stack in the prelude of \code{main}. In
 Figure~\ref{fig:print-x86-output-gc}, the instruction
@@ -5562,7 +5566,7 @@ that does what its name suggests. The program then applies
 The definitional interpreter for $R_4$ is in
 Figure~\ref{fig:interp-R4}. The case for the \code{program} form is
 responsible for setting up the mutual recursion between the top-level
-function definitions. We use the classic backpatching approach that
+function definitions. We use the classic back-patching approach that
 uses mutable variables and makes two passes over the function
 definitions~\citep{Kelsey:1998di}.  In the first pass we set up the
 top-level environment using a mutable cons cell for each function
@@ -5804,7 +5808,7 @@ that would unnecessarily overwrite the return address. Instead we can
 simply use the \key{jmp} instruction. Like the indirect function call,
 we write an indirect jump with a register prefixed with an asterisk.
 We recommend using \code{rax} to hold the jump target because the
-preceeding ``conclusion'' overwrites just about everything else.
+preceding ``conclusion'' overwrites just about everything else.
 \begin{lstlisting}
    jmp *%rax
 \end{lstlisting}
@@ -5925,7 +5929,7 @@ $\Rightarrow$
 \end{minipage}
 \end{tabular}
 
-In the body of the function, all occurrances of the $i$th argument in
+In the body of the function, all occurrences of the $i$th argument in
 which $i>5$ must be replaced with a \code{vector-ref}.
 
 \section{Remove Complex Operators and Operands}
@@ -6098,7 +6102,7 @@ name \code{tail-jmp}.
 
 Recall that in Section~\ref{sec:explicate-control-r1} we recommended
 using the label \code{start} for the initial block of a program, and
-in Section~\ref{sec:select-r1} we recommended labelling the conclusion
+in Section~\ref{sec:select-r1} we recommended labeling the conclusion
 of the program with \code{conclusion}, so that $(\key{return}\;\Arg)$
 can be compiled to an assignment to \code{rax} followed by a jump to
 \code{conclusion}. With the addition of function definitions, we will
@@ -6174,7 +6178,7 @@ definitions.
 Figure~\ref{fig:add-fun} shows an example translation of a simple
 function in $R_4$ to x86. The figure also includes the results of the
 \code{explicate-control} and \code{select-instructions} passes.  We
-have ommited the \code{has-type} AST nodes for readability.  Can you
+have omitted the \code{has-type} AST nodes for readability.  Can you
 see any ways to improve the translation?
 
 \begin{figure}[tbp]
@@ -6423,7 +6427,7 @@ the result of this program is \code{42}.
 The syntax for this language with anonymous functions and lexical
 scoping, $R_5$, is defined in Figure~\ref{fig:r5-syntax}. It adds the
 \key{lambda} form to the grammar for $R_4$, which already has syntax
-for function application.  In this chapter we shall descibe how to
+for function application.  In this chapter we shall describe how to
 compile $R_5$ back into $R_4$, compiling lexically-scoped functions
 into a combination of functions (as in $R_4$) and tuples (as in
 $R_3$).
@@ -6463,10 +6467,10 @@ $R_3$).
 
 To compile lexically-scoped functions to top-level function
 definitions, the compiler will need to provide special treatment to
-variable occurences such as \code{x} and \code{y} in the body of the
+variable occurrences such as \code{x} and \code{y} in the body of the
 \code{lambda} of Figure~\ref{fig:lexical-scoping}, for the functions
 of $R_4$ may not refer to variables defined outside the function. To
-identify such variable occurences, we review the standard notion of
+identify such variable occurrences, we review the standard notion of
 free variable.
 
 \begin{definition}
@@ -6478,7 +6482,7 @@ $e$.
 For example, the variables \code{x}, \code{y}, and \code{z} are all
 free with respect to the expression \code{(+ x (+ y z))}.  On the
 other hand, only \code{x} and \code{y} are free with respect to the
-following expression becuase \code{z} is bound by the \code{lambda}.
+following expression because \code{z} is bound by the \code{lambda}.
 \begin{lstlisting}
    (lambda: ([z : Integer]) : Integer
       (+ x (+ y z)))
@@ -6626,7 +6630,7 @@ type to the function in the closure's type, and it does not matter.
 The sequence of \key{let} forms bind the free variables to their
 values obtained from the closure.
 
-We transform function application into code that retreives the
+We transform function application into code that retrieves the
 function pointer from the closure and then calls the function, passing
 in the closure as the first argument. We bind $e'$ to a temporary
 variable to avoid code duplication.
@@ -6808,7 +6812,7 @@ are called \emph{polymorphic}. There are many kinds of polymorphism,
 such as subtype polymorphism and parametric
 polymorphism~\citep{Cardelli:1985kx}. The kind of polymorphism are
 talking about here does not have a special name, but it is the usual
-kind that arrises in dynamically typed languages.
+kind that arises in dynamically typed languages.
 
 Another characteristic of dynamically typed languages is that
 primitive operations, such as \code{not}, are often defined to operate
@@ -6935,7 +6939,7 @@ steal the 3 right-most bits from our 64-bit values to encode the
 runtime type.  We shall use $001$ to identify integers, $100$ for
 Booleans, $010$ for vectors, $011$ for procedures, and $101$ for the
 void value. We shall refer to these 3 bits as the \emph{tag} and we
-define the following auxilliary function.
+define the following auxiliary function.
 \begin{align*}
 \itm{tagof}(\key{Integer}) &= 001 \\
 \itm{tagof}(\key{Boolean}) &= 100 \\
@@ -7105,7 +7109,7 @@ Figure~\ref{fig:interp-R6}.
                      [else #f]))]
      ...))
 
-;; Equavalence of flat types
+;; Equivalence of flat types
 (define (tyeq? t1 t2)
   (match `(,t1 ,t2)
     [`((Vectorof Any) (Vector ,t2s ...))
@@ -7148,7 +7152,7 @@ of type \code{Any}.  The \code{value-of-any} retrieves the underlying
 value from a tagged value. Finally, the \code{exit} operation ends the
 execution of the program by invoking the operating system's
 \code{exit} function. So the translation for \code{project} is as
-follows. (We have ommitted the \code{has-type} AST nodes to make this
+follows. (We have omitted the \code{has-type} AST nodes to make this
 output more readable.)
 
 \begin{tabular}{lll}
@@ -7313,7 +7317,7 @@ of type \code{Any} in the same way that it treats variables of type
   the pass \code{build-interference} to mark all variables that are
   live after a \code{callq} as interfering with all the registers.
 
-\item If avariable of type \code{Any} is spilled, it must be spilled
+\item If a variable of type \code{Any} is spilled, it must be spilled
   to the root stack instead of the normal procedure call stack.
 \end{itemize}
 
@@ -7521,7 +7525,7 @@ The \key{lookup} function takes a key and an association list (a list
 of key-value pairs), and returns the first value that is associated
 with the given key, if there is one. If not, an error is triggered.
 The association list may contain both immutable pairs (built with
-\key{cons}) and mutable mapirs (built with \key{mcons}).
+\key{cons}) and mutable pairs (built with \key{mcons}).
 
 The \key{map2} function ...
 
@@ -7678,4 +7682,15 @@ registers.
 %%  LocalWords:  arg bitwise XOR'd thenlabel immediates optimizations
 %%  LocalWords:  deallocating Ungar Detlefs Tene kx FromSpace ToSpace
 %%  LocalWords:  Appel Diwan Siebert ptr  fromspace rootstack typedef
-%%  LocalWords:  len prev rootlen heaplen setl lt
+%%  LocalWords:  len prev rootlen heaplen setl lt Kohlbecker dk multi
+% LocalWords:  Bloomington Wollowski definitional whitespace deref JM
+% LocalWords:  subexpression subexpressions iteratively ANF Danvy rco
+% LocalWords:  goto stmt JS ly cmp ty le ge jle goto's EFLAG CFG pred
+% LocalWords:  acyclic worklist Aho qf tsort implementer's hj Shidal
+% LocalWords:  nonnegative Shahriyar endian salq sarq uint cheney ior
+% LocalWords:  tospace vecinit collectret alloc initret decrement jl
+% LocalWords:  dereferencing GC di vals ps mcons ds mcdr callee's th
+% LocalWords:  mainDef tailcall prepending mainstart num params rT qb
+% LocalWords:  mainconclusion Cardelli bodyT fvs clos fvts subtype uj
+% LocalWords:  polymorphism untyped elts tys tagof Vectorof tyeq orq
+% LocalWords:  andq untagged Shao inlining ebp jge setle setg setge