Selaa lähdekoodia

refactoring grammars

Jeremy Siek 3 vuotta sitten
vanhempi
commit
ed1673b7cd
2 muutettua tiedostoa jossa 308 lisäystä ja 177 poistoa
  1. 302 171
      book.tex
  2. 6 6
      defs.tex

+ 302 - 171
book.tex

@@ -882,14 +882,28 @@ defined in Figure~\ref{fig:r0-concrete-syntax}.
   converts the concrete syntax (represented as a string) into an
   abstract syntax tree.}
 
+\newcommand{\LintGrammar}{
+  \begin{array}{rcl}
+    \Exp{} &::=& \Int{} \MID \LP\key{read}\RP \MID \LP\key{-}\;\Exp\RP \MID \LP\key{+} \; \Exp{}\;\Exp{}\RP
+  \end{array}
+}
+\newcommand{\LintAST}{
+  \begin{array}{rcl}
+    \Exp{} &::=& \INT{\Int} \MID \READ{} \\
+           &\MID& \NEG{\Exp} \MID \ADD{\Exp}{\Exp}
+  \end{array}
+}
+
 \begin{figure}[tp]
 \fbox{
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 \[
-\begin{array}{rcl}
-  \Exp &::=& \Int \MID \LP\key{read}\RP \MID \LP\key{-}\;\Exp\RP \MID \LP\key{+} \; \Exp\;\Exp\RP\\
-  \LangInt{} &::=& \Exp
+\begin{array}{l}  
+  \LintGrammar \\
+  \begin{array}{rcl}
+    \LangInt{} &::=& \Exp
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -915,10 +929,11 @@ defined in Figure~\ref{fig:r0-concrete-syntax}.
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd
 \[
-\begin{array}{rcl}
-\Exp &::=& \INT{\Int} \MID \READ{} \MID \NEG{\Exp} \\
-     &\MID&  \ADD{\Exp}{\Exp}  \\
-\LangInt{}  &::=& \PROGRAM{\code{'()}}{\Exp}
+\begin{array}{l}
+  \LintAST{} \\
+  \begin{array}{rcl}
+    \LangInt{}  &::=& \PROGRAM{\code{'()}}{\Exp}
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -1687,16 +1702,29 @@ program.
 Despite the simplicity of the \LangVar{} language, it is rich enough to
 exhibit several compilation techniques.
 
+\newcommand{\LvarGrammar}{
+  \begin{array}{rcl}
+    \Exp &::=& \Var \MID \CLET{\Var}{\Exp}{\Exp}
+  \end{array}
+}
+\newcommand{\LvarAST}{
+  \begin{array}{rcl}
+    \Exp &::=& \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} 
+  \end{array}
+}
+    
 \begin{figure}[tp]
 \centering
 \fbox{
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd
 \[
-\begin{array}{rcl}
-  \Exp &::=& \Int{} \MID \CREAD{} \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp}\\
-       &\MID& \Var{} \MID \CLET{\Var}{\Exp}{\Exp} \\
-  \LangVarM{} &::=& \Exp
+\begin{array}{l}
+   \gray{\LintGrammar{}} \\
+   \LvarGrammar{}  \\
+  \begin{array}{rcl}
+    \LangVarM{} &::=& \Exp
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -1721,16 +1749,18 @@ exhibit several compilation techniques.
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd
 \[
-\begin{array}{rcl}
-\Exp &::=& \INT{\Int} \MID \READ{} \\
-     &\MID& \NEG{\Exp} \MID \ADD{\Exp}{\Exp}  \\
-     &\MID&  \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} \\
-\LangVarM{} &::=& \PROGRAM{\code{'()}}{\Exp}
+\begin{array}{l}
+  \gray{\LintAST{}} \\
+  \LvarAST \\
+  \begin{array}{rcl}
+    \LangVarM{} &::=& \PROGRAM{\code{'()}}{\Exp}
+  \end{array}
 \end{array}
 \]
 \fi}
 {\if\edition\pythonEd
 \[
+\begin{array}{l}
 \begin{array}{rcl}
 \Exp{} &::=& \INT{\Int} \MID \READ{} \\
        &\MID& \NEG{\Exp} \MID  \ADD{\Exp}{\Exp} \MID \VAR{\Var{}} \\
@@ -6435,22 +6465,46 @@ operators to include
   arguments. That responsibility is moved to the type checker for
   \LangIf{}, which we introduce in Section~\ref{sec:type-check-Lif}.}
 
+
+\newcommand{\LifGrammar}{
+  \begin{array}{lcl}
+    \itm{bool} &::=& \TRUE \MID \FALSE \\  
+    \itm{cmp} &::= & \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=} \\
+    \Exp &::=& \CSUB{\Exp}{\Exp} \MID \itm{bool}
+        \MID (\key{and}\;\Exp\;\Exp) \MID (\key{or}\;\Exp\;\Exp)
+        \MID (\key{not}\;\Exp) \\
+        &\MID& (\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} 
+  \end{array}
+}
+\newcommand{\LifAST}{
+\begin{array}{lcl}
+  \itm{bool} &::=& \code{\#t} \MID \code{\#f} \\
+  \itm{cmp} &::= & \code{eq?} \MID \code{<} \MID \code{<=} \MID \code{>} \MID \code{>=} \\
+  \itm{op} &::= & \itm{cmp} \MID \code{read} \MID \code{+} \MID \code{-}
+    \MID \code{and} \MID \code{or} \MID \code{not} \\
+  \Exp &::=& \PRIM{\itm{op}}{\Exp\ldots}
+       \MID \BOOL{\itm{bool}} \MID \IF{\Exp}{\Exp}{\Exp} \\
+\end{array}
+}
+\newcommand{\LintOnlyAST}{
+  \begin{array}{rcl}
+    \Exp{} &::=& \INT{\Int} 
+  \end{array}
+}
+
 \begin{figure}[tp]
 \centering
 \fbox{
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 \[
-\begin{array}{lcl}
-  \itm{bool} &::=& \TRUE \MID \FALSE \\  
-  \itm{cmp} &::= & \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=} \\
-  \Exp &::=& \gray{ \Int \MID \CREAD{} \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp} }  \MID \CSUB{\Exp}{\Exp} \\
-     &\MID&  \gray{ \Var \MID \CLET{\Var}{\Exp}{\Exp} } \\
-     &\MID& \itm{bool}
-      \MID (\key{and}\;\Exp\;\Exp) \MID (\key{or}\;\Exp\;\Exp)
-      \MID (\key{not}\;\Exp) \\
-      &\MID& (\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} \\
-  \LangIfM{} &::=& \Exp
+\begin{array}{l}
+  \LifGrammar{} \\
+  \gray{\LintGrammar{}} \\
+  \gray{\LvarGrammar{}} \\
+  \begin{array}{lcl}
+    \LangIfM{} &::=& \Exp
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -6480,15 +6534,13 @@ operators to include
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 \[
-\begin{array}{lcl}
-  \itm{bool} &::=& \code{\#t} \MID \code{\#f} \\
-  \itm{cmp} &::= & \code{eq?} \MID \code{<} \MID \code{<=} \MID \code{>} \MID \code{>=} \\
-  \itm{op} &::= & \itm{cmp} \MID \code{read} \MID \code{+} \MID \code{-}
-    \MID \code{and} \MID \code{or} \MID \code{not} \\
-  \Exp &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
-     &\MID& \PRIM{\itm{op}}{\Exp\ldots}\\
-     &\MID& \BOOL{\itm{bool}} \MID \IF{\Exp}{\Exp}{\Exp} \\
-  \LangIfM{} &::=& \PROGRAM{\code{'()}}{\Exp}
+\begin{array}{l}
+  \LifAST{} \\
+  \gray{\LintOnlyAST} \\
+  \gray{\LvarAST{}} \\
+  \begin{array}{lcl}
+    \LangIfM{} &::=& \PROGRAM{\code{'()}}{\Exp}
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -9401,6 +9453,20 @@ the condition remains true.
 
 \section{The \LangLoop{} Language}
 
+\newcommand{\LwhileGrammar}{
+  \begin{array}{lcl}
+   \Exp &::=& \CSETBANG{\Var}{\Exp}
+      \MID \CBEGIN{\Exp\ldots}{\Exp}
+      \MID \CWHILE{\Exp}{\Exp} \MID \LP\key{void}\RP 
+  \end{array}
+}
+\newcommand{\LwhileAST}{
+\begin{array}{lcl}
+  \Exp &::=& \SETBANG{\Var}{\Exp} \MID \BEGIN{\LP\Exp\ldots\RP}{\Exp}\\
+    &\MID& \WHILE{\Exp}{\Exp} \MID \VOID{}  
+\end{array}
+}
+
 \begin{figure}[tp]
 \centering
 \fbox{
@@ -9408,19 +9474,14 @@ the condition remains true.
     \small
 {\if\edition\racketEd    
 \[
-\begin{array}{lcl}
-  \Exp &::=& \gray{ \Int \MID \CREAD{} \MID \CNEG{\Exp}
-     \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} }  \\
-    &\MID&  \gray{ \Var \MID \CLET{\Var}{\Exp}{\Exp} }\\
-    &\MID& \gray{\itm{bool} 
-     \MID (\key{and}\;\Exp\;\Exp) 
-     \MID (\key{or}\;\Exp\;\Exp) 
-     \MID (\key{not}\;\Exp) } \\
-    &\MID& \gray{ (\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} } \\
-   &\MID& \CSETBANG{\Var}{\Exp}
-  \MID \CBEGIN{\Exp\ldots}{\Exp}
-  \MID \CWHILE{\Exp}{\Exp} \MID \LP\key{void}\RP \\
-  \LangLoopM{} &::=& \gray{\Exp}
+\begin{array}{l}
+  \gray{\LifGrammar{}} \\
+  \gray{\LintGrammar{}} \\
+  \gray{\LvarGrammar{}} \\
+  \LwhileGrammar \\
+  \begin{array}{lcl}
+  \LangLoopM{} &::=& \Exp
+\end{array}
 \end{array}
 \]
 \fi}
@@ -9451,16 +9512,22 @@ the condition remains true.
     \small
 {\if\edition\racketEd    
 \[
+\begin{array}{l}
+  \gray{\LifAST{}} \\
+  \gray{\LintOnlyAST} \\
+  \gray{\LvarAST{}} \\
+  \LwhileAST{} \\
 \begin{array}{lcl}
-  \Exp &::=& \gray{ \INT{\Int} \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
-       &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots} }\\
-     &\MID& \gray{ \BOOL{\itm{bool}}
-      \MID \IF{\Exp}{\Exp}{\Exp} } \\
-  &\MID& \SETBANG{\Var}{\Exp} \MID \BEGIN{\LP\Exp\ldots\RP}{\Exp}
-    \MID \WHILE{\Exp}{\Exp} \\
-    &\MID& \VOID{}  \\
+  %% \Exp &::=& \gray{ \INT{\Int} \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
+  %%      &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots} }\\
+  %%    &\MID& \gray{ \BOOL{\itm{bool}}
+  %%     \MID \IF{\Exp}{\Exp}{\Exp} } \\
+  %% &\MID& \SETBANG{\Var}{\Exp} \MID \BEGIN{\LP\Exp\ldots\RP}{\Exp}
+  %%   \MID \WHILE{\Exp}{\Exp} \\
+  %%   &\MID& \VOID{}  \\
   \LangLoopM{} &::=& \gray{ \PROGRAM{\code{'()}}{\Exp} }
 \end{array}
+\end{array}
 \]
 \fi}
 {\if\edition\pythonEd
@@ -10522,7 +10589,26 @@ print( t[0] + t[2][0] if t[1] else 44 )
 \end{lstlisting}
 \fi}
 
-
+\newcommand{\LtupGrammar}{
+\begin{array}{lcl}
+  \Type &::=& \key{Integer} \MID \key{Boolean} \MID \key{Void}
+   \MID \LP\key{Vector}\;\Type\ldots\RP \\
+  \Exp &::=& \LP\key{vector}\;\Exp\ldots\RP 
+   \MID \LP\key{vector-length}\;\Exp\RP \\
+  &\MID& \LP\key{vector-ref}\;\Exp\;\Int\RP
+   \MID \LP\key{vector-set!}\;\Exp\;\Int\;\Exp\RP 
+\end{array}
+}
+\newcommand{\LtupAST}{
+\begin{array}{lcl}
+ \Type &::=& \key{Integer} \MID \key{Boolean} \MID \key{Void}
+      \MID \LP\key{Vector}\;\Type\ldots\RP \\
+\itm{op} &::=& \code{vector} \MID \code{vector-length} \\
+\Exp &::=& \VECREF{\Exp}{\INT{\Int}} \\
+     &\MID& \VECSET{\Exp}{\INT{\Int}}{\Exp} \\
+     &\MID& \LP\key{HasType}~\Exp~\Type \RP 
+\end{array}
+}
 
 \begin{figure}[tbp]
 \centering
@@ -10530,26 +10616,33 @@ print( t[0] + t[2][0] if t[1] else 44 )
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 \[
-\begin{array}{lcl}
-  \Type &::=& \gray{\key{Integer} \MID \key{Boolean}}
-  \MID \LP\key{Vector}\;\Type\ldots\RP \MID \key{Void}\\
-  \Exp &::=& \gray{  \Int \MID \CREAD{} \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} }  \\
-  &\MID&  \gray{  \Var \MID \CLET{\Var}{\Exp}{\Exp}  }\\
-  &\MID& \gray{ \key{\#t} \MID \key{\#f} 
-   \MID \LP\key{and}\;\Exp\;\Exp\RP 
-   \MID \LP\key{or}\;\Exp\;\Exp\RP
-   \MID \LP\key{not}\;\Exp\RP } \\
-  &\MID& \gray{  \LP\itm{cmp}\;\Exp\;\Exp\RP 
-   \MID \CIF{\Exp}{\Exp}{\Exp}  } \\
-   &\MID& \gray{ \CSETBANG{\Var}{\Exp}
-    \MID \CBEGIN{\Exp\ldots}{\Exp}
-    \MID \CWHILE{\Exp}{\Exp} \MID \LP\key{void}\RP } \\
-  &\MID& \LP\key{vector}\;\Exp\ldots\RP 
-   \MID \LP\key{vector-length}\;\Exp\RP \\
-  &\MID& \LP\key{vector-ref}\;\Exp\;\Int\RP
-   \MID \LP\key{vector-set!}\;\Exp\;\Int\;\Exp\RP \\
-  &\MID& \LP\key{has-type}~\Exp~\Type\RP\\
-  \LangVecM{} &::=& \Exp
+\begin{array}{l}
+  \gray{\LifGrammar{}} \\
+  \gray{\LintGrammar{}} \\
+  \gray{\LvarGrammar{}} \\
+  \gray{\LwhileGrammar} \\
+  \LtupGrammar \\  
+  \begin{array}{lcl}
+  %% \Type &::=& \gray{\key{Integer} \MID \key{Boolean}}
+  %% \MID \LP\key{Vector}\;\Type\ldots\RP \MID \key{Void}\\
+  %% \Exp &::=& \gray{  \Int \MID \CREAD{} \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} }  \\
+  %% &\MID&  \gray{  \Var \MID \CLET{\Var}{\Exp}{\Exp}  }\\
+  %% &\MID& \gray{ \key{\#t} \MID \key{\#f} 
+  %%  \MID \LP\key{and}\;\Exp\;\Exp\RP 
+  %%  \MID \LP\key{or}\;\Exp\;\Exp\RP
+  %%  \MID \LP\key{not}\;\Exp\RP } \\
+  %% &\MID& \gray{  \LP\itm{cmp}\;\Exp\;\Exp\RP 
+  %%  \MID \CIF{\Exp}{\Exp}{\Exp}  } \\
+  %%  &\MID& \gray{ \CSETBANG{\Var}{\Exp}
+  %%   \MID \CBEGIN{\Exp\ldots}{\Exp}
+  %%   \MID \CWHILE{\Exp}{\Exp} \MID \LP\key{void}\RP } \\
+  %% &\MID& \LP\key{vector}\;\Exp\ldots\RP 
+  %%  \MID \LP\key{vector-length}\;\Exp\RP \\
+  %% &\MID& \LP\key{vector-ref}\;\Exp\;\Int\RP
+  %%  \MID \LP\key{vector-set!}\;\Exp\;\Int\;\Exp\RP \\
+  %% &\MID& \LP\key{has-type}~\Exp~\Type\RP\\
+    \LangVecM{} &::=& \Exp
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -10581,17 +10674,23 @@ print( t[0] + t[2][0] if t[1] else 44 )
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 \[
+\begin{array}{l}
+  \gray{\LifAST{}} \\
+  \gray{\LintOnlyAST} \\
+  \gray{\LvarAST{}} \\
+  \gray{\LwhileAST{}} \\
+  \LtupAST{} \\
 \begin{array}{lcl}
-  \itm{op} &::=& \ldots \MID \code{vector} \MID \code{vector-length} \\
-\Exp &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
-     &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots}
-      \MID \BOOL{\itm{bool}}
-      \MID \IF{\Exp}{\Exp}{\Exp} } \\
-    &\MID& \VECREF{\Exp}{\INT{\Int}}\\
-    &\MID& \VECSET{\Exp}{\INT{\Int}}{\Exp} \\
-     &\MID& \LP\key{HasType}~\Exp~\Type \RP \\
+%% \Exp &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
+%%      &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots}
+%%       \MID \BOOL{\itm{bool}}
+%%       \MID \IF{\Exp}{\Exp}{\Exp} } \\
+%%     &\MID& \VECREF{\Exp}{\INT{\Int}}\\
+%%     &\MID& \VECSET{\Exp}{\INT{\Int}}{\Exp} \\
+%%      &\MID& \LP\key{HasType}~\Exp~\Type \RP \\
   \LangVecM{} &::=& \PROGRAM{\key{'()}}{\Exp}
 \end{array}
+\end{array}
 \]
 \fi}
 {\if\edition\pythonEd
@@ -12579,30 +12678,53 @@ referenced from inside a function body are other globally-defined
 functions. The syntax of \LangFun{} prevents functions from being nested
 inside each other.
 
+\newcommand{\LfunGrammar}{
+  \begin{array}{lcl}
+   \Type &::=& (\Type \ldots \; \key{->}\; \Type) \\
+   \Exp &::=& \LP\Exp \; \Exp \ldots\RP \\
+   \Def &::=& \CDEF{\Var}{\LS\Var \key{:} \Type\RS \ldots}{\Type}{\Exp} \\
+  \end{array}
+}
+\newcommand{\LfunAST}{
+  \begin{array}{lcl}
+  \Type &::=& (\Type \ldots \; \key{->}\; \Type) \\
+  \Exp &::=& \APPLY{\Exp}{\Exp\ldots}\\
+  \Def &::=& \FUNDEF{\Var}{\LP[\Var \code{:} \Type]\ldots\RP}{\Type}{\code{'()}}{\Exp}
+  \end{array}
+}
+
 \begin{figure}[tp]
 \centering
 \fbox{
   \begin{minipage}{0.96\textwidth}
     \small
 \[
-\begin{array}{lcl}
-  \Type &::=& \gray{ \key{Integer} \MID \key{Boolean}
-         \MID (\key{Vector}\;\Type\ldots) \MID \key{Void}  } \MID (\Type \ldots \; \key{->}\; \Type) \\
-\itm{cmp} &::= & \gray{  \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=}  } \\
-  \Exp &::=& \gray{ \Int \MID \CREAD{} \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} } \\
-    &\MID&  \gray{ \Var \MID \CLET{\Var}{\Exp}{\Exp} }\\
-    &\MID& \gray{ \key{\#t} \MID \key{\#f} 
-    \MID (\key{and}\;\Exp\;\Exp)
-    \MID (\key{or}\;\Exp\;\Exp)
-    \MID (\key{not}\;\Exp)} \\
-   &\MID& \gray{(\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} } \\
-  &\MID& \gray{(\key{vector}\;\Exp\ldots) \MID
-    (\key{vector-ref}\;\Exp\;\Int)} \\
-  &\MID& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\MID (\key{void})
-      \MID \LP\key{has-type}~\Exp~\Type\RP } \\
-  &\MID& \LP\Exp \; \Exp \ldots\RP \\
-  \Def &::=& \CDEF{\Var}{\LS\Var \key{:} \Type\RS \ldots}{\Type}{\Exp} \\
+\begin{array}{l}
+  \gray{\LifGrammar{}} \\
+  \gray{\LintGrammar{}} \\
+  \gray{\LvarGrammar{}} \\
+  \gray{\LwhileGrammar} \\
+  \gray{\LtupGrammar} \\  
+  \LfunGrammar \\  
+  \begin{array}{lcl}
+%%   \Type &::=& \gray{ \key{Integer} \MID \key{Boolean}
+%%          \MID (\key{Vector}\;\Type\ldots) \MID \key{Void}  } \MID (\Type \ldots \; \key{->}\; \Type) \\
+%% \itm{cmp} &::= & \gray{  \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=}  } \\
+%%   \Exp &::=& \gray{ \Int \MID \CREAD{} \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp} } \\
+%%     &\MID&  \gray{ \Var \MID \CLET{\Var}{\Exp}{\Exp} }\\
+%%     &\MID& \gray{ \key{\#t} \MID \key{\#f} 
+%%     \MID (\key{and}\;\Exp\;\Exp)
+%%     \MID (\key{or}\;\Exp\;\Exp)
+%%     \MID (\key{not}\;\Exp)} \\
+%%    &\MID& \gray{(\itm{cmp}\;\Exp\;\Exp) \MID \CIF{\Exp}{\Exp}{\Exp} } \\
+%%   &\MID& \gray{(\key{vector}\;\Exp\ldots) \MID
+%%     (\key{vector-ref}\;\Exp\;\Int)} \\
+%%   &\MID& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\MID (\key{void})
+%%       \MID \LP\key{has-type}~\Exp~\Type\RP } \\
+%%   &\MID& \LP\Exp \; \Exp \ldots\RP \\
+%%   \Def &::=& \CDEF{\Var}{\LS\Var \key{:} \Type\RS \ldots}{\Type}{\Exp} \\
   \LangFunM{} &::=& \Def \ldots \; \Exp
+  \end{array}
 \end{array}
 \]
 \end{minipage}
@@ -12617,15 +12739,23 @@ inside each other.
   \begin{minipage}{0.96\textwidth}
     \small
 \[
-\begin{array}{lcl}
-\Exp &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
-     &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots} }\\
-     &\MID& \gray{ \BOOL{\itm{bool}} 
-      \MID \IF{\Exp}{\Exp}{\Exp} } \\
-     &\MID& \gray{ \VOID{} \MID \LP\key{HasType}~\Exp~\Type \RP } 
-     \MID \APPLY{\Exp}{\Exp\ldots}\\
- \Def &::=& \FUNDEF{\Var}{\LP[\Var \code{:} \Type]\ldots\RP}{\Type}{\code{'()}}{\Exp}\\
+\begin{array}{l}
+  \gray{\LifAST{}} \\
+  \gray{\LintOnlyAST} \\
+  \gray{\LvarAST{}} \\
+  \gray{\LwhileAST{}} \\
+  \gray{\LtupAST{}} \\
+  \LfunAST \\
+  \begin{array}{lcl}
+%% \Exp &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} } \\
+%%      &\MID& \gray{ \PRIM{\itm{op}}{\Exp\ldots} }\\
+%%      &\MID& \gray{ \BOOL{\itm{bool}} 
+%%       \MID \IF{\Exp}{\Exp}{\Exp} } \\
+%%      &\MID& \gray{ \VOID{} \MID \LP\key{HasType}~\Exp~\Type \RP } 
+%%      \MID \APPLY{\Exp}{\Exp\ldots}\\
+%%  \Def &::=& \FUNDEF{\Var}{\LP[\Var \code{:} \Type]\ldots\RP}{\Type}{\code{'()}}{\Exp}\\
   \LangFunM{} &::=& \PROGRAMDEFSEXP{\code{'()}}{\LP\Def\ldots\RP)}{\Exp}
+  \end{array}
 \end{array}
 \]
 \end{minipage}
@@ -12817,13 +12947,14 @@ and where the \code{rip} would be at that moment and then changes
 \code{add1(\%rip)} to \code{$d$(\%rip)}, which at runtime will compute
 the address of \code{add1}.
 
-In Section~\ref{sec:x86} we used of the \code{callq} instruction to
-jump to a function whose location is given by a label. To support
-function calls in this chapter we instead will be jumping to a
-function whose location is given by an address in a register, that is,
-we need to make an \emph{indirect function call}. The x86 syntax for
-this is a \code{callq} instruction but with an asterisk before the
-register name.\index{subject}{indirect function call}
+In Section~\ref{sec:x86} we used the \code{callq} instruction to jump
+to functions whose locations were given by a label, such as
+\code{read\_int}. To support function calls in this chapter we instead
+will be jumping to functions whose location are given by an address in
+a register, that is, we need to make an \emph{indirect function
+call}. The x86 syntax for this is a \code{callq} instruction but with
+an asterisk before the register name.\index{subject}{indirect function
+  call}
 \begin{lstlisting}
    callq *%rbx
 \end{lstlisting}
@@ -12860,16 +12991,16 @@ the function.
 
 \index{subject}{prelude}\index{subject}{conclusion}
 
-Regarding (2) frames \index{subject}{frame} and the procedure call stack,
-\index{subject}{procedure call stack} recall from Section~\ref{sec:x86} that
-the stack grows down, with each function call using a chunk of space
-called a frame. The caller sets the stack pointer, register
-\code{rsp}, to the last data item in its frame. The callee must not
-change anything in the caller's frame, that is, anything that is at or
-above the stack pointer. The callee is free to use locations that are
-below the stack pointer.
+Regarding (2) frames \index{subject}{frame} and the procedure call
+stack, \index{subject}{procedure call stack} recall from
+Section~\ref{sec:x86} that the stack grows down and each function call
+uses a chunk of space on the stack called a frame. The caller sets the
+stack pointer, register \code{rsp}, to the last data item in its
+frame. The callee must not change anything in the caller's frame, that
+is, anything that is at or above the stack pointer. The callee is free
+to use locations that are below the stack pointer.
 
-Recall that we are storing variables of vector type on the root stack.
+Recall that we are storing variables of tuple type on the root stack.
 So the prelude needs to move the root stack pointer \code{r15} up and
 the conclusion needs to move the root stack pointer back down.  Also,
 the prelude must initialize to \code{0} this frame's slots in the root
@@ -12897,7 +13028,7 @@ then the prelude of the \code{main} function must save that register
 to the stack and the conclusion of \code{main} must restore it.  This
 recommendation now generalizes to all functions.
 
-Also recall that the base pointer, register \code{rbp}, is used as a
+Recall that the base pointer, register \code{rbp}, is used as a
 point-of-reference within a frame, so that each local variable can be
 accessed at a fixed offset from the base pointer
 (Section~\ref{sec:x86}).
@@ -12970,44 +13101,44 @@ $-8(j+k)$(\key{\%rbp}) &  & local variable $k$ \\
 In general, the amount of stack space used by a program is determined
 by the longest chain of nested function calls. That is, if function
 $f_1$ calls $f_2$, $f_2$ calls $f_3$, $\ldots$, and $f_{n-1}$ calls
-$f_n$, then the amount of stack space is bounded by $O(n)$.  The depth
-$n$ can grow quite large in the case of recursive or mutually
-recursive functions. However, in some cases we can arrange to use only
-constant space, i.e. $O(1)$, instead of $O(n)$.
+$f_n$, then the amount of stack space is linear in $n$.  The depth $n$
+can grow quite large in the case of recursive or mutually recursive
+functions. However, in some cases we can arrange to use only a
+constant amount of space for a long chain of nested function calls.
 
 If a function call is the last action in a function body, then that
 call is said to be a \emph{tail call}\index{subject}{tail call}.
 For example, in the following
-program, the recursive call to \code{tail-sum} is a tail call.
+program, the recursive call to \code{tail\_sum} is a tail call.
 \begin{center}
 \begin{lstlisting}
-(define (tail-sum [n : Integer] [r : Integer]) : Integer
+(define (tail_sum [n : Integer] [r : Integer]) : Integer
   (if (eq? n 0) 
       r
-      (tail-sum (- n 1) (+ n r))))
+      (tail_sum (- n 1) (+ n r))))
 
-(+ (tail-sum 5 0) 27)
+(+ (tail_sum 5 0) 27)
 \end{lstlisting}
 \end{center}
-At a tail call, the frame of the caller is no longer needed, so we
-can pop the caller's frame before making the tail call. With this
+At a tail call, the frame of the caller is no longer needed, so we can
+pop the caller's frame before making the tail call. With this
 approach, a recursive function that only makes tail calls will only
-use $O(1)$ stack space.  Functional languages like Racket typically
-rely heavily on recursive functions, so they typically guarantee that
-all tail calls will be optimized in this way.
+use a constant amount of stack space.  Functional languages like
+Racket typically rely heavily on recursive functions, so they
+typically guarantee that all tail calls will be optimized in this way.
 \index{subject}{frame}
 
-However, some care is needed with regards to argument passing in tail
-calls.  As mentioned above, for arguments beyond the sixth, the
-convention is to use space in the caller's frame for passing
-arguments.  But for a tail call we pop the caller's frame and can no
-longer use it.  Another alternative is to use space in the callee's
-frame for passing arguments. However, this option is also problematic
-because the caller and callee's frame overlap in memory.  As we begin
-to copy the arguments from their sources in the caller's frame, the
-target locations in the callee's frame might overlap with the sources
-for later arguments! We solve this problem by using the heap instead
-of the stack for passing more than six arguments, as we describe in
+Some care is needed with regards to argument passing in tail calls.
+As mentioned above, for arguments beyond the sixth, the convention is
+to use space in the caller's frame for passing arguments.  But for a
+tail call we pop the caller's frame and can no longer use it.  An
+alternative is to use space in the callee's frame for passing
+arguments. However, this option is also problematic because the caller
+and callee's frames overlap in memory.  As we begin to copy the
+arguments from their sources in the caller's frame, the target
+locations in the callee's frame might collide with the sources for
+later arguments! We solve this problem by using the heap instead of
+the stack for passing more than six arguments, which we describe in
 the Section~\ref{sec:limit-functions-r4}.
 
 As mentioned above, for a tail call we pop the caller's frame prior to
@@ -13015,8 +13146,8 @@ making the tail call. The instructions for popping a frame are the
 instructions that we usually place in the conclusion of a
 function. Thus, we also need to place such code immediately before
 each tail call. These instructions include restoring the callee-saved
-registers, so it is good that the argument passing registers are all
-caller-saved registers.
+registers, so it is fortunate that the argument passing registers are
+all caller-saved registers!
 
 One last note regarding which instruction to use to make the tail
 call. When the callee is finished, it should not return to the current
@@ -13025,10 +13156,10 @@ one. Thus, the return address that is already on the stack is the
 right one, and we should not use \key{callq} to make the tail call, as
 that would unnecessarily overwrite the return address. Instead we can
 simply use the \key{jmp} instruction. Like the indirect function call,
-we write an \emph{indirect jump}\index{subject}{indirect jump} with a register
-prefixed with an asterisk.  We recommend using \code{rax} to hold the
-jump target because the preceding conclusion overwrites just about
-everything else.
+we write an \emph{indirect jump}\index{subject}{indirect jump} with a
+register prefixed with an asterisk.  We recommend using \code{rax} to
+hold the jump target because the preceding conclusion can overwrite
+just about everything else.
 \begin{lstlisting}
    jmp *%rax
 \end{lstlisting}
@@ -13060,7 +13191,7 @@ function name differently than the use of a local variable; we need to
 use \code{leaq} to convert the function name (a label in x86) to an
 address in a register.  Thus, it is a good idea to create a new pass
 that changes function references from just a symbol $f$ to
-$\FUNREF{f}$. This pass is named \code{reveal-functions} and the
+$\FUNREF{f}$. This pass is named \code{reveal\_functions} and the
 output language, \LangFunRef{}, is defined in Figure~\ref{fig:f1-syntax}.
 The concrete syntax for a function reference is $\CFUNREF{f}$.
 
@@ -13089,9 +13220,9 @@ The concrete syntax for a function reference is $\CFUNREF{f}$.
 
 Placing this pass after \code{uniquify} will make sure that there are
 no local variables and functions that share the same name. On the
-other hand, \code{reveal-functions} needs to come before the
-\code{explicate\_control} pass because that pass helps us compile
-\code{FunRef} forms into assignment statements.
+other hand, \code{reveal\_functions} needs to come before the
+\code{remove\_complex\_operands} pass because function references
+should be categorized as complex expressions.
 
 \section{Limit Functions}
 \label{sec:limit-functions-r4}
@@ -14087,7 +14218,7 @@ that we box those variables that are both assigned-to and that appear
 free inside a \code{lambda}. The purpose of the
 \code{convert-assignments} pass is to carry out that transformation.
 We recommend placing this pass after \code{uniquify} but before
-\code{reveal-functions}.
+\code{reveal\_functions}.
 
 Consider again the first example from
 Section~\ref{sec:assignment-scoping}:
@@ -14244,7 +14375,7 @@ function \code{f}.
 
 The compiling of lexically-scoped functions into top-level function
 definitions is accomplished in the pass \code{convert-to-closures}
-that comes after \code{reveal-functions} and before
+that comes after \code{reveal\_functions} and before
 \code{limit-functions}. 
 
 As usual, we implement the pass as a recursive function over the
@@ -14342,7 +14473,7 @@ an extra closure parameter.
 \label{sec:example-lambda}
 
 Figure~\ref{fig:lexical-functions-example} shows the result of
-\code{reveal-functions} and \code{convert-to-closures} for the example
+\code{reveal\_functions} and \code{convert-to-closures} for the example
 program demonstrating lexical scoping that we discussed at the
 beginning of this chapter.
 
@@ -14523,19 +14654,19 @@ for the compilation of \LangLam{}.
 In this chapter we compiled lexically-scoped functions into a
 relatively efficient representation: flat closures. However, even this
 representation comes with some overhead. For example, consider the
-following program with a function \code{tail-sum} that does not have
-any free variables and where all the uses of \code{tail-sum} are in
-applications where we know that only \code{tail-sum} is being applied
+following program with a function \code{tail\_sum} that does not have
+any free variables and where all the uses of \code{tail\_sum} are in
+applications where we know that only \code{tail\_sum} is being applied
 (and not any other functions).
 \begin{center}
 \begin{minipage}{0.95\textwidth}
 \begin{lstlisting}
-(define (tail-sum [n : Integer] [r : Integer]) : Integer
+(define (tail_sum [n : Integer] [r : Integer]) : Integer
   (if (eq? n 0)
       r
-      (tail-sum (- n 1) (+ n r))))
+      (tail_sum (- n 1) (+ n r))))
 
-(+ (tail-sum 5 0) 27)
+(+ (tail_sum 5 0) 27)
 \end{lstlisting}
 \end{minipage}
 \end{center}
@@ -14558,9 +14689,9 @@ all functions, obtaining the following output for this program.
 \end{center}
 
 In the previous Chapter, there would be no allocation in the program
-and the calls to \code{tail-sum} would be direct calls. In contrast,
+and the calls to \code{tail\_sum} would be direct calls. In contrast,
 the above program allocates memory for each \code{closure} and the
-calls to \code{tail-sum} are indirect. These two differences incur
+calls to \code{tail\_sum} are indirect. These two differences incur
 considerable overhead in a program such as this one, where the
 allocations and indirect calls occur inside a tight loop.
 

+ 6 - 6
defs.tex

@@ -228,12 +228,12 @@
 \newcommand{\NOT}[1]{\key{(Prim}~\code{not}~\code{(}#1~\code{))}}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
 \newcommand{\VECTOR}[1]{\LP\key{Prim}~\code{vector}~\LP~#1\RP\RP}
-\newcommand{\VECREF}[2]{\LP\key{Prim}~\code{vector-ref}~\LP~#1~#2\RP\RP}
-\newcommand{\VECSET}[3]{\LP\key{Prim}~\code{vector-set!}~\LP~#1~#2~#3\RP\RP}
-\newcommand{\VECLEN}[1]{\LP\key{Prim}~\code{vector-length}~\LP~#1\RP\RP}
-\newcommand{\ANYVECREF}[2]{\LP\key{Prim}~\code{any-vector-ref}~\LP~#1~#2\RP\RP}
-\newcommand{\ANYVECSET}[3]{\LP\key{Prim}~\code{any-vector-set!}~\LP~#1~#2~#3\RP\RP}
-\newcommand{\ANYVECLEN}[1]{\LP\key{Prim}~\code{any-vector-length}~\LP~#1\RP\RP}
+\newcommand{\VECREF}[2]{\LP\key{Prim}~\code{vector-ref}~\LP #1~#2\RP\RP}
+\newcommand{\VECSET}[3]{\LP\key{Prim}~\code{vector-set!}~\LP #1~#2~#3\RP\RP}
+\newcommand{\VECLEN}[1]{\LP\key{Prim}~\code{vector-length}~\LP #1\RP\RP}
+\newcommand{\ANYVECREF}[2]{\LP\key{Prim}~\code{any-vector-ref}~\LP #1~#2\RP\RP}
+\newcommand{\ANYVECSET}[3]{\LP\key{Prim}~\code{any-vector-set!}~\LP #1~#2~#3\RP\RP}
+\newcommand{\ANYVECLEN}[1]{\LP\key{Prim}~\code{any-vector-length}~\LP #1\RP\RP}
 \newcommand{\CLOSURE}[2]{\LP\key{Closure}~#1~#2\RP}
 \newcommand{\ALLOC}[2]{\LP\key{Allocate}~#1~#2\RP}
 \newcommand{\ALLOCCLOS}[3]{\LP\key{AllocateClosure}~#1~#2~#3\RP}