Selaa lähdekoodia

flatten pass for ch 4

Jeremy Siek 9 vuotta sitten
vanhempi
commit
8bd863dd1f
1 muutettua tiedostoa jossa 104 lisäystä ja 122 poistoa
  1. 104 122
      book.tex

+ 104 - 122
book.tex

@@ -1207,7 +1207,7 @@ in the program must be present in this list.
 \Arg &::=& \Int \mid \Var \\
 \Exp &::=& \Arg \mid (\Op \; \Arg^{*})\\
 \Stmt &::=& \ASSIGN{\Var}{\Exp} \mid \RETURN{\Arg} \\
-\Prog & ::= & (\key{program}\;(\Var^{*})\;\Stmt^{+})
+C_0 & ::= & (\key{program}\;(\Var^{*})\;\Stmt^{+})
 \end{array}
 \]
 \end{minipage}
@@ -1400,7 +1400,7 @@ your \key{uniquify} pass on the example programs.
 
 
 \section{Flatten Expressions}
-\label{sec:flatten-s0}
+\label{sec:flatten-r1}
 
 The \code{flatten} pass will transform $R_1$ programs into $C_0$
 programs. In particular, the purpose of the \code{flatten} pass is to
@@ -2369,10 +2369,10 @@ expression. The operators are expanded to include the \key{and} and
 \key{not} operations on Booleans and the \key{eq?} operation for
 comparing two integers and for comparing two Booleans.
 
