Jeremy Siek 3 жил өмнө
parent
commit
377f482217
2 өөрчлөгдсөн 89 нэмэгдсэн , 98 устгасан
  1. 88 97
      book.tex
  2. 1 1
      defs.tex

+ 88 - 97
book.tex

@@ -10846,8 +10846,9 @@ for the compilation of \LangLoop{}.
 %% \margincomment{\scriptsize Be more explicit about how to deal with
 %%   the root stack. \\ --Jeremy}
 
-In this chapter we study the implementation of
-tuples\racket{, called vectors in Racket}.
+In this chapter we study the implementation of tuples\racket{, called
+  vectors in Racket}.  A tuple is a fixed-length sequence of elements
+where each element may have a different type.
 %
 This language feature is the first to use the computer's
 \emph{heap}\index{subject}{heap} because the lifetime of a tuple is
@@ -12636,13 +12637,12 @@ mark. The following example uses \code{set-point-x!} to change the
 \section{Challenge: Arrays}
 \label{sec:arrays}
 
-In Chapter~\ref{ch:Lvec} we studied tuples, that is, sequences of
-elements whose length is determined at compile-time and where each
-element of a tuple may have a different type (they are
-heterogeous). This challenge is also about sequences, but this time
-the length is determined at run-time and all the elements have the same
-type (they are homogeneous). We use the term ``array'' for this later
-kind of sequence.
+In Chapter~\ref{ch:Lvec} we studied tuples, that is, a heterogeous
+sequences of elements whose length is determined at compile-time. This
+challenge is also about sequences, but this time the length is
+determined at run-time and all the elements have the same type (they
+are homogeneous). We use the term ``array'' for this later kind of
+sequence.
 
 The Racket language does not distinguish between tuples and arrays,
 they are both represented by vectors. However, Typed Racket
@@ -12661,6 +12661,13 @@ We also include integer multiplication in \LangArray{}, as it is
 useful in many examples involving arrays such as computing the
 inner-product of two arrays (Figure~\ref{fig:inner-product}).
 
+\newcommand{\LarrayGrammarRacket}{
+\begin{array}{lcl}
+  \Type &::=& \LP \key{Vectorof}~\Type \RP \\
+  \Exp &::=& \CMUL{\Exp}{\Exp}
+       \MID \CMAKEVEC{\Exp}{\Exp} \\
+\end{array}
+}
 
 \begin{figure}[tp]
 \centering
@@ -12669,28 +12676,16 @@ inner-product of two arrays (Figure~\ref{fig:inner-product}).
     \small
 {\if\edition\racketEd    
 \[
+\begin{array}{l}
+  \gray{\LintGrammarRacket{}} \\ \hline
+  \gray{\LvarGrammarRacket{}} \\ \hline
+  \gray{\LifGrammarRacket{}} \\ \hline
+  \gray{\LwhileGrammarRacket} \\ \hline
+  \gray{\LtupGrammarRacket} \\ \hline
+  \LarrayGrammarRacket \\
 \begin{array}{lcl}
-  \Type &::=& \ldots \MID \LP \key{Vectorof}~\Type \RP \\
-  \Exp &::=& \gray{ \Int \MID \CREAD{} \MID \CNEG{\Exp}
-     \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} }  \MID \CMUL{\Exp}{\Exp}\\
-    &\MID&  \gray{ \Var \MID \CLET{\Var}{\Exp}{\Exp} }\\
-    &\MID& \gray{\key{\#t} \MID \key{\#f} 
-     \MID \LP\key{and}\;\Exp\;\Exp\RP 
-     \MID \LP\key{or}\;\Exp\;\Exp\RP 
-     \MID \LP\key{not}\;\Exp\RP } \\
-    &\MID& \gray{ \LP\key{eq?}\;\Exp\;\Exp\RP \MID \CIF{\Exp}{\Exp}{\Exp} } \\
-    &\MID& \gray{ \LP\key{vector}\;\Exp\ldots\RP \MID
-          \LP\key{vector-ref}\;\Exp\;\Int\RP} \\
-    &\MID& \gray{\LP\key{vector-set!}\;\Exp\;\Int\;\Exp\RP\MID \LP\key{void}\RP
-    \MID \LP\Exp \; \Exp\ldots\RP } \\
-    &\MID& \gray{ \LP \key{procedure-arity}~\Exp\RP 
-    \MID \CLAMBDA{\LP\LS\Var \key{:} \Type\RS\ldots\RP}{\Type}{\Exp} } \\
-  &\MID& \gray{ \CSETBANG{\Var}{\Exp}
-  \MID \CBEGIN{\Exp\ldots}{\Exp}
-  \MID \CWHILE{\Exp}{\Exp} } \\
-  &\MID& \CMAKEVEC{\Exp}{\Exp} \\
-  \Def &::=& \gray{ \CDEF{\Var}{\LS\Var \key{:} \Type\RS\ldots}{\Type}{\Exp} } \\
-  \LangArray{} &::=& \gray{\Def\ldots \; \Exp}
+  \LangArray{} &::=& \Exp
+\end{array}
 \end{array}
 \]
 \fi}
