|
@@ -7610,12 +7610,12 @@ language includes several operations that involve Booleans
|
|
|
conditional expression\index{subject}{conditional expression}
|
|
|
\python{ and statement\index{subject}{IfStmt@\IFSTMTNAME{}}}.
|
|
|
With the addition of \key{if}, programs can have
|
|
|
-nontrivial control flow\index{subject}{control flow} which
|
|
|
+nontrivial control flow\index{subject}{control flow}, which
|
|
|
%
|
|
|
\racket{impacts \code{explicate\_control} and liveness analysis.}
|
|
|
%
|
|
|
\python{impacts liveness analysis and motivates a new pass named
|
|
|
- \code{explicate\_control}.}%
|
|
|
+ \code{explicate\_control}.}
|
|
|
%
|
|
|
Also, because we now have two kinds of values, we need to handle
|
|
|
programs that apply an operation to the wrong kind of value, such as
|
|
@@ -7634,7 +7634,7 @@ treats nonzero integers as if they were \racket{\code{\#t}}\python{\code{True}}.
|
|
|
in Racket because \code{car} expects a pair.}
|
|
|
%
|
|
|
\python{On the other hand, \code{1[0]} results in a runtime error
|
|
|
- in Python because an ``\code{int} object is not subscriptable''.}
|
|
|
+ in Python because an ``\code{int} object is not subscriptable.''}
|
|
|
|
|
|
\racket{Typed Racket}\python{The MyPy type checker} makes similar
|
|
|
design choices as \racket{Racket}\python{Python}, except that much of the
|
|
@@ -7646,7 +7646,7 @@ of \racket{\code{(car 1)}}\python{\code{1[0]}}, \racket{Typed Racket}
|
|
|
\racket{because Racket expects the type of the argument to be of the form
|
|
|
\code{(Listof T)} or \code{(Pairof T1 T2)}.}
|
|
|
%
|
|
|
-\python{stating that a ``value of type \code{int} is not indexable''.}
|
|
|
+\python{stating that a ``value of type \code{int} is not indexable.''}
|
|
|
|
|
|
The \LangIf{} language performs type checking during compilation just as
|
|
|
\racket{Typed Racket}\python{MyPy}. In chapter~\ref{ch:Ldyn} we study
|
|
@@ -8350,14 +8350,15 @@ The type of a Boolean constant is \BOOLTY{}.
|
|
|
\racket{The \code{operator-types} function adds dictionary entries for
|
|
|
the new operators.}
|
|
|
%
|
|
|
-\python{Logical not requires its argument to be a \BOOLTY{} and
|
|
|
- produces a \BOOLTY{}. Similarly for logical and and logical or. }
|
|
|
+\python{The logical \code{not} operator requires its argument to be a
|
|
|
+ \BOOLTY{} and produces a \BOOLTY{}. Similarly for the logical \code{and}
|
|
|
+ and logical \code{or} operators.}
|
|
|
%
|
|
|
The equality operator requires the two arguments to have the same type,
|
|
|
and therefore we handle it separately from the other operators.
|
|
|
%
|
|
|
\python{The other comparisons (less-than, etc.) require their
|
|
|
-arguments to be of type \INTTY{} and they produce a \BOOLTY{}.}
|
|
|
+arguments to be of type \INTTY{}, and they produce a \BOOLTY{}.}
|
|
|
%
|
|
|
The condition of an \code{if} must
|
|
|
be of \BOOLTY{} type, and the two branches must have the same type.
|
|
@@ -8421,9 +8422,9 @@ $C$ language~\citep{Kernighan:1988nx} in that it has labels and
|
|
|
%
|
|
|
The \LangCIf{} language supports the same operators as \LangIf{} but
|
|
|
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
|
|
|
-a comparison and the two branches may only contain \code{goto}
|
|
|
+a comparison, and the two branches may contain only \code{goto}
|
|
|
statements. These restrictions make it easier to translate \code{if}
|
|
|
statements to x86. The \LangCIf{} language also adds a \code{return}
|
|
|
statement to finish the program with a specified value.
|
|
@@ -8436,9 +8437,9 @@ either a \code{return} statement, a \code{goto}, or an
|
|
|
A \code{goto} transfers control to the sequence of statements
|
|
|
associated with its label.
|
|
|
%
|
|
|
-The concrete syntax for \LangCIf{} is defined in
|
|
|
-figure~\ref{fig:c1-concrete-syntax} and the abstract syntax is defined
|
|
|
-in figure~\ref{fig:c1-syntax}.
|
|
|
+Figure~\ref{fig:c1-concrete-syntax} shows the concrete syntax for \LangCIf{},
|
|
|
+and figure~\ref{fig:c1-syntax} shows its
|
|
|
+abstract syntax.
|
|
|
%
|
|
|
\fi}
|
|
|
%
|
|
@@ -8556,8 +8557,9 @@ in figure~\ref{fig:c1-syntax}.
|
|
|
|
|
|
\section{The \LangXIf{} Language}
|
|
|
\label{sec:x86-if}
|
|
|
+\index{subject}{x86}
|
|
|
|
|
|
-\index{subject}{x86} To implement the new logical operations, the
|
|
|
+To implement the new logical operations, the
|
|
|
comparison operations, and the \key{if} expression\python{ and
|
|
|
statement}, we delve further into the x86
|
|
|
language. Figures~\ref{fig:x86-1-concrete} and \ref{fig:x86-1} present
|
|
@@ -8814,12 +8816,12 @@ the \code{not} operator and comparison operators must be atomic.
|
|
|
in the translation of \code{if} expressions. When we recursively
|
|
|
process the two branches of the \code{if}, we generate temporary
|
|
|
variables and their initializing expressions. However, these
|
|
|
- expressions may contain side effects and should only be executed
|
|
|
+ expressions may contain side effects and should be executed only
|
|
|
when the condition of the \code{if} is true (for the ``then''
|
|
|
branch) or false (for the ``else'' branch). The \code{Begin} provides
|
|
|
a way to initialize the temporary variables within the two branches
|
|
|
of the \code{if} expression. In general, the $\BEGIN{ss}{e}$
|
|
|
- form execute the statements $ss$ and then returns the result of
|
|
|
+ form executes the statements $ss$ and then returns the result of
|
|
|
expression $e$.}
|
|
|
|
|
|
Add cases to the \code{rco\_exp} and \code{rco\_atom} functions for
|
|
@@ -9196,10 +9198,10 @@ def create_block(stmts, basic_blocks):
|
|
|
Figure~\ref{fig:explicate-control-Lif} provides a skeleton for the
|
|
|
\code{explicate\_control} pass.
|
|
|
|
|
|
-The \code{explicate\_effect} function has three parameters: 1) the
|
|
|
-expression to be compiled, 2) the already-compiled code for this
|
|
|
+The \code{explicate\_effect} function has three parameters: (1) the
|
|
|
+expression to be compiled; (2) the already-compiled code for this
|
|
|
expression's \emph{continuation}, that is, the list of statements that
|
|
|
-should execute after this expression, and 3) the dictionary of
|
|
|
+should execute after this expression; and (3) the dictionary of
|
|
|
generated basic blocks. The \code{explicate\_effect} function returns
|
|
|
a list of \LangCIf{} statements and it may add to the dictionary of
|
|
|
basic blocks.
|
|
@@ -9207,18 +9209,18 @@ basic blocks.
|
|
|
Let's consider a few of the cases for the expression to be compiled.
|
|
|
If the expression to be compiled is a constant, then it can be
|
|
|
discarded because it has no side effects. If it's a \CREAD{}, then it
|
|
|
-has a side-effect and should be preserved. So the expression should be
|
|
|
+has a side effect and should be preserved. So the expression should be
|
|
|
translated into a statement using the \code{Expr} AST class. If the
|
|
|
expression to be compiled is an \code{if} expression, we translate the
|
|
|
two branches using \code{explicate\_effect} and then translate the
|
|
|
condition expression using \code{explicate\_pred}, which generates
|
|
|
code for the entire \code{if}.
|
|
|
|
|
|
-The \code{explicate\_assign} function has four parameters: 1) the
|
|
|
-right-hand side of the assignment, 2) the left-hand side of the
|
|
|
-assignment (the variable), 3) the continuation, and 4) the dictionary
|
|
|
+The \code{explicate\_assign} function has four parameters: (1) the
|
|
|
+right-hand side of the assignment, (2) the left-hand side of the
|
|
|
+assignment (the variable), (3) the continuation, and (4) the dictionary
|
|
|
of basic blocks. The \code{explicate\_assign} function returns a list
|
|
|
-of \LangCIf{} statements and it may add to the dictionary of basic
|
|
|
+of \LangCIf{} statements, and it may add to the dictionary of basic
|
|
|
blocks.
|
|
|
|
|
|
When the right-hand side is an \code{if} expression, there is some
|
|
@@ -9544,24 +9546,24 @@ with a \key{goto}.
|
|
|
{\if\edition\pythonEd\pythonColor
|
|
|
%
|
|
|
The last of the auxiliary functions is \code{explicate\_stmt}. It has
|
|
|
-three parameters: 1) the statement to be compiled, 2) the code for its
|
|
|
-continuation, and 3) the dictionary of basic blocks. The
|
|
|
-\code{explicate\_stmt} returns a list of statements and it may add to
|
|
|
+three parameters: (1) the statement to be compiled, (2) the code for its
|
|
|
+continuation, and (3) the dictionary of basic blocks. The
|
|
|
+\code{explicate\_stmt} returns a list of statements, and it may add to
|
|
|
the dictionary of basic blocks. The cases for assignment and an
|
|
|
expression-statement are given in full in the skeleton code: they
|
|
|
simply dispatch to \code{explicate\_assign} and
|
|
|
\code{explicate\_effect}, respectively. The case for \code{if}
|
|
|
-statements is not given, and is similar to the case for \code{if}
|
|
|
+statements is not given; it is similar to the case for \code{if}
|
|
|
expressions.
|
|
|
|
|
|
The \code{explicate\_control} function itself is given in
|
|
|
figure~\ref{fig:explicate-control-Lif}. It applies
|
|
|
\code{explicate\_stmt} to each statement in the program, from back to
|
|
|
-front. Thus, the result so-far, stored in \code{new\_body}, can be
|
|
|
+front. Thus, the result so far, stored in \code{new\_body}, can be
|
|
|
used as the continuation parameter in the next call to
|
|
|
\code{explicate\_stmt}. The \code{new\_body} is initialized to a
|
|
|
\code{Return} statement. Once complete, we add the \code{new\_body} to
|
|
|
-the dictionary of basic blocks, labeling it as the ``start'' block.
|
|
|
+the dictionary of basic blocks, labeling it the ``start'' block.
|
|
|
%
|
|
|
\fi}
|
|
|
|
|
@@ -10353,7 +10355,7 @@ promise, \code{force} simply returns the argument.
|
|
|
%
|
|
|
{\if\edition\pythonEd\pythonColor
|
|
|
%
|
|
|
-While Python does not provide direct support for lazy evaluation, it
|
|
|
+Although Python does not provide direct support for lazy evaluation, it
|
|
|
is easy to mimic. We can \emph{delay} the evaluation of a computation
|
|
|
by wrapping it inside a function with no parameters. We can
|
|
|
\emph{force} its evaluation by calling the function. However, we might
|
|
@@ -10375,12 +10377,12 @@ class Promise:
|
|
|
return self.cache
|
|
|
\end{lstlisting}
|
|
|
%
|
|
|
-However, in some cases of \code{explicate\_pred}, etc., we will return
|
|
|
-a list of statements and in other cases we will return a function that
|
|
|
+However, in some cases of \code{explicate\_pred} we will return a list
|
|
|
+of statements, and in other cases we will return a function that
|
|
|
computes a list of statements. To uniformly deal with both regular
|
|
|
data and promises, we define the following \code{force} function that
|
|
|
checks whether its input is delayed (i.e., whether it is a
|
|
|
-\code{Promise}) and then either 1) forces the promise , or 2) returns
|
|
|
+\code{Promise}) and then either (1) forces the promise or (2) returns
|
|
|
the input.
|
|
|
%
|
|
|
\begin{lstlisting}
|