|
@@ -6979,7 +6979,7 @@ $(\key{boolean?}\,e)$ etc., expect a tagged value and return \key{\#t}
|
|
if the tag corresponds to the predicate, and return \key{\#t}
|
|
if the tag corresponds to the predicate, and return \key{\#t}
|
|
otherwise.
|
|
otherwise.
|
|
%
|
|
%
|
|
-Selctions from the type checker for $R_6$ are shown in
|
|
|
|
|
|
+Selections from the type checker for $R_6$ are shown in
|
|
Figure~\ref{fig:typecheck-R6} and the definitional interpreter for
|
|
Figure~\ref{fig:typecheck-R6} and the definitional interpreter for
|
|
$R_6$ is in Figure~\ref{fig:interp-R6}.
|
|
$R_6$ is in Figure~\ref{fig:interp-R6}.
|
|
|
|
|
|
@@ -7057,16 +7057,6 @@ $R_6$ is in Figure~\ref{fig:interp-R6}.
|
|
|
|
|
|
\clearpage
|
|
\clearpage
|
|
|
|
|
|
-%\section{The $R_7$ Language: Untyped Racket}
|
|
|
|
-%\label{sec:r7-lang}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-%% \section{Compiling $R_6$}
|
|
|
|
-%% \label{sec:compile-r6}
|
|
|
|
-
|
|
|
|
-%% Most of the compiler passes only require straightforward changes. The
|
|
|
|
-%% interesting part is in instruction selection.
|
|
|
|
-
|
|
|
|
\section{Shrinking $R_6$}
|
|
\section{Shrinking $R_6$}
|
|
\label{sec:shrink-r6}
|
|
\label{sec:shrink-r6}
|
|
|
|
|
|
@@ -7110,10 +7100,10 @@ Similarly, we recommend translating the type predicates
|
|
|
|
|
|
We recommend compiling an \key{inject} as follows if the type is
|
|
We recommend compiling an \key{inject} as follows if the type is
|
|
\key{Integer} or \key{Boolean}. The \key{salq} instruction shifts the
|
|
\key{Integer} or \key{Boolean}. The \key{salq} instruction shifts the
|
|
-destination to the left by the number of bits specified by the source
|
|
|
|
-($2$) and it preserves the sign of the integer. We use the \key{orq}
|
|
|
|
-instruction to combine the tag and the value to form the tagged value.
|
|
|
|
-\\
|
|
|
|
|
|
+destination to the left by the number of bits specified its source
|
|
|
|
+argument (in this case $3$, the length of the tag) and it preserves
|
|
|
|
+the sign of the integer. We use the \key{orq} instruction to combine
|
|
|
|
+the tag and the value to form the tagged value. \\
|
|
\begin{tabular}{lll}
|
|
\begin{tabular}{lll}
|
|
\begin{minipage}{0.4\textwidth}
|
|
\begin{minipage}{0.4\textwidth}
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
@@ -7126,16 +7116,15 @@ $\Rightarrow$
|
|
\begin{minipage}{0.5\textwidth}
|
|
\begin{minipage}{0.5\textwidth}
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
(movq |$e'$| |\itm{lhs}'|)
|
|
(movq |$e'$| |\itm{lhs}'|)
|
|
-(salq (int 2) |\itm{lhs}'|)
|
|
|
|
|
|
+(salq (int 3) |\itm{lhs}'|)
|
|
(orq (int |$\itm{tagof}(T)$|) |\itm{lhs}'|)
|
|
(orq (int |$\itm{tagof}(T)$|) |\itm{lhs}'|)
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\end{minipage}
|
|
\end{minipage}
|
|
\end{tabular} \\
|
|
\end{tabular} \\
|
|
The instruction selection for vectors and procedures is different
|
|
The instruction selection for vectors and procedures is different
|
|
because their is no need to shift them to the left. The rightmost 3
|
|
because their is no need to shift them to the left. The rightmost 3
|
|
-bits are already zeros as described above. So we combine the value and
|
|
|
|
-the tag using
|
|
|
|
-\key{orq}. \\
|
|
|
|
|
|
+bits are already zeros as described above. So we just combine the
|
|
|
|
+value and the tag using \key{orq}. \\
|
|
\begin{tabular}{lll}
|
|
\begin{tabular}{lll}
|
|
\begin{minipage}{0.4\textwidth}
|
|
\begin{minipage}{0.4\textwidth}
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
@@ -7151,19 +7140,39 @@ $\Rightarrow$
|
|
(orq (int |$\itm{tagof}(T)$|) |\itm{lhs}'|)
|
|
(orq (int |$\itm{tagof}(T)$|) |\itm{lhs}'|)
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\end{minipage}
|
|
\end{minipage}
|
|
-\end{tabular} \\
|
|
|
|
|
|
+\end{tabular}
|
|
|
|
+
|
|
|
|
+\paragraph{Tag of Any}
|
|
|
|
|
|
-\paragraph{Project}
|
|
|
|
|
|
+Recall that the \code{tag-of-any} operation extracts the type tag from
|
|
|
|
+a value of type \code{Any}. The type tag is the bottom three bits, so
|
|
|
|
+we obtain the tag by taking the bitwise-and of the value with $111$
|
|
|
|
+($7$ in decimal).
|
|
|
|
+
|
|
|
|
+\begin{tabular}{lll}
|
|
|
|
+\begin{minipage}{0.4\textwidth}
|
|
|
|
+\begin{lstlisting}
|
|
|
|
+(assign |\itm{lhs}| (tag-of-any |$e$|))
|
|
|
|
+\end{lstlisting}
|
|
|
|
+\end{minipage}
|
|
|
|
+&
|
|
|
|
+$\Rightarrow$
|
|
|
|
+&
|
|
|
|
+\begin{minipage}{0.5\textwidth}
|
|
|
|
+\begin{lstlisting}
|
|
|
|
+(movq |$e'$| |\itm{lhs}'|)
|
|
|
|
+(andq (int 7) |\itm{lhs}'|)
|
|
|
|
+\end{lstlisting}
|
|
|
|
+\end{minipage}
|
|
|
|
+\end{tabular}
|
|
|
|
|
|
|
|
+\paragraph{Value of Any}
|
|
|
|
|
|
-The instruction selection for \key{project} is a bit more involved.
|
|
|
|
-Like \key{inject}, the instructions are different depending on whether
|
|
|
|
-the type $T$ is a pointer (vector or procedure) or not (Integer or
|
|
|
|
-Boolean). The following shows the instruction selection for Integer
|
|
|
|
-and Boolean. We first check to see if the tag on the tagged value
|
|
|
|
-matches the tag of the target type $T$. If not, we halt the program by
|
|
|
|
-calling the \code{exit} function. If we have a match, we need to
|
|
|
|
-produce an untagged value by shifting it to the right by 2 bits.
|
|
|
|
|
|
+Like \key{inject}, the instructions for \key{value-of-any} are
|
|
|
|
+different depending on whether the type $T$ is a pointer (vector or
|
|
|
|
+procedure) or not (Integer or Boolean). The following shows the
|
|
|
|
+instruction selection for Integer and Boolean. We produce an untagged
|
|
|
|
+value by shifting it to the right by 3 bits.
|
|
%
|
|
%
|
|
\\
|
|
\\
|
|
\begin{tabular}{lll}
|
|
\begin{tabular}{lll}
|
|
@@ -7178,23 +7187,17 @@ $\Rightarrow$
|
|
\begin{minipage}{0.5\textwidth}
|
|
\begin{minipage}{0.5\textwidth}
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
(movq |$e'$| |\itm{lhs}'|)
|
|
(movq |$e'$| |\itm{lhs}'|)
|
|
-(andq (int 3) |\itm{lhs}'|)
|
|
|
|
-(if (eq? |\itm{lhs}'| (int |$\itm{tagof}(T)$|))
|
|
|
|
- ((movq |$e'$| |\itm{lhs}'|)
|
|
|
|
- (sarq (int 2) |\itm{lhs}'|))
|
|
|
|
- ((callq exit)))
|
|
|
|
|
|
+(sarq (int 3) |\itm{lhs}'|)
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\end{minipage}
|
|
\end{minipage}
|
|
\end{tabular} \\
|
|
\end{tabular} \\
|
|
%
|
|
%
|
|
-The case for vectors and procedures begins in a similar way, checking
|
|
|
|
-that the runtime tag matches the target type $T$ and exiting if there
|
|
|
|
-is a mismatch. However, the way in which we convert the tagged value
|
|
|
|
-to a value is different, as there is no need to shift. Instead we need
|
|
|
|
-to zero-out the rightmost 2 bits. We accomplish this by creating the
|
|
|
|
-bit pattern $\ldots 0011$, applying \code{notq} to obtain $\ldots
|
|
|
|
-1100$, and then applying \code{andq} with the tagged value get the
|
|
|
|
-desired result. \\
|
|
|
|
|
|
+In the case for vectors and procedures, there is no need to
|
|
|
|
+shift. Instead we just need to zero-out the rightmost 3 bits. We
|
|
|
|
+accomplish this by creating the bit pattern $\ldots 0111$ ($7$ in
|
|
|
|
+decimal) and apply \code{bitwise-not} to obtain $\ldots 1000$ which we
|
|
|
|
+\code{movq} into the destination $\itm{lhs}$. We then generate
|
|
|
|
+\code{andq} with the tagged value to get the desired result. \\
|
|
%
|
|
%
|
|
\begin{tabular}{lll}
|
|
\begin{tabular}{lll}
|
|
\begin{minipage}{0.4\textwidth}
|
|
\begin{minipage}{0.4\textwidth}
|
|
@@ -7207,20 +7210,15 @@ $\Rightarrow$
|
|
&
|
|
&
|
|
\begin{minipage}{0.5\textwidth}
|
|
\begin{minipage}{0.5\textwidth}
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
-(movq |$e'$| |\itm{lhs}'|)
|
|
|
|
-(andq (int 3) |\itm{lhs}'|)
|
|
|
|
-(if (eq? |\itm{lhs}'| (int |$\itm{tagof}(T)$|))
|
|
|
|
- ((movq (int 3) |\itm{lhs}'|)
|
|
|
|
- (notq |\itm{lhs}'|)
|
|
|
|
- (andq |$e'$| |\itm{lhs}'|))
|
|
|
|
- ((callq exit)))
|
|
|
|
|
|
+(movq (int |$\ldots 1000$|) |\itm{lhs}'|)
|
|
|
|
+(andq |$e'$| |\itm{lhs}'|)
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\end{minipage}
|
|
\end{minipage}
|
|
-\end{tabular} \\
|
|
|
|
|
|
+\end{tabular}
|
|
|
|
|
|
-\paragraph{Type Predicates} We leave it to the reader to
|
|
|
|
-devise a sequence of instructions to implement the type predicates
|
|
|
|
-\key{boolean?}, \key{integer?}, \key{vector?}, and \key{procedure?}.
|
|
|
|
|
|
+%% \paragraph{Type Predicates} We leave it to the reader to
|
|
|
|
+%% devise a sequence of instructions to implement the type predicates
|
|
|
|
+%% \key{boolean?}, \key{integer?}, \key{vector?}, and \key{procedure?}.
|
|
|
|
|
|
\section{Compiling $R_7$ to $R_6$}
|
|
\section{Compiling $R_7$ to $R_6$}
|
|
\label{sec:compile-r7}
|
|
\label{sec:compile-r7}
|
|
@@ -7237,21 +7235,20 @@ The second row of Figure~\ref{fig:compile-r7-r6}, the compilation of
|
|
addition, is representative of compilation for many operations: the
|
|
addition, is representative of compilation for many operations: the
|
|
arguments have type \key{Any} and must be projected to \key{Integer}
|
|
arguments have type \key{Any} and must be projected to \key{Integer}
|
|
before the addition can be performed.
|
|
before the addition can be performed.
|
|
-%
|
|
|
|
|
|
+
|
|
The compilation of \key{lambda} (third row of
|
|
The compilation of \key{lambda} (third row of
|
|
Figure~\ref{fig:compile-r7-r6}) shows what happens when we need to
|
|
Figure~\ref{fig:compile-r7-r6}) shows what happens when we need to
|
|
-produce type annotations, we simply use \key{Any}.
|
|
|
|
|
|
+produce type annotations: we simply use \key{Any}.
|
|
%
|
|
%
|
|
-The compilation of \code{if}, \code{eq?}, and \code{and} all
|
|
|
|
-demonstrate how this pass has to account for some differences in
|
|
|
|
-behavior between $R_7$ and $R_6$. The $R_7$ language is more
|
|
|
|
-permissive than $R_6$ regarding what kind of values can be used in
|
|
|
|
-various places. For example, the condition of an \key{if} does not
|
|
|
|
-have to be a Boolean. Similarly, the arguments of \key{and} do not
|
|
|
|
-need to be Boolean. For \key{eq?}, the arguments need not be of the
|
|
|
|
-same type.
|
|
|
|
|
|
+The compilation of \code{if} and \code{eq?} demonstrate how this pass
|
|
|
|
+has to account for some differences in behavior between $R_7$ and
|
|
|
|
+$R_6$. The $R_7$ language is more permissive than $R_6$ regarding what
|
|
|
|
+kind of values can be used in various places. For example, the
|
|
|
|
+condition of an \key{if} does not have to be a Boolean. For \key{eq?},
|
|
|
|
+the arguments need not be of the same type (but in that case, the
|
|
|
|
+result will be \code{\#f}).
|
|
|
|
|
|
-\begin{figure}[tbp]
|
|
|
|
|
|
+\begin{figure}[btp]
|
|
\centering
|
|
\centering
|
|
\begin{tabular}{|lll|} \hline
|
|
\begin{tabular}{|lll|} \hline
|
|
\begin{minipage}{0.25\textwidth}
|
|
\begin{minipage}{0.25\textwidth}
|
|
@@ -7361,23 +7358,7 @@ $\Rightarrow$
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\end{minipage}
|
|
\end{minipage}
|
|
\\[2ex]\hline
|
|
\\[2ex]\hline
|
|
-\begin{minipage}{0.25\textwidth}
|
|
|
|
-\begin{lstlisting}
|
|
|
|
-(and |$e_1$| |$e_2$|)
|
|
|
|
-\end{lstlisting}
|
|
|
|
-\end{minipage}
|
|
|
|
-&
|
|
|
|
-$\Rightarrow$
|
|
|
|
-&
|
|
|
|
-\begin{minipage}{0.6\textwidth}
|
|
|
|
-\begin{lstlisting}
|
|
|
|
-(let ([tmp |$e'_1$|])
|
|
|
|
- (if (eq? tmp (inject #f Boolean))
|
|
|
|
- tmp
|
|
|
|
- |$e'_2$|))
|
|
|
|
-\end{lstlisting}
|
|
|
|
-\end{minipage} \\\hline
|
|
|
|
-\end{tabular} \\
|
|
|
|
|
|
+\end{tabular}
|
|
|
|
|
|
\caption{Compiling $R_7$ to $R_6$.}
|
|
\caption{Compiling $R_7$ to $R_6$.}
|
|
\label{fig:compile-r7-r6}
|
|
\label{fig:compile-r7-r6}
|