-\begin{figure}[htbp]
+\begin{figure}[tbp]
 \centering
 \fbox{
-\begin{minipage}{0.85\textwidth}
+\begin{minipage}{0.96\textwidth}
 \[
 \begin{array}{lcl}
   \Op  &::=& \ldots \mid \key{and} \mid \key{not} \mid \key{eq?} \\
@@ -2491,9 +2491,6 @@ use of a variable, it can lookup its type in the associaton list.
 \label{fig:type-check-R2}
 \end{figure}
 
-
-
-
 \begin{exercise}\normalfont
 Complete the implementation of \code{typecheck-R2} and test it on 10
 new example programs in $R_2$ that you choose based on how thoroughly
@@ -2505,137 +2502,122 @@ checker agrees with the value returned by the interpreter, that is, if
 the type checker returns \key{Integer}, then the interpreter should
 return an integer. Likewise, if the type checker returns
 \key{Boolean}, then the interpreter should return \code{\#t} or
-\code{\#f}.
+\code{\#f}. Note that if your type checker does not signal an error
+for a program, then interpreting that program should not encounter an
+error.  If it does, there is something wrong with your type checker.
 \end{exercise}
 
-%% % T ::= Integer | Boolean
-
-%% It is common practice to specify a type system by writing rules for
-%% each kind of AST node. For example, the rule for \key{if} is:
-%% \begin{quote}
-%%   For any expressions $e_1, e_2, e_3$ and any type $T$, if $e_1$ has
-%%   type \key{bool}, $e_2$ has type $T$, and $e_3$ has type $T$, then
-%%   $\IF{e_1}{e_2}{e_3}$ has type $T$.
-%% \end{quote}
-%% It is also common practice to write rules using a horizontal line,
-%% with the conditions written above the line and the conclusion written
-%% below the line.
-%% \begin{equation*}
-%%   \inference{e_1 \text{ has type } \key{bool} & 
-%%         e_2 \text{ has type } T & e_3 \text{ has type } T}
-%%   {\IF{e_1}{e_2}{e_3} \text{ has type } T}
-%% \end{equation*}
-%% Because the phrase ``has type'' is repeated so often in these type
-%% checking rules, it is abbreviated to just a colon. So the above rule
-%% is abbreviated to the following.
-%% \begin{equation*}
-%%   \inference{e_1 : \key{bool} & e_2 : T & e_3 : T}
-%%             {\IF{e_1}{e_2}{e_3} : T}
-%% \end{equation*}
-
-%% The $\LET{x}{e_1}{e_2}$ construct poses an interesting challenge. The
-%% variable $x$ is assigned the value of $e_1$ and then $x$ can be used
-%% inside $e_2$. When we get to an occurrence of $x$ inside $e_2$, how do
-%% we know what type the variable should be?  The answer is that we need
-%% a way to map from variable names to types.  Such a mapping is called a
-%% \emph{type environment} (aka. \emph{symbol table}). The capital Greek
-%% letter gamma, written $\Gamma$, is used for referring to type
-%% environments environments. The notation $\Gamma, x : T$ stands for
-%% making a copy of the environment $\Gamma$ and then associating $T$
-%% with the variable $x$ in the new environment.  We write $\Gamma(x)$ to
-%% lookup the associated type for $x$.  The type checking rules for
-%% \key{let} and variables are as follows.
-%% \begin{equation*}
-%%   \inference{e_1 : T_1 \text{ in } \Gamma &
-%%              e_2 : T_2 \text{ in } \Gamma,x:T_1}
-%%             {\LET{x}{e_1}{e_2} : T_2 \text{ in } \Gamma} 
-%%   \qquad
-%%   \inference{\Gamma(x) = T}
-%%             {x : T \text{ in } \Gamma}
-%% \end{equation*}
-%% Type checking has roots in logic, and logicians have a tradition of
-%% writing the environment on the left-hand side and separating it from
-%% the expression with a turn-stile ($\vdash$).  The turn-stile does not
-%% have any intrinsic meaning per se.  It is punctuation that separates
-%% the environment $\Gamma$ from the expression $e$.  So the above typing
-%% rules are written as follows.
-%% \begin{equation*}
-%%   \inference{\Gamma \vdash e_1 : T_1 &
-%%              \Gamma,x:T_1 \vdash e_2 : T_2}
-%%             {\Gamma \vdash \LET{x}{e_1}{e_2} : T_2} 
-%%    \qquad
-%%   \inference{\Gamma(x) = T}
-%%             {\Gamma \vdash x : T}
-%% \end{equation*}
-%% Overall, the statement $\Gamma \vdash e : T$ is an example of what is
-%% called a \emph{judgment}.  In particular, this judgment says, ``In
-%% environment $\Gamma$, expression $e$ has type $T$.''
-%% Figure~\ref{fig:S1-type-system} shows the type checking rules for
-%% $R_2$.
-
-%% \begin{figure}
-%% \begin{gather*}
-%%   \inference{\Gamma(x) = T}
-%%             {\Gamma \vdash x : T}
-%%    \qquad
-%%   \inference{\Gamma \vdash e_1 : T_1 &
-%%              \Gamma,x:T_1 \vdash e_2 : T_2}
-%%             {\Gamma \vdash \LET{x}{e_1}{e_2} : T_2} 
-%%   \\[2ex]
-%%   \inference{}{\Gamma \vdash n : \key{Integer}}
-%%   \quad
-%%   \inference{\Gamma \vdash e_i : T_i \ ^{\forall i \in 1\ldots n} & \Delta(\Op,T_1,\ldots,T_n) = T}
-%%             {\Gamma \vdash (\Op \; e_1 \ldots e_n) : T}
-%%   \\[2ex]
-%%   \inference{}{\Gamma \vdash \key{\#t} : \key{Boolean}}
-%%   \quad
-%%   \inference{}{\Gamma \vdash \key{\#f} : \key{Boolean}}
-%%   \quad
-%%   \inference{\Gamma \vdash e_1 : \key{bool} \\
-%%              \Gamma \vdash e_2 : T &
-%%              \Gamma \vdash e_3 : T}
-%%   {\Gamma \vdash \IF{e_1}{e_2}{e_3} : T}
-%% \end{gather*}
-%% \caption{Type System for $R_2$.}
-%% \label{fig:S1-type-system}
-%% \end{figure}
-
-
-%% \begin{figure}
-
-%% \begin{align*}
-%% \Delta(\key{+},\key{Integer},\key{Integer}) &= \key{Integer} \\
-%% %\Delta(\key{-},\key{Integer},\key{Integer}) &= \key{Integer} \\
-%% \Delta(\key{-},\key{Integer}) &= \key{Integer} \\
-%% %\Delta(\key{*},\key{Integer},\key{Integer}) &= \key{Integer} \\
-%% \Delta(\key{read}) &= \key{Integer} \\
-%% \Delta(\key{and},\key{Boolean},\key{Boolean}) &= \key{Boolean} \\
-%% %\Delta(\key{or},\key{Boolean},\key{Boolean}) &= \key{Boolean} \\
-%% \Delta(\key{not},\key{Boolean}) &= \key{Boolean} \\
-%% \Delta(\key{eq?},\key{Integer},\key{Integer}) &= \key{Boolean} \\
-%% \Delta(\key{eq?},\key{Boolean},\key{Boolean}) &= \key{Boolean} 
-%% \end{align*}
-
-%% \caption{Types for the primitives operators.}
-%% \end{figure}
-
-
 \section{The $C_1$ Language}
 \label{sec:c1}
 
-\begin{figure}[htbp]
+The $R_2$ language adds Booleans and conditional expressions to $R_1$.
+As with $R_1$, we shall compile to a C-like intermediate language, but
+we need to grow that intermediate language to handle the new features
+in $R_2$. Figure~\ref{fig:c1-syntax} shows the new features of $C_1$;
+we add \key{\#t} and \key{\#f} to the $\Arg$ non-terminal and we add
+an \key{if} statement.
+
+\begin{figure}[tbp]
+\fbox{
+\begin{minipage}{0.96\textwidth}
 \[
 \begin{array}{lcl}
 \Arg &::=& \ldots \mid \key{\#t} \mid \key{\#f} \\
-\Stmt &::=& \ldots \mid \IF{\Exp}{\Stmt^{*}}{\Stmt^{*}} 
+\Stmt &::=& \ldots \mid \IF{\Exp}{\Stmt^{*}}{\Stmt^{*}} \\
+C_1 & ::= & (\key{program}\;(\Var^{*})\;\Stmt^{+})
 \end{array}
 \]
+\end{minipage}
+}
 \caption{The $C_1$ intermediate language, an extension of $C_0$
   (Figure~\ref{fig:c0-syntax}).}
 \label{fig:c1-syntax}
 \end{figure}
 
 \section{Flatten Expressions}
+\label{sec:flatten-r2}
+
+The \code{flatten} pass needs to be expanded to handle the Boolean
+literals \key{\#t} and \key{\#f} as well as the \key{if}
+expressions. We shall start with a simple example of translating a
+\key{if} expression, shown below on the left. \\
+\begin{tabular}{lll}
+\begin{minipage}{0.4\textwidth}
+\begin{lstlisting}
+ (program (if #f 0 42))
+\end{lstlisting}
+\end{minipage}
+&
+$\Rightarrow$
+&
+\begin{minipage}{0.4\textwidth}
+\begin{lstlisting}
+(program (if.1)
+  (if #f
+    ((assign if.1 0))
+    ((assign if.1 42)))
+  (return if.1))
+\end{lstlisting}
+\end{minipage}
+\end{tabular} \\
+The value of the \key{if} expression is the value of the branch that
+is selected. Recall that in the \code{flatten} pass we need to replace
+complex expressions with simple expressions (variables or
+literals). In the translation above, on the right, we have translated
+the \key{if} expression into a new variable \key{if.1} and we have
+produced code that will assign the appropriate value to \key{if.1}.
+For $R_1$, the \code{flatten} pass returned a list of assignment
+statements. Here, for $R_2$, we return a list of statements that can
+include both \key{if} statements and assignment statements.
+
+The next example is a bit more involved, showing what happens then
+there are complex expressions in the condition and branch expressions
+of an \key{if}, including nested \key{if} expressions.
+
+\begin{tabular}{lll}
+\begin{minipage}{0.4\textwidth}
+\begin{lstlisting}
+(program
+  (if (eq? (read) 0)
+      777
+      (+ 2 (if (eq? (read) 0)
+               40
+               444))))
+\end{lstlisting}
+\end{minipage}
+&
+$\Rightarrow$
+&
+\begin{minipage}{0.4\textwidth}
+\begin{lstlisting}
+(program (t.1 t.2 if.1 t.3 
+           t.4 if.2 t.5)
+  (assign t.1 (read))
+  (assign t.2 (eq? t.1 0))
+  (if t.2
+    ((assign if.1 777))
+    ((assign t.3 (read))
+     (assign t.4 (eq? t.3 0))
+     (if t.4
+       ((assign if.2 40))
+       ((assign if.2 444)))
+     (assign t.5 (+ 2 if.2))
+     (assign if.1 t.5)))
+  (return if.1))
+\end{lstlisting}
+\end{minipage}
+\end{tabular} \\
+
+\begin{exercise}\normalfont
+Expand your \code{flatten} pass to handle $R_2$, that is, handle the
+Boolean literals and the \key{if} expressions. Create 4 more test
+cases that expose whether your coe for flattening Booleans and
+\key{if} expressions is correct. Test your \code{flatten} pass by
+running the output programs with \code{interp-C}
+(Appendix~\ref{appendix:interp}).
+\end{exercise}
+
+
 
 \section{Select Instructions}