@@ -12707,7 +12702,7 @@ UNDER CONSTRUCTION
 \begin{figure}[tp]
 \begin{lstlisting}
 (define (inner-product [A : (Vectorof Integer)] [B : (Vectorof Integer)]
-                       [n : Integer]) : Integer
+                          [n : Integer]) : Integer
   (let ([i 0])
     (let ([prod 0])
       (begin
@@ -12730,7 +12725,7 @@ UNDER CONSTRUCTION
 \end{figure}
 
 
-The type checker for \LangArray{} is define in
+The type checker for \LangArray{} is defined in
 Figure~\ref{fig:type-check-Lvecof}. The result type of
 \code{make-vector} is \code{(Vectorof T)} where \code{T} is the type
 of the intializing expression.  The length expression is required to
@@ -12741,23 +12736,15 @@ updated to handle the situation where the vector has type
 \code{vectorof} form so that later passes can easily distinguish
 between operations on tuples versus arrays. We override the
 \code{operator-types} method to provide the type signature for
-multiplication: it takes two integers and returns an integer.  To
-support injection and projection of arrays to the \code{Any} type
-(Section~\ref{sec:Rany-lang}), we also override the \code{flat-ty?}
-predicate.
+multiplication: it takes two integers and returns an integer.
 
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define type-check-Lvecof-class
-  (class type-check-Lwhile-class
+  (class type-check-Lvec-class
     (super-new)
     (inherit check-type-equal?)
 
-    (define/override (flat-ty? ty)
-      (match ty
-        ['(Vectorof Any) #t]
-        [else (super flat-ty? ty)]))
-    
     (define/override (operator-types)
       (append '((* . ((Integer Integer) . Integer)))
               (super operator-types)))
@@ -12813,11 +12800,10 @@ integers.
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define interp-Lvecof-class
-  (class interp-Lwhile-class
+  (class interp-Lvec-class
     (super-new)
 
     (define/override (interp-op op)
-      (verbose "Lvecof/interp-op" op)
       (match op
         ['make-vector make-vector]
         ['* fx*]
@@ -12864,59 +12850,65 @@ an array:
 \end{itemize}
 
 
-Recall that in Chapter~\ref{ch:Ldyn}, we use a $3$-bit tag to
-differentiate the kinds of values that have been injected into the
-\code{Any} type. We use the bit pattern \code{110} (or $6$ in decimal)
-to indicate that the value is an array.
+%% Recall that in Chapter~\ref{ch:Ldyn}, we use a $3$-bit tag to
+%% differentiate the kinds of values that have been injected into the
+%% \code{Any} type. We use the bit pattern \code{110} (or $6$ in decimal)
+%% to indicate that the value is an array.
 
 In the following subsections we provide hints regarding how to update
 the passes to handle arrays.
 
-
-\subsection{Reveal Casts}
-
-The array-access operators \code{vectorof-ref} and
-\code{vectorof-set!} are similar to the \code{any-vector-ref} and
-\code{any-vector-set!} operators of Chapter~\ref{ch:Ldyn} in
-that the type checker cannot tell whether the index will be in bounds,
-so the bounds check must be performed at run time.  Recall that the
-\code{reveal-casts} pass (Section~\ref{sec:reveal-casts-Rany}) wraps
-an \code{If} arround a vector reference for update to check whether
-the index is less than the length.  You should do the same for
-\code{vectorof-ref} and \code{vectorof-set!} .
-
-In addition, the handling of the \code{any-vector} operators in
-\code{reveal-casts} needs to be updated to account for arrays that are
-injected to \code{Any}. For the \code{any-vector-length} operator, the
-generated code should test whether the tag is for tuples (\code{010})
-or arrays (\code{110}) and then dispatch to either
-\code{any-vector-length} or \code{any-vectorof-length}.  For the later
-we add a case in \code{select\_instructions} to generate the
-appropriate instructions for accessing the array length from the
-header of an array.
-
-For the \code{any-vector-ref} and \code{any-vector-set!} operators,
-the generated code needs to check that the index is less than the
-vector length, so like the code for \code{any-vector-length}, check
-the tag to determine whether to use \code{any-vector-length} or
-\code{any-vectorof-length} for this purpose.  Once the bounds checking
-is complete, the generated code can use \code{any-vector-ref} and
-\code{any-vector-set!} for both tuples and arrays because the
-instructions used for those operators do not look at the tag at the
-front of the tuple or array.
+\subsection{Bounds Checking}
+
+We recommend inserting a new pass named \code{check\_bounds} that
+inserts code around each the \code{vector-ref} and \code{vector-set!}
+operation to ensure that the index is greater than or equal to zero
+and less than the \code{vector-length}.
+
+%% \subsection{Reveal Casts}
+
+%% The array-access operators \code{vectorof-ref} and
+%% \code{vectorof-set!} are similar to the \code{any-vector-ref} and
+%% \code{any-vector-set!} operators of Chapter~\ref{ch:Ldyn} in
+%% that the type checker cannot tell whether the index will be in bounds,
+%% so the bounds check must be performed at run time.  Recall that the
+%% \code{reveal-casts} pass (Section~\ref{sec:reveal-casts-Rany}) wraps
+%% an \code{If} arround a vector reference for update to check whether
+%% the index is less than the length.  You should do the same for
+%% \code{vectorof-ref} and \code{vectorof-set!} .
+
+%% In addition, the handling of the \code{any-vector} operators in
+%% \code{reveal-casts} needs to be updated to account for arrays that are
+%% injected to \code{Any}. For the \code{any-vector-length} operator, the
+%% generated code should test whether the tag is for tuples (\code{010})
+%% or arrays (\code{110}) and then dispatch to either
+%% \code{any-vector-length} or \code{any-vectorof-length}.  For the later
+%% we add a case in \code{select\_instructions} to generate the
+%% appropriate instructions for accessing the array length from the
+%% header of an array.
+
+%% For the \code{any-vector-ref} and \code{any-vector-set!} operators,
+%% the generated code needs to check that the index is less than the
+%% vector length, so like the code for \code{any-vector-length}, check
+%% the tag to determine whether to use \code{any-vector-length} or
+%% \code{any-vectorof-length} for this purpose.  Once the bounds checking
+%% is complete, the generated code can use \code{any-vector-ref} and
+%% \code{any-vector-set!} for both tuples and arrays because the
+%% instructions used for those operators do not look at the tag at the
+%% front of the tuple or array.
 
 \subsection{Expose Allocation}
 
 This pass should translate the \code{make-vector} operator into
 lower-level operations. In particular, the new AST node
-$\LP\key{AllocateArray}~\Exp~\Type\RP$ allocates an array of the
+$\LP\key{AllocateArray}~\Exp~\Type\RP$ is analogous to the
+\code{Allocate} AST node for tuples.  It allocates an array of the
 length specified by the $\Exp$, but does not initialize the elements
-of the array. (Analogous to the \code{Allocate} AST node for tuples.)
-The $\Type$ argument must be $\LP\key{Vectorof}~T\RP$ where $T$ is the
-element type for the array. Regarding the initialization of the array,
-we recommend generated a \code{while} loop that uses
-\code{vector-set!} to put the initializing value into every element of
-the array.
+of the array. The $\Type$ argument must be $\LP\key{Vectorof}~T\RP$
+where $T$ is the element type for the array. Regarding the
+initialization of the array, we recommend generated a \code{while}
+loop that uses \code{vector-set!} to put the initializing value into
+every element of the array.
 
 \subsection{Remove Complex Operands}
 
@@ -12943,23 +12935,21 @@ Section~\ref{sec:array-rep}.
 The instructions generated for \code{vectorof-ref} differ from those
 for \code{vector-ref} (Section~\ref{sec:select-instructions-gc}) in
 that the index is not a constant so the offset must be computed at
-runtime, similar to the instructions generated for
-\code{any-vector-of-ref} (Section~\ref{sec:select-Rany}).  The same is
-true for \code{vectorof-set!}.  Also, the \code{vectorof-set!} may
-appear in an assignment and as a stand-alone statement, so make sure
-to handle both situations in this pass.
+runtime. The same is true for \code{vectorof-set!}.  Also, the
+\code{vectorof-set!} may appear in an assignment and as a stand-alone
+statement, so make sure to handle both situations in this pass.
 
-Finally, the instructions for \code{any-vectorof-length} should be
-similar to those for \code{vectorof-length}, except that one must
-first project the array by writing zeroes into the $3$-bit tag
+%% Finally, the instructions for \code{any-vectorof-length} should be
+%% similar to those for \code{vectorof-length}, except that one must
+%% first project the array by writing zeroes into the $3$-bit tag
 
 \begin{exercise}\normalfont\normalsize
 
 Implement a compiler for the \LangArray{} language by extending your
 compiler for \LangLoop{}. Test your compiler on a half dozen new
 programs, including the one in Figure~\ref{fig:inner-product} and also
-a program that multiplies two matrices. Note that matrices are
-2-dimensional arrays, but those can be encoded into 1-dimensional
+a program that multiplies two matrices. Note that although matrices
+are 2-dimensional arrays, they can be encoded into 1-dimensional
 arrays by laying out each row in the array, one after the next.
   
 \end{exercise}
@@ -17237,6 +17227,7 @@ class TypeCheckLany(TypeCheckLlambda):
   (match ty
     [(or `Integer `Boolean '_ `Void) #t]
     [`(Vector ,ts ...) (for/and ([t ts]) (eq? t 'Any))]
+    ['(Vectorof Any) #t]
     [`(,ts ... -> ,rt)
       (and (eq? rt 'Any) (for/and ([t ts]) (eq? t 'Any)))]
     [else #f]))

+ 1 - 1
defs.tex

@@ -64,7 +64,7 @@
 \newcommand{\LangCLoop}{$\CLang_{\circlearrowleft}$} %C7
 \newcommand{\LangCLoopM}{\CLang_{\circlearrowleft}} %C7
 \newcommand{\LangLoopANF}{\ensuremath{\Lang^{\RCO}_{\mathsf{While}}}} %R8
-\newcommand{\LangArray}{\ensuremath{\Lang^{\mathsf{Vecof}}_{\mathsf{While}}}} %\Lang^s3
+\newcommand{\LangArray}{\ensuremath{\Lang^{\mathsf{Array}}_{\mathsf{While}}}} %\Lang^s3
 \newcommand{\LangGrad}{$\Lang_{\mathsf{?}}$} %R9
 \newcommand{\LangGradM}{\Lang_{\mathsf{?}}} %R9
 \newcommand{\LangCast}{$\Lang_{\mathsf{cast}}$} %R9'