Jeremy Siek il y a 3 ans
Parent
commit
377f482217
2 fichiers modifiés avec 89 ajouts et 98 suppressions
  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
 %% \margincomment{\scriptsize Be more explicit about how to deal with
 %%   the root stack. \\ --Jeremy}
 %%   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
 This language feature is the first to use the computer's
 \emph{heap}\index{subject}{heap} because the lifetime of a tuple is
 \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}
 \section{Challenge: Arrays}
 \label{sec: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,
 The Racket language does not distinguish between tuples and arrays,
 they are both represented by vectors. However, Typed Racket
 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
 useful in many examples involving arrays such as computing the
 inner-product of two arrays (Figure~\ref{fig:inner-product}).
 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]
 \begin{figure}[tp]
 \centering
 \centering
@@ -12669,28 +12676,16 @@ inner-product of two arrays (Figure~\ref{fig:inner-product}).
     \small
     \small
 {\if\edition\racketEd    
 {\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}
 \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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -12707,7 +12702,7 @@ UNDER CONSTRUCTION
 \begin{figure}[tp]
 \begin{figure}[tp]
 \begin{lstlisting}
 \begin{lstlisting}
 (define (inner-product [A : (Vectorof Integer)] [B : (Vectorof Integer)]
 (define (inner-product [A : (Vectorof Integer)] [B : (Vectorof Integer)]
-                       [n : Integer]) : Integer
+                          [n : Integer]) : Integer
   (let ([i 0])
   (let ([i 0])
     (let ([prod 0])
     (let ([prod 0])
       (begin
       (begin
@@ -12730,7 +12725,7 @@ UNDER CONSTRUCTION
 \end{figure}
 \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
 Figure~\ref{fig:type-check-Lvecof}. The result type of
 \code{make-vector} is \code{(Vectorof T)} where \code{T} is the type
 \code{make-vector} is \code{(Vectorof T)} where \code{T} is the type
 of the intializing expression.  The length expression is required to
 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
 \code{vectorof} form so that later passes can easily distinguish
 between operations on tuples versus arrays. We override the
 between operations on tuples versus arrays. We override the
 \code{operator-types} method to provide the type signature for
 \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{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define type-check-Lvecof-class
 (define type-check-Lvecof-class
-  (class type-check-Lwhile-class
+  (class type-check-Lvec-class
     (super-new)
     (super-new)
     (inherit check-type-equal?)
     (inherit check-type-equal?)
 
 
-    (define/override (flat-ty? ty)
-      (match ty
-        ['(Vectorof Any) #t]
-        [else (super flat-ty? ty)]))
-    
     (define/override (operator-types)
     (define/override (operator-types)
       (append '((* . ((Integer Integer) . Integer)))
       (append '((* . ((Integer Integer) . Integer)))
               (super operator-types)))
               (super operator-types)))
@@ -12813,11 +12800,10 @@ integers.
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 (define interp-Lvecof-class
 (define interp-Lvecof-class
-  (class interp-Lwhile-class
+  (class interp-Lvec-class
     (super-new)
     (super-new)
 
 
     (define/override (interp-op op)
     (define/override (interp-op op)
-      (verbose "Lvecof/interp-op" op)
       (match op
       (match op
         ['make-vector make-vector]
         ['make-vector make-vector]
         ['* fx*]
         ['* fx*]
@@ -12864,59 +12850,65 @@ an array:
 \end{itemize}
 \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
 In the following subsections we provide hints regarding how to update
 the passes to handle arrays.
 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}
 \subsection{Expose Allocation}
 
 
 This pass should translate the \code{make-vector} operator into
 This pass should translate the \code{make-vector} operator into
 lower-level operations. In particular, the new AST node
 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
 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}
 \subsection{Remove Complex Operands}
 
 
@@ -12943,23 +12935,21 @@ Section~\ref{sec:array-rep}.
 The instructions generated for \code{vectorof-ref} differ from those
 The instructions generated for \code{vectorof-ref} differ from those
 for \code{vector-ref} (Section~\ref{sec:select-instructions-gc}) in
 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
 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
 \begin{exercise}\normalfont\normalsize
 
 
 Implement a compiler for the \LangArray{} language by extending your
 Implement a compiler for the \LangArray{} language by extending your
 compiler for \LangLoop{}. Test your compiler on a half dozen new
 compiler for \LangLoop{}. Test your compiler on a half dozen new
 programs, including the one in Figure~\ref{fig:inner-product} and also
 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.
 arrays by laying out each row in the array, one after the next.
   
   
 \end{exercise}
 \end{exercise}
@@ -17237,6 +17227,7 @@ class TypeCheckLany(TypeCheckLlambda):
   (match ty
   (match ty
     [(or `Integer `Boolean '_ `Void) #t]
     [(or `Integer `Boolean '_ `Void) #t]
     [`(Vector ,ts ...) (for/and ([t ts]) (eq? t 'Any))]
     [`(Vector ,ts ...) (for/and ([t ts]) (eq? t 'Any))]
+    ['(Vectorof Any) #t]
     [`(,ts ... -> ,rt)
     [`(,ts ... -> ,rt)
       (and (eq? rt 'Any) (for/and ([t ts]) (eq? t 'Any)))]
       (and (eq? rt 'Any) (for/and ([t ts]) (eq? t 'Any)))]
     [else #f]))
     [else #f]))

+ 1 - 1
defs.tex

@@ -64,7 +64,7 @@
 \newcommand{\LangCLoop}{$\CLang_{\circlearrowleft}$} %C7
 \newcommand{\LangCLoop}{$\CLang_{\circlearrowleft}$} %C7
 \newcommand{\LangCLoopM}{\CLang_{\circlearrowleft}} %C7
 \newcommand{\LangCLoopM}{\CLang_{\circlearrowleft}} %C7
 \newcommand{\LangLoopANF}{\ensuremath{\Lang^{\RCO}_{\mathsf{While}}}} %R8
 \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{\LangGrad}{$\Lang_{\mathsf{?}}$} %R9
 \newcommand{\LangGradM}{\Lang_{\mathsf{?}}} %R9
 \newcommand{\LangGradM}{\Lang_{\mathsf{?}}} %R9
 \newcommand{\LangCast}{$\Lang_{\mathsf{cast}}$} %R9'
 \newcommand{\LangCast}{$\Lang_{\mathsf{cast}}$} %R9'