瀏覽代碼

refactoring grammars

Jeremy Siek 3 年之前
父節點
當前提交
ed1673b7cd
共有 2 個文件被更改,包括 308 次插入177 次删除
  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
   converts the concrete syntax (represented as a string) into an
   abstract syntax tree.}
   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]
 \begin{figure}[tp]
 \fbox{
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -915,10 +929,11 @@ defined in Figure~\ref{fig:r0-concrete-syntax}.
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -1687,16 +1702,29 @@ program.
 Despite the simplicity of the \LangVar{} language, it is rich enough to
 Despite the simplicity of the \LangVar{} language, it is rich enough to
 exhibit several compilation techniques.
 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]
 \begin{figure}[tp]
 \centering
 \centering
 \fbox{
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -1721,16 +1749,18 @@ exhibit several compilation techniques.
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
 {\if\edition\pythonEd
 {\if\edition\pythonEd
 \[
 \[
+\begin{array}{l}
 \begin{array}{rcl}
 \begin{array}{rcl}
 \Exp{} &::=& \INT{\Int} \MID \READ{} \\
 \Exp{} &::=& \INT{\Int} \MID \READ{} \\
        &\MID& \NEG{\Exp} \MID  \ADD{\Exp}{\Exp} \MID \VAR{\Var{}} \\
        &\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
   arguments. That responsibility is moved to the type checker for
   \LangIf{}, which we introduce in Section~\ref{sec:type-check-Lif}.}
   \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]
 \begin{figure}[tp]
 \centering
 \centering
 \fbox{
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -6480,15 +6534,13 @@ operators to include
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -9401,6 +9453,20 @@ the condition remains true.
 
 
 \section{The \LangLoop{} Language}
 \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]
 \begin{figure}[tp]
 \centering
 \centering
 \fbox{
 \fbox{
@@ -9408,19 +9474,14 @@ the condition remains true.
     \small
     \small
 {\if\edition\racketEd    
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -9451,16 +9512,22 @@ the condition remains true.
     \small
     \small
 {\if\edition\racketEd    
 {\if\edition\racketEd    
 \[
 \[
+\begin{array}{l}
+  \gray{\LifAST{}} \\
+  \gray{\LintOnlyAST} \\
+  \gray{\LvarAST{}} \\
+  \LwhileAST{} \\
 \begin{array}{lcl}
 \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} }
   \LangLoopM{} &::=& \gray{ \PROGRAM{\code{'()}}{\Exp} }
 \end{array}
 \end{array}
+\end{array}
 \]
 \]
 \fi}
 \fi}
 {\if\edition\pythonEd
 {\if\edition\pythonEd
@@ -10522,7 +10589,26 @@ print( t[0] + t[2][0] if t[1] else 44 )
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \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]
 \begin{figure}[tbp]
 \centering
 \centering
@@ -10530,26 +10616,33 @@ print( t[0] + t[2][0] if t[1] else 44 )
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 {\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}
 \end{array}
 \]
 \]
 \fi}
 \fi}
@@ -10581,17 +10674,23 @@ print( t[0] + t[2][0] if t[1] else 44 )
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd    
 {\if\edition\racketEd    
 \[
 \[
+\begin{array}{l}
+  \gray{\LifAST{}} \\
+  \gray{\LintOnlyAST} \\
+  \gray{\LvarAST{}} \\
+  \gray{\LwhileAST{}} \\
+  \LtupAST{} \\
 \begin{array}{lcl}
 \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}
   \LangVecM{} &::=& \PROGRAM{\key{'()}}{\Exp}
 \end{array}
 \end{array}
+\end{array}
 \]
 \]
 \fi}
 \fi}
 {\if\edition\pythonEd
 {\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
 functions. The syntax of \LangFun{} prevents functions from being nested
 inside each other.
 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]
 \begin{figure}[tp]
 \centering
 \centering
 \fbox{
 \fbox{
   \begin{minipage}{0.96\textwidth}
   \begin{minipage}{0.96\textwidth}
     \small
     \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
   \LangFunM{} &::=& \Def \ldots \; \Exp
+  \end{array}
 \end{array}
 \end{array}
 \]
 \]
 \end{minipage}
 \end{minipage}
@@ -12617,15 +12739,23 @@ inside each other.
   \begin{minipage}{0.96\textwidth}
   \begin{minipage}{0.96\textwidth}
     \small
     \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}
   \LangFunM{} &::=& \PROGRAMDEFSEXP{\code{'()}}{\LP\Def\ldots\RP)}{\Exp}
+  \end{array}
 \end{array}
 \end{array}
 \]
 \]
 \end{minipage}
 \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
 \code{add1(\%rip)} to \code{$d$(\%rip)}, which at runtime will compute
 the address of \code{add1}.
 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}
 \begin{lstlisting}
    callq *%rbx
    callq *%rbx
 \end{lstlisting}
 \end{lstlisting}
@@ -12860,16 +12991,16 @@ the function.
 
 
 \index{subject}{prelude}\index{subject}{conclusion}
 \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
 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 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
 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
 to the stack and the conclusion of \code{main} must restore it.  This
 recommendation now generalizes to all functions.
 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
 point-of-reference within a frame, so that each local variable can be
 accessed at a fixed offset from the base pointer
 accessed at a fixed offset from the base pointer
 (Section~\ref{sec:x86}).
 (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
 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
 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_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
 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}.
 call is said to be a \emph{tail call}\index{subject}{tail call}.
 For example, in the following
 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{center}
 \begin{lstlisting}
 \begin{lstlisting}
-(define (tail-sum [n : Integer] [r : Integer]) : Integer
+(define (tail_sum [n : Integer] [r : Integer]) : Integer
   (if (eq? n 0) 
   (if (eq? n 0) 
       r
       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{lstlisting}
 \end{center}
 \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
 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}
 \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}.
 the Section~\ref{sec:limit-functions-r4}.
 
 
 As mentioned above, for a tail call we pop the caller's frame prior to
 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
 instructions that we usually place in the conclusion of a
 function. Thus, we also need to place such code immediately before
 function. Thus, we also need to place such code immediately before
 each tail call. These instructions include restoring the callee-saved
 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
 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
 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
 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
 that would unnecessarily overwrite the return address. Instead we can
 simply use the \key{jmp} instruction. Like the indirect function call,
 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}
 \begin{lstlisting}
    jmp *%rax
    jmp *%rax
 \end{lstlisting}
 \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
 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
 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
 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}.
 output language, \LangFunRef{}, is defined in Figure~\ref{fig:f1-syntax}.
 The concrete syntax for a function reference is $\CFUNREF{f}$.
 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
 Placing this pass after \code{uniquify} will make sure that there are
 no local variables and functions that share the same name. On the
 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}
 \section{Limit Functions}
 \label{sec:limit-functions-r4}
 \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
 free inside a \code{lambda}. The purpose of the
 \code{convert-assignments} pass is to carry out that transformation.
 \code{convert-assignments} pass is to carry out that transformation.
 We recommend placing this pass after \code{uniquify} but before
 We recommend placing this pass after \code{uniquify} but before
-\code{reveal-functions}.
+\code{reveal\_functions}.
 
 
 Consider again the first example from
 Consider again the first example from
 Section~\ref{sec:assignment-scoping}:
 Section~\ref{sec:assignment-scoping}:
@@ -14244,7 +14375,7 @@ function \code{f}.
 
 
 The compiling of lexically-scoped functions into top-level function
 The compiling of lexically-scoped functions into top-level function
 definitions is accomplished in the pass \code{convert-to-closures}
 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}. 
 \code{limit-functions}. 
 
 
 As usual, we implement the pass as a recursive function over the
 As usual, we implement the pass as a recursive function over the
@@ -14342,7 +14473,7 @@ an extra closure parameter.
 \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
-\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
 program demonstrating lexical scoping that we discussed at the
 beginning of this chapter.
 beginning of this chapter.
 
 
@@ -14523,19 +14654,19 @@ for the compilation of \LangLam{}.
 In this chapter we compiled lexically-scoped functions into a
 In this chapter we compiled lexically-scoped functions into a
 relatively efficient representation: flat closures. However, even this
 relatively efficient representation: flat closures. However, even this
 representation comes with some overhead. For example, consider the
 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).
 (and not any other functions).
 \begin{center}
 \begin{center}
 \begin{minipage}{0.95\textwidth}
 \begin{minipage}{0.95\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
-(define (tail-sum [n : Integer] [r : Integer]) : Integer
+(define (tail_sum [n : Integer] [r : Integer]) : Integer
   (if (eq? n 0)
   (if (eq? n 0)
       r
       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{lstlisting}
 \end{minipage}
 \end{minipage}
 \end{center}
 \end{center}
@@ -14558,9 +14689,9 @@ all functions, obtaining the following output for this program.
 \end{center}
 \end{center}
 
 
 In the previous Chapter, there would be no allocation in the program
 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
 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
 considerable overhead in a program such as this one, where the
 allocations and indirect calls occur inside a tight loop.
 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{\NOT}[1]{\key{(Prim}~\code{not}~\code{(}#1~\code{))}}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
 \newcommand{\VECTOR}[1]{\LP\key{Prim}~\code{vector}~\LP~#1\RP\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{\CLOSURE}[2]{\LP\key{Closure}~#1~#2\RP}
 \newcommand{\ALLOC}[2]{\LP\key{Allocate}~#1~#2\RP}
 \newcommand{\ALLOC}[2]{\LP\key{Allocate}~#1~#2\RP}
 \newcommand{\ALLOCCLOS}[3]{\LP\key{AllocateClosure}~#1~#2~#3\RP}
 \newcommand{\ALLOCCLOS}[3]{\LP\key{AllocateClosure}~#1~#2~#3\RP}