|
@@ -26,7 +26,7 @@
|
|
|
|
|
|
\def\racketEd{0}
|
|
\def\racketEd{0}
|
|
\def\pythonEd{1}
|
|
\def\pythonEd{1}
|
|
-\def\edition{0}
|
|
|
|
|
|
+\def\edition{1}
|
|
|
|
|
|
% material that is specific to the Racket edition of the book
|
|
% material that is specific to the Racket edition of the book
|
|
\newcommand{\racket}[1]{{\if\edition\racketEd{#1}\fi}}
|
|
\newcommand{\racket}[1]{{\if\edition\racketEd{#1}\fi}}
|
|
@@ -39,6 +39,20 @@
|
|
% material that is specific to the Python edition of the book
|
|
% material that is specific to the Python edition of the book
|
|
\newcommand{\python}[1]{{\if\edition\pythonEd\pythonColor #1\fi}}
|
|
\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:
|
|
%% For multiple indices:
|
|
%\usepackage{multind} moved this to the file TimesAPriori_MIT.cls. -Jeremy
|
|
%\usepackage{multind} moved this to the file TimesAPriori_MIT.cls. -Jeremy
|
|
\makeindex{subject}
|
|
\makeindex{subject}
|
|
@@ -4351,7 +4365,7 @@ regular expressions.
|
|
\end{itemize}
|
|
\end{itemize}
|
|
|
|
|
|
In a Lark grammar file, each kind of token is specified by a
|
|
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
|
|
that consists of the name of the terminal followed by a colon followed
|
|
by a sequence of literals. The literals include strings such as
|
|
by a sequence of literals. The literals include strings such as
|
|
\code{"abc"}, regular expressions surrounded by \code{/} characters,
|
|
\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
|
|
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
|
|
specify the abstract syntax of a language. We now take a closer look
|
|
at using grammar rules to specify the concrete syntax. Recall that
|
|
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
|
|
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
|
|
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
|
|
of a pattern for an abstract syntax tree. In particular, each
|
|
right-hand side is a sequence of
|
|
right-hand side is a sequence of
|
|
\emph{symbols}\index{subject}{symbol}, where a symbol is either a
|
|
\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}
|
|
\end{lstlisting}
|
|
Change your compiler from chapter~\ref{ch:Lvar} to use your
|
|
Change your compiler from chapter~\ref{ch:Lvar} to use your
|
|
Lark parser instead of using the \code{parse} function from
|
|
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
|
|
programs that you have created, and create four additional programs
|
|
that test for ambiguities in your grammar.
|
|
that test for ambiguities in your grammar.
|
|
\end{exercise}
|
|
\end{exercise}
|
|
@@ -4655,7 +4669,7 @@ learn about the LALR(1) algorithm, which is more efficient but cannot
|
|
handle all context-free grammars.
|
|
handle all context-free grammars.
|
|
|
|
|
|
Earley's algorithm can be viewed as an interpreter; it treats the
|
|
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
|
|
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
|
|
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
|
|
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
|
|
exp: exp "+" . exp_hi
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
represents a partial parse that has matched an \code{exp} followed by
|
|
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{+}.
|
|
\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
|
|
repeats three actions---prediction, scanning, and completion---for as
|
|
long as opportunities arise. We demonstrate Earley's algorithm on a
|
|
long as opportunities arise. We demonstrate Earley's algorithm on a
|
|
running example, parsing the following program:
|
|
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
|
|
which in turn completes \code{lang\_int}, the start symbol of the
|
|
grammar, so the parsing of the input is complete.
|
|
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.
|
|
algorithm.
|
|
\begin{enumerate}
|
|
\begin{enumerate}
|
|
\item The algorithm begins by initializing slot $0$ of the chart with the
|
|
\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
|
|
A particularly influential implementation of LALR(1) is the
|
|
\texttt{yacc} parser generator by \citet{Johnson:1979qy};
|
|
\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
|
|
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
|
|
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}.}
|
|
$\ttm{x}$ interferes with \ttm{w} and \ttm{rsp}.}
|
|
%
|
|
%
|
|
\python{The fourth instruction is \lstinline{addq $7, x}, and the
|
|
\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}.}
|
|
$\ttm{x}$ interferes with \ttm{w}.}
|
|
%
|
|
%
|
|
\racket{The next instruction is \lstinline{movq x, y}, and the
|
|
\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
|
|
$C$ language~\citep{Kernighan:1988nx} in that it has labels and
|
|
\code{goto} statements, so we name it \LangCIf{}.
|
|
\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
|
|
the arguments of operators are restricted to atomic expressions. The
|
|
\LangCIf{} language does not include \code{if} expressions, but it does
|
|
\LangCIf{} language does not include \code{if} expressions, but it does
|
|
include a restricted form of \code{if} statement. The condition must be
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
sides, concatenated with its continuation.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
\begin{figure}[tbp]
|
|
@@ -9449,11 +9463,11 @@ branch. The \code{explicate\_pred} function should match on
|
|
%
|
|
%
|
|
{\if\edition\pythonEd\pythonColor
|
|
{\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
|
|
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.
|
|
dictionary of basic blocks.
|
|
|
|
|
|
\fi}
|
|
\fi}
|
|
@@ -10402,7 +10416,7 @@ function instead of recomputing it each time. The following
|
|
return self.cache
|
|
return self.cache
|
|
\end{lstlisting}
|
|
\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
|
|
of statements, and in other cases we return a function that
|
|
computes a list of statements. To uniformly deal with both regular
|
|
computes a list of statements. To uniformly deal with both regular
|
|
data and promises, we define the following \code{force} function that
|
|
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
|
|
At first glance, the translation of \code{while} loops to x86 seems
|
|
straightforward because the \LangCIf{} intermediate language already
|
|
straightforward because the \LangCIf{} intermediate language already
|
|
supports \code{goto} and conditional branching. However, there are
|
|
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.
|
|
that we introduce the changes necessary to the existing passes.
|
|
%
|
|
%
|
|
\fi}
|
|
\fi}
|
|
@@ -17296,7 +17310,7 @@ print(f(0, 10)(32))
|
|
|
|
|
|
Many of our compiler passes rely on being able to connect variable
|
|
Many of our compiler passes rely on being able to connect variable
|
|
uses with their definitions using just the name of the
|
|
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
|
|
not uniquely determine its definition. To solve this problem we
|
|
recommend implementing a pass named \code{uniquify} that renames every
|
|
recommend implementing a pass named \code{uniquify} that renames every
|
|
variable in the program to make sure that they are all unique.
|
|
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
|
|
(representing a closure) and extract the $5$ bits starting at position
|
|
$58$ from the tag.}
|
|
$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]
|
|
\begin{tcolorbox}[colback=white]
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
\begin{tikzpicture}[baseline=(current bounding box.center),scale=0.85]
|
|
\begin{tikzpicture}[baseline=(current bounding box.center),scale=0.85]
|
|
@@ -18053,8 +18068,6 @@ $58$ from the tag.}
|
|
\label{fig:Llambda-passes}
|
|
\label{fig:Llambda-passes}
|
|
\end{figure}
|
|
\end{figure}
|
|
|
|
|
|
-Figure~\ref{fig:Llambda-passes} provides an overview of the passes
|
|
|
|
-needed for the compilation of \LangLam{}.
|
|
|
|
|
|
|
|
\clearpage
|
|
\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
|
|
to use for type checking the expression $e'$. Thus, we run into
|
|
difficulty if $e'$ is a \code{Lambda} expression. We recommend
|
|
difficulty if $e'$ is a \code{Lambda} expression. We recommend
|
|
translating \code{Lambda} to a new AST class \code{AnnLambda} (for
|
|
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.
|
|
parameters.
|
|
%
|
|
%
|
|
\fi}
|
|
\fi}
|
|
@@ -19704,8 +19717,8 @@ translated in a similar way:
|
|
%
|
|
%
|
|
The \code{any\_tuple\_load} operation combines the projection action
|
|
The \code{any\_tuple\_load} operation combines the projection action
|
|
with the load operation. Also, the load operation allows arbitrary
|
|
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
|
|
within bounds. Thus, we insert code to perform bounds checking at
|
|
runtime. The translation for \code{any\_tuple\_load} is as follows.
|
|
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.
|
|
%% 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}
|
|
\label{sec:register-allocation-Lany}
|
|
\index{subject}{register allocation}
|
|
\index{subject}{register allocation}
|
|
|
|
|
|
@@ -20103,8 +20116,10 @@ nevertheless they should be valid \LangDyn{} programs that run to
|
|
completion without error.
|
|
completion without error.
|
|
\end{exercise}
|
|
\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]
|
|
\begin{tcolorbox}[colback=white]
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
\begin{tikzpicture}[baseline=(current bounding box.center),scale=0.85]
|
|
\begin{tikzpicture}[baseline=(current bounding box.center),scale=0.85]
|
|
@@ -20228,8 +20243,6 @@ completion without error.
|
|
\label{fig:Ldyn-passes}
|
|
\label{fig:Ldyn-passes}
|
|
\end{figure}
|
|
\end{figure}
|
|
|
|
|
|
-Figure~\ref{fig:Ldyn-passes} provides an overview of the passes needed
|
|
|
|
-for the compilation of \LangDyn{}.
|
|
|
|
|
|
|
|
% Further Reading
|
|
% Further Reading
|
|
|
|
|
|
@@ -20416,7 +20429,7 @@ next two sections.
|
|
|
|
|
|
%\clearpage
|
|
%\clearpage
|
|
|
|
|
|
-\section{Type Checking \LangGrad{}}
|
|
|
|
|
|
+\section{Type Checking \LangGrad{} \vspace{-2pt}}
|
|
\label{sec:gradual-type-check}
|
|
\label{sec:gradual-type-check}
|
|
|
|
|
|
We begin by discussing the type checking of a partially typed variant
|
|
We begin by discussing the type checking of a partially typed variant
|
|
@@ -20516,6 +20529,7 @@ def consistent(self, t1, t2):
|
|
return t1 == t2
|
|
return t1 == t2
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\fi}
|
|
\fi}
|
|
|
|
+\vspace{-5pt}
|
|
\end{tcolorbox}
|
|
\end{tcolorbox}
|
|
|
|
|
|
\caption{The consistency method on types.}
|
|
\caption{The consistency method on types.}
|
|
@@ -20575,7 +20589,6 @@ and \ref{fig:type-check-Lgradual-3}.
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
def map(f : Callable[[int], int], v : tuple[int,int]) -> tuple[int,int]:
|
|
def map(f : Callable[[int], int], v : tuple[int,int]) -> tuple[int,int]:
|
|
return f(v[0]), f(v[1])
|
|
return f(v[0]), f(v[1])
|
|
-
|
|
|
|
def inc(x):
|
|
def inc(x):
|
|
return x + 1
|
|
return x + 1
|
|
def true():
|
|
def true():
|
|
@@ -20587,6 +20600,7 @@ t = map(maybe_inc, (0, 41))
|
|
print(t[1])
|
|
print(t[1])
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\fi}
|
|
\fi}
|
|
|
|
+\vspace{-5pt}
|
|
\end{tcolorbox}
|
|
\end{tcolorbox}
|
|
|
|
|
|
\caption{A variant of the \code{map} example with an error.}
|
|
\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]
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
def map(f : Callable[[int], int], v : tuple[int,int]) -> tuple[int,int]:
|
|
def map(f : Callable[[int], int], v : tuple[int,int]) -> tuple[int,int]:
|
|
return f(v[0]), f(v[1])
|
|
return f(v[0]), f(v[1])
|
|
-
|
|
|
|
def inc(x : Any) -> Any:
|
|
def inc(x : Any) -> Any:
|
|
return Cast(Cast(x, Any, int) + 1, int, Any)
|
|
return Cast(Cast(x, Any, int) + 1, int, Any)
|
|
def true() -> Any:
|
|
def true() -> Any:
|
|
@@ -20657,6 +20670,7 @@ t = map(Cast(maybe_inc, Callable[[Any], Any], Callable[[int], int]),
|
|
print(t[1])
|
|
print(t[1])
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\fi}
|
|
\fi}
|
|
|
|
+\vspace{-5pt}
|
|
\end{tcolorbox}
|
|
\end{tcolorbox}
|
|
|
|
|
|
\caption{Output of the \code{cast\_insert} pass for the \code{map}
|
|
\caption{Output of the \code{cast\_insert} pass for the \code{map}
|
|
@@ -21012,10 +21026,9 @@ def check_consistent(self, t1, t2, e):
|
|
|
|
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
-
|
|
|
|
\clearpage
|
|
\clearpage
|
|
|
|
|
|
-\section{Interpreting \LangCast{}}
|
|
|
|
|
|
+\section{Interpreting \LangCast{} \vspace{-2pt}}
|
|
\label{sec:interp-casts}
|
|
\label{sec:interp-casts}
|
|
|
|
|
|
The runtime behavior of casts involving simple types such as
|
|
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
|
|
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} types would be to build a new
|
|
\racket{tuple}\python{array} whose elements are the result
|
|
\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.
|
|
type. However, this approach is not valid for mutable data structures.
|
|
In the example of figure~\ref{fig:map-bang},
|
|
In the example of figure~\ref{fig:map-bang},
|
|
if the cast created a new \racket{tuple}\python{array}, then the updates inside
|
|
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
|
|
\code{map\_inplace} would happen to the new \racket{tuple}\python{array} and not
|
|
the original one.
|
|
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{figure}[tbp]
|
|
\begin{tcolorbox}[colback=white]
|
|
\begin{tcolorbox}[colback=white]
|
|
% gradual_test_11.rkt
|
|
% gradual_test_11.rkt
|
|
@@ -21115,39 +21160,7 @@ print(v[1])
|
|
\label{fig:map-bang}
|
|
\label{fig:map-bang}
|
|
\end{figure}
|
|
\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]
|
|
\begin{tcolorbox}[colback=white]
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
@@ -21410,7 +21423,7 @@ class InterpLcast(InterpLany):
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
{\if\edition\pythonEd\pythonColor
|
|
{\if\edition\pythonEd\pythonColor
|
|
-\section{Overload Resolution}
|
|
|
|
|
|
+\section{Overload Resolution \vspace{-2pt}}
|
|
\label{sec:gradual-resolution}
|
|
\label{sec:gradual-resolution}
|
|
|
|
|
|
Recall that when we added support for arrays in
|
|
Recall that when we added support for arrays in
|
|
@@ -21429,7 +21442,7 @@ access and length operations to the primitives \code{any\_load},
|
|
|
|
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
-\section{Cast Insertion}
|
|
|
|
|
|
+\section{Cast Insertion \vspace{-2pt}}
|
|
\label{sec:gradual-insert-casts}
|
|
\label{sec:gradual-insert-casts}
|
|
|
|
|
|
In our discussion of type checking of \LangGrad{}, we mentioned how
|
|
In our discussion of type checking of \LangGrad{}, we mentioned how
|
|
@@ -21487,7 +21500,7 @@ tuples of type \CANYTY{}: \code{any-vector-length},
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
|
|
|
|
-\section{Lower Casts}
|
|
|
|
|
|
+\section{Lower Casts \vspace{-2pt}}
|
|
\label{sec:lower_casts}
|
|
\label{sec:lower_casts}
|
|
|
|
|
|
The next step in the journey toward x86 is the \code{lower\_casts}
|
|
The next step in the journey toward x86 is the \code{lower\_casts}
|
|
@@ -21662,7 +21675,7 @@ def main() -> int:
|
|
\end{figure}
|
|
\end{figure}
|
|
|
|
|
|
|
|
|
|
-\section{Differentiate Proxies}
|
|
|
|
|
|
+\section{Differentiate Proxies \vspace{-2pt}}
|
|
\label{sec:differentiate-proxies}
|
|
\label{sec:differentiate-proxies}
|
|
|
|
|
|
So far, the responsibility of differentiating tuples and tuple 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.
|
|
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}
|
|
\label{sec:reveal-casts-gradual}
|
|
|
|
|
|
{\if\edition\racketEd
|
|
{\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.
|
|
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}
|
|
\label{sec:closure-conversion-gradual}
|
|
|
|
|
|
The auxiliary function that translates type annotations needs to be
|
|
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
|
|
Otherwise, the only other changes are adding cases that copy the new
|
|
AST nodes.
|
|
AST nodes.
|
|
|
|
|
|
-\section{Select Instructions}
|
|
|
|
|
|
+\section{Select Instructions \vspace{-2pt}}
|
|
\label{sec:select-instructions-gradual}
|
|
\label{sec:select-instructions-gradual}
|
|
\index{subject}{select instructions}
|
|
\index{subject}{select instructions}
|
|
|
|
|
|
@@ -23638,6 +23651,8 @@ reference per instruction. Other operands must be immediates or
|
|
registers.
|
|
registers.
|
|
|
|
|
|
\begin{table}[tbp]
|
|
\begin{table}[tbp]
|
|
|
|
+ \captionabove{Quick reference for the x86 instructions used in this book.}
|
|
|
|
+ \label{tab:x86-instr}
|
|
\centering
|
|
\centering
|
|
\begin{tabular}{l|l}
|
|
\begin{tabular}{l|l}
|
|
\textbf{Instruction} & \textbf{Operation} \\ \hline
|
|
\textbf{Instruction} & \textbf{Operation} \\ \hline
|
|
@@ -23684,9 +23699,6 @@ registers.
|
|
\texttt{setg} $A$ & \\
|
|
\texttt{setg} $A$ & \\
|
|
\texttt{setge} $A$ &
|
|
\texttt{setge} $A$ &
|
|
\end{tabular}
|
|
\end{tabular}
|
|
-\vspace{5pt}
|
|
|
|
- \caption{Quick reference for the x86 instructions used in this book.}
|
|
|
|
- \label{tab:x86-instr}
|
|
|
|
\end{table}
|
|
\end{table}
|
|
|
|
|
|
|
|
|