|
@@ -525,7 +525,7 @@ Bloomington, Indiana
|
|
\label{ch:trees-recur}
|
|
\label{ch:trees-recur}
|
|
\setcounter{footnote}{0}
|
|
\setcounter{footnote}{0}
|
|
|
|
|
|
-In this chapter we review the basic tools needed to implement a
|
|
|
|
|
|
+In this chapter we introduce the basic tools needed to implement a
|
|
compiler. Programs are typically input by a programmer as text, that
|
|
compiler. Programs are typically input by a programmer as text, that
|
|
is, a sequence of characters. The program-as-text representation is
|
|
is, a sequence of characters. The program-as-text representation is
|
|
called \emph{concrete syntax}. We use concrete syntax to concisely
|
|
called \emph{concrete syntax}. We use concrete syntax to concisely
|
|
@@ -545,8 +545,8 @@ called \emph{parsing}\index{subject}{parsing}\python{\ and is studied in
|
|
\racket{A parser is provided in the support code for translating from
|
|
\racket{A parser is provided in the support code for translating from
|
|
concrete to abstract syntax.}%
|
|
concrete to abstract syntax.}%
|
|
%
|
|
%
|
|
-\python{For now we use Python's \code{ast} module to translate from concrete
|
|
|
|
- to abstract syntax.}
|
|
|
|
|
|
+\python{For now we use the \code{parse} function in Python's
|
|
|
|
+ \code{ast} module to translate from concrete to abstract syntax.}
|
|
|
|
|
|
ASTs can be represented inside the compiler in many different ways,
|
|
ASTs can be represented inside the compiler in many different ways,
|
|
depending on the programming language used to write the compiler.
|
|
depending on the programming language used to write the compiler.
|
|
@@ -984,9 +984,9 @@ figure~\ref{fig:r0-concrete-syntax} and the abstract syntax for
|
|
\code{read-program} in appendix~\ref{appendix:utilities} for more
|
|
\code{read-program} in appendix~\ref{appendix:utilities} for more
|
|
details.}
|
|
details.}
|
|
%
|
|
%
|
|
-\python{The \code{parse} function in Python's \code{ast} module
|
|
|
|
- converts the concrete syntax (represented as a string) into an
|
|
|
|
- abstract syntax tree.}
|
|
|
|
|
|
+\python{We recommend using the \code{parse} function in Python's
|
|
|
|
+ \code{ast} module to convert the concrete syntax into an abstract
|
|
|
|
+ syntax tree.}
|
|
|
|
|
|
\newcommand{\LintGrammarRacket}{
|
|
\newcommand{\LintGrammarRacket}{
|
|
\begin{array}{rcl}
|
|
\begin{array}{rcl}
|
|
@@ -1277,7 +1277,7 @@ that correspond to a grammar and the body of each
|
|
node.\footnote{This principle of structuring code according to the
|
|
node.\footnote{This principle of structuring code according to the
|
|
data definition is advocated in the book \emph{How to Design
|
|
data definition is advocated in the book \emph{How to Design
|
|
Programs} by \citet{Felleisen:2001aa}.} \python{We define a
|
|
Programs} by \citet{Felleisen:2001aa}.} \python{We define a
|
|
- second function, named \code{stmt}, that recognizes whether a value
|
|
|
|
|
|
+ second function, named \code{is\_stmt}, that recognizes whether a value
|
|
is a \LangInt{} statement.} \python{Finally, }
|
|
is a \LangInt{} statement.} \python{Finally, }
|
|
figure~\ref{fig:exp-predicate} \racket{also} contains the definition of
|
|
figure~\ref{fig:exp-predicate} \racket{also} contains the definition of
|
|
\code{is\_Lint}, which determines whether an AST is a program in \LangInt{}.
|
|
\code{is\_Lint}, which determines whether an AST is a program in \LangInt{}.
|
|
@@ -1329,7 +1329,7 @@ def is_exp(e):
|
|
case _:
|
|
case _:
|
|
return False
|
|
return False
|
|
|
|
|
|
-def stmt(s):
|
|
|
|
|
|
+def is_stmt(s):
|
|
match s:
|
|
match s:
|
|
case Expr(Call(Name('print'), [e])):
|
|
case Expr(Call(Name('print'), [e])):
|
|
return is_exp(e)
|
|
return is_exp(e)
|
|
@@ -1341,7 +1341,7 @@ def stmt(s):
|
|
def is_Lint(p):
|
|
def is_Lint(p):
|
|
match p:
|
|
match p:
|
|
case Module(body):
|
|
case Module(body):
|
|
- return all([stmt(s) for s in body])
|
|
|
|
|
|
+ return all([is_stmt(s) for s in body])
|
|
case _:
|
|
case _:
|
|
return False
|
|
return False
|
|
|
|
|
|
@@ -1511,7 +1511,8 @@ abstract syntax is
|
|
\fi}
|
|
\fi}
|
|
{\if\edition\pythonEd\pythonColor
|
|
{\if\edition\pythonEd\pythonColor
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
- Module([Expr(Call(Name('print'), [BinOp(Constant(10), Add(), Constant(32))]))])
|
|
|
|
|
|
+ Module([Expr(Call(Name('print'),
|
|
|
|
+ [BinOp(Constant(10), Add(), Constant(32))]))])
|
|
\end{lstlisting}
|
|
\end{lstlisting}
|
|
\fi}
|
|
\fi}
|
|
The following program demonstrates that expressions may be nested within
|
|
The following program demonstrates that expressions may be nested within
|
|
@@ -2066,8 +2067,8 @@ in the following program.
|
|
\noindent If we invoke \code{interp\_Lvar} on this program, it
|
|
\noindent If we invoke \code{interp\_Lvar} on this program, it
|
|
dispatches to \code{interp\_Lint} to handle the \code{-} operator, but
|
|
dispatches to \code{interp\_Lint} to handle the \code{-} operator, but
|
|
then it recursively calls \code{interp\_Lint} again on its argument.
|
|
then it recursively calls \code{interp\_Lint} again on its argument.
|
|
-Because there is no case for \code{Var} in \code{interp\_Lint}, we get
|
|
|
|
-an error!
|
|
|
|
|
|
+Because there is no case for \racket{\code{Var}}\python{\code{Name}} in
|
|
|
|
+\code{interp\_Lint}, we get an error!
|
|
|
|
|
|
To make our interpreters extensible we need something called
|
|
To make our interpreters extensible we need something called
|
|
\emph{open recursion}\index{subject}{open recursion}, in which the
|
|
\emph{open recursion}\index{subject}{open recursion}, in which the
|
|
@@ -2080,7 +2081,7 @@ method overriding to interpret \LangInt{} and \LangVar{} using
|
|
\href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
|
|
\href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
|
|
\index{subject}{class} feature of Racket.}%
|
|
\index{subject}{class} feature of Racket.}%
|
|
%
|
|
%
|
|
-\python{a Python \code{class} definition.}
|
|
|
|
|
|
+\python{Python \code{class} definitions.}
|
|
%
|
|
%
|
|
We define one class for each language and define a method for
|
|
We define one class for each language and define a method for
|
|
interpreting expressions inside each class. The class for \LangVar{}
|
|
interpreting expressions inside each class. The class for \LangVar{}
|
|
@@ -2182,9 +2183,9 @@ InterpLvar().interp_exp(e0)
|
|
\code{interp\_exp} in \LangVar{} dispatches to the \code{interp\_exp}
|
|
\code{interp\_exp} in \LangVar{} dispatches to the \code{interp\_exp}
|
|
method in \LangInt{}. But then for the recursive method call, it
|
|
method in \LangInt{}. But then for the recursive method call, it
|
|
dispatches to \code{interp\_exp} in \LangVar{}, where the
|
|
dispatches to \code{interp\_exp} in \LangVar{}, where the
|
|
-\code{Var} node is handled correctly. Thus, method overriding gives us
|
|
|
|
-the open recursion that we need to implement our interpreters in an
|
|
|
|
-extensible way.
|
|
|
|
|
|
+\racket{\code{Var}}\python{\code{Name}} node is handled correctly.
|
|
|
|
+Thus, method overriding gives us the open recursion that we need to
|
|
|
|
+implement our interpreters in an extensible way.
|
|
|
|
|
|
|
|
|
|
\subsection{Definitional Interpreter for \LangVar{}}
|
|
\subsection{Definitional Interpreter for \LangVar{}}
|
|
@@ -2201,7 +2202,7 @@ figure~\ref{fig:interp-Lvar}.
|
|
we discuss in the next paragraph, and \code{cont} for
|
|
we discuss in the next paragraph, and \code{cont} for
|
|
\emph{continuation}, which is the technical name for what comes
|
|
\emph{continuation}, which is the technical name for what comes
|
|
after a particular point in a program. The \code{cont} parameter is
|
|
after a particular point in a program. The \code{cont} parameter is
|
|
- the list of statements that that follow the current statement. Note
|
|
|
|
|
|
+ the list of statements that follow the current statement. Note
|
|
that \code{interp\_stmts} invokes \code{interp\_stmt} on the first
|
|
that \code{interp\_stmts} invokes \code{interp\_stmt} on the first
|
|
statement and passes the rest of the statements as the argument for
|
|
statement and passes the rest of the statements as the argument for
|
|
\code{cont}. This organization enables each statement to decide what
|
|
\code{cont}. This organization enables each statement to decide what
|
|
@@ -2359,8 +2360,8 @@ class InterpLvar(InterpLint):
|
|
|
|
|
|
def interp_stmt(self, s, env, cont):
|
|
def interp_stmt(self, s, env, cont):
|
|
match s:
|
|
match s:
|
|
- case Assign([lhs], value):
|
|
|
|
- env[lhs.id] = self.interp_exp(value, env)
|
|
|
|
|
|
+ case Assign([Name(id)], value):
|
|
|
|
+ env[id] = self.interp_exp(value, env)
|
|
return self.interp_stmts(cont, env)
|
|
return self.interp_stmts(cont, env)
|
|
case _:
|
|
case _:
|
|
return super().interp_stmt(s, env, cont)
|
|
return super().interp_stmt(s, env, cont)
|
|
@@ -2514,7 +2515,7 @@ each of which is an integer constant (called an \emph{immediate
|
|
A register is a special kind of variable that holds a 64-bit
|
|
A register is a special kind of variable that holds a 64-bit
|
|
value. There are 16 general-purpose registers in the computer; their
|
|
value. There are 16 general-purpose registers in the computer; their
|
|
names are given in figure~\ref{fig:x86-int-concrete}. A register is
|
|
names are given in figure~\ref{fig:x86-int-concrete}. A register is
|
|
-written with a percent sign, \key{\%}, followed by the register name,
|
|
|
|
|
|
+written with a percent sign, \key{\%}, followed by its name,
|
|
for example \key{\%rax}.
|
|
for example \key{\%rax}.
|
|
|
|
|
|
An immediate value is written using the notation \key{\$}$n$ where $n$
|
|
An immediate value is written using the notation \key{\$}$n$ where $n$
|
|
@@ -3385,8 +3386,8 @@ in the name \LangVarANF{}. An important invariant of the
|
|
\code{remove\_complex\_operands} pass is that the relative ordering
|
|
\code{remove\_complex\_operands} pass is that the relative ordering
|
|
among complex expressions is not changed, but the relative ordering
|
|
among complex expressions is not changed, but the relative ordering
|
|
between atomic expressions and complex expressions can change and
|
|
between atomic expressions and complex expressions can change and
|
|
-often does. The reason that these changes are behavior preserving is
|
|
|
|
-that the atomic expressions are pure.
|
|
|
|
|
|
+often does. These changes are behavior preserving because
|
|
|
|
+atomic expressions are pure.
|
|
|
|
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
Another well-known form for intermediate languages is the
|
|
Another well-known form for intermediate languages is the
|
|
@@ -3567,24 +3568,10 @@ programs, place \lstinline{(debug-level 1)} before the call to
|
|
|
|
|
|
Create five \LangVar{} programs that exercise the most interesting
|
|
Create five \LangVar{} programs that exercise the most interesting
|
|
parts of the \code{remove\_complex\_operands} pass. The five programs
|
|
parts of the \code{remove\_complex\_operands} pass. The five programs
|
|
-should be placed in the subdirectory named \key{tests}, and the file
|
|
|
|
-names should start with \code{var\_test\_} followed by a unique
|
|
|
|
-integer and end with the file extension \key{.py}.
|
|
|
|
-%% The \key{run-tests.rkt} script in the support code checks whether the
|
|
|
|
-%% output programs produce the same result as the input programs. The
|
|
|
|
-%% script uses the \key{interp-tests} function
|
|
|
|
-%% (Appendix~\ref{appendix:utilities}) from \key{utilities.rkt} to test
|
|
|
|
-%% your \key{uniquify} pass on the example programs. The \code{passes}
|
|
|
|
-%% parameter of \key{interp-tests} is a list that should have one entry
|
|
|
|
-%% for each pass in your compiler. For now, define \code{passes} to
|
|
|
|
-%% contain just one entry for \code{uniquify} as shown below.
|
|
|
|
-%% \begin{lstlisting}
|
|
|
|
-%% (define passes
|
|
|
|
-%% (list (list "uniquify" uniquify interp_Lvar type-check-Lvar)))
|
|
|
|
-%% \end{lstlisting}
|
|
|
|
-Run the \key{run-tests.py} script in the support code to check
|
|
|
|
-whether the output programs produce the same result as the input
|
|
|
|
-programs.
|
|
|
|
|
|
+should be placed in the subdirectory \key{tests/var}, and the file
|
|
|
|
+names should end with the file extension \key{.py}. Run the
|
|
|
|
+\key{run-tests.py} script in the support code to check whether the
|
|
|
|
+output programs produce the same result as the input programs.
|
|
\end{exercise}
|
|
\end{exercise}
|
|
|
|
|
|
\fi}
|
|
\fi}
|
|
@@ -3742,8 +3729,7 @@ translations of $\Atm_1$ and $\Atm_2$, respectively.) There is an
|
|
\key{addq} instruction in x86, but it performs an in-place update.
|
|
\key{addq} instruction in x86, but it performs an in-place update.
|
|
%
|
|
%
|
|
So, we could move $\Arg_1$ into the \code{rax} register, then add
|
|
So, we could move $\Arg_1$ into the \code{rax} register, then add
|
|
-$\Arg_2$ to \code{rax}, and then finally move \code{rax} into the
|
|
|
|
-left-hand \itm{var}.
|
|
|
|
|
|
+$\Arg_2$ to \code{rax}, and then finally move \code{rax} into \itm{var}.
|
|
\begin{transformation}
|
|
\begin{transformation}
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
@@ -3818,8 +3804,8 @@ generated x86 assembly code, you need to compile \code{runtime.c} to
|
|
\code{-c}) and link it into the executable. For our purposes of code
|
|
\code{-c}) and link it into the executable. For our purposes of code
|
|
generation, all you need to do is translate an assignment of
|
|
generation, all you need to do is translate an assignment of
|
|
\READOP{} into a call to the \code{read\_int} function followed by a
|
|
\READOP{} into a call to the \code{read\_int} function followed by a
|
|
-move from \code{rax} to the left-hand side variable. (Recall that the
|
|
|
|
-return value of a function goes into \code{rax}.)
|
|
|
|
|
|
+move from \code{rax} to the left-hand side variable. (The
|
|
|
|
+return value of a function is placed in \code{rax}.)
|
|
\begin{transformation}
|
|
\begin{transformation}
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
\begin{lstlisting}
|
|
\begin{lstlisting}
|
|
@@ -3869,7 +3855,7 @@ recursively and then append the resulting instructions.
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
{\if\edition\pythonEd\pythonColor
|
|
{\if\edition\pythonEd\pythonColor
|
|
-We recommend that you use the function \code{utils.label\_name()} to
|
|
|
|
|
|
+We recommend that you use the function \code{utils.label\_name} to
|
|
transform strings into labels, for example, in
|
|
transform strings into labels, for example, in
|
|
the target of the \code{callq} instruction. This practice makes your
|
|
the target of the \code{callq} instruction. This practice makes your
|
|
compiler portable across Linux and Mac OS X, which requires an underscore
|
|
compiler portable across Linux and Mac OS X, which requires an underscore
|
|
@@ -4098,8 +4084,8 @@ all labels (for example, changing \key{main} to \key{\_main}).
|
|
determining which operating system the compiler is running on. It
|
|
determining which operating system the compiler is running on. It
|
|
returns \code{'macosx}, \code{'unix}, or \code{'windows}.}
|
|
returns \code{'macosx}, \code{'unix}, or \code{'windows}.}
|
|
%
|
|
%
|
|
-\python{The Python \code{platform} library includes a \code{system()}
|
|
|
|
- function that returns \code{\textquotesingle Linux\textquotesingle},
|
|
|
|
|
|
+\python{The Python \code{platform.system}
|
|
|
|
+ function returns \code{\textquotesingle Linux\textquotesingle},
|
|
\code{\textquotesingle Windows\textquotesingle}, or
|
|
\code{\textquotesingle Windows\textquotesingle}, or
|
|
\code{\textquotesingle Darwin\textquotesingle} (for Mac).}
|
|
\code{\textquotesingle Darwin\textquotesingle} (for Mac).}
|
|
|
|
|
|
@@ -4162,7 +4148,7 @@ the \code{pe\_exp}
|
|
\python{and \code{pe\_stmt} functions.}
|
|
\python{and \code{pe\_stmt} functions.}
|
|
%
|
|
%
|
|
Once complete, add the partial evaluation pass to the front of your
|
|
Once complete, add the partial evaluation pass to the front of your
|
|
-compiler, and make sure that your compiler still passes all the
|
|
|
|
|
|
+compiler, and check that your compiler still passes all the
|
|
tests.
|
|
tests.
|
|
\end{exercise}
|
|
\end{exercise}
|
|
|
|
|
|
@@ -6801,7 +6787,7 @@ Run the script to test the \code{patch\_instructions} pass.
|
|
\end{exercise}
|
|
\end{exercise}
|
|
|
|
|
|
|
|
|
|
-\section{Prelude and Conclusion}
|
|
|
|
|
|
+\section{Generate Prelude and Conclusion}
|
|
\label{sec:print-x86-reg-alloc}
|
|
\label{sec:print-x86-reg-alloc}
|
|
\index{subject}{calling conventions}
|
|
\index{subject}{calling conventions}
|
|
\index{subject}{prelude}\index{subject}{conclusion}
|
|
\index{subject}{prelude}\index{subject}{conclusion}
|
|
@@ -10072,7 +10058,7 @@ Add the following entry to the list of \code{passes} in
|
|
|
|
|
|
{\if\edition\pythonEd\pythonColor
|
|
{\if\edition\pythonEd\pythonColor
|
|
|
|
|
|
-\section{Prelude and Conclusion}
|
|
|
|
|
|
+\section{Generate Prelude and Conclusion}
|
|
\label{sec:prelude-conclusion-cond}
|
|
\label{sec:prelude-conclusion-cond}
|
|
|
|
|
|
The generation of the \code{main} function with its prelude and
|
|
The generation of the \code{main} function with its prelude and
|
|
@@ -13792,7 +13778,7 @@ changes to also record the number of spills to the root stack.
|
|
%\section{Patch Instructions}
|
|
%\section{Patch Instructions}
|
|
%[mention that global variables are memory references]
|
|
%[mention that global variables are memory references]
|
|
|
|
|
|
-\section{Prelude and Conclusion}
|
|
|
|
|
|
+\section{Generate Prelude and Conclusion}
|
|
\label{sec:print-x86-gc}
|
|
\label{sec:print-x86-gc}
|
|
\label{sec:prelude-conclusion-x86-gc}
|
|
\label{sec:prelude-conclusion-x86-gc}
|
|
\index{subject}{prelude}\index{subject}{conclusion}
|
|
\index{subject}{prelude}\index{subject}{conclusion}
|
|
@@ -16264,7 +16250,7 @@ register. Additionally, you should ensure that the argument of
|
|
trample many other registers before the tail call, as explained in the
|
|
trample many other registers before the tail call, as explained in the
|
|
next section.
|
|
next section.
|
|
|
|
|
|
-\section{Prelude and Conclusion}
|
|
|
|
|
|
+\section{Generate Prelude and Conclusion}
|
|
|
|
|
|
Now that register allocation is complete, we can translate the
|
|
Now that register allocation is complete, we can translate the
|
|
\code{TailJmp} into a sequence of instructions. A naive translation of
|
|
\code{TailJmp} into a sequence of instructions. A naive translation of
|
|
@@ -17758,7 +17744,7 @@ The top-level function definitions need to be updated to take an extra
|
|
closure parameter, but that parameter is ignored in the body of those
|
|
closure parameter, but that parameter is ignored in the body of those
|
|
functions.
|
|
functions.
|
|
|
|
|
|
-\section{An Example Translation}
|
|
|
|
|
|
+\subsection{An Example Translation}
|
|
\label{sec:example-lambda}
|
|
\label{sec:example-lambda}
|
|
|
|
|
|
Figure~\ref{fig:lexical-functions-example} shows the result of
|
|
Figure~\ref{fig:lexical-functions-example} shows the result of
|
|
@@ -20434,7 +20420,7 @@ next two sections.
|
|
|
|
|
|
%\clearpage
|
|
%\clearpage
|
|
|
|
|
|
-\section{Type Checking \LangGrad{} \vspace{-2pt}}
|
|
|
|
|
|
+\section{Type Checking \LangGrad{}}
|
|
\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
|
|
@@ -21035,7 +21021,7 @@ def check_consistent(self, t1, t2, e):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-\section{Interpreting \LangCast{} \vspace{-2pt}}
|
|
|
|
|
|
+\section{Interpreting \LangCast{} }
|
|
\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
|
|
@@ -21430,7 +21416,7 @@ class InterpLcast(InterpLany):
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
{\if\edition\pythonEd\pythonColor
|
|
{\if\edition\pythonEd\pythonColor
|
|
-\section{Overload Resolution \vspace{-2pt}}
|
|
|
|
|
|
+\section{Overload Resolution }
|
|
\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
|
|
@@ -21449,7 +21435,7 @@ access and length operations to the primitives \code{any\_load},
|
|
|
|
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
-\section{Cast Insertion \vspace{-2pt}}
|
|
|
|
|
|
+\section{Cast Insertion }
|
|
\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
|
|
@@ -21507,7 +21493,7 @@ tuples of type \CANYTY{}: \code{any-vector-length},
|
|
\fi}
|
|
\fi}
|
|
|
|
|
|
|
|
|
|
-\section{Lower Casts \vspace{-2pt}}
|
|
|
|
|
|
+\section{Lower Casts }
|
|
\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}
|
|
@@ -21683,7 +21669,7 @@ def main() -> int:
|
|
|
|
|
|
%\pagebreak
|
|
%\pagebreak
|
|
|
|
|
|
-\section{Differentiate Proxies \vspace{-2pt}}
|
|
|
|
|
|
+\section{Differentiate Proxies }
|
|
\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
|
|
@@ -21925,7 +21911,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 \vspace{-2pt}}
|
|
|
|
|
|
+\section{Reveal Casts }
|
|
\label{sec:reveal-casts-gradual}
|
|
\label{sec:reveal-casts-gradual}
|
|
|
|
|
|
{\if\edition\racketEd
|
|
{\if\edition\racketEd
|
|
@@ -21961,7 +21947,7 @@ Otherwise, the only other changes are adding cases that copy the new AST nodes.
|
|
|
|
|
|
\pagebreak
|
|
\pagebreak
|
|
|
|
|
|
-\section{Closure Conversion \vspace{-2pt}}
|
|
|
|
|
|
+\section{Closure Conversion }
|
|
\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
|
|
@@ -21971,7 +21957,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 \vspace{-2pt}}
|
|
|
|
|
|
+\section{Select Instructions }
|
|
\label{sec:select-instructions-gradual}
|
|
\label{sec:select-instructions-gradual}
|
|
\index{subject}{select instructions}
|
|
\index{subject}{select instructions}
|
|
|
|
|