Prechádzať zdrojové kódy

first draft of functions

Jeremy Siek 3 rokov pred
rodič
commit
3ec8d99d9a
2 zmenil súbory, kde vykonal 282 pridanie a 90 odobranie
  1. 269 85
      book.tex
  2. 13 5
      defs.tex

+ 269 - 85
book.tex

@@ -7596,6 +7596,24 @@ particularly important to \textbf{not} replace its condition with a
 temporary variable because that would interfere with the generation of
 high-quality output in the \code{explicate\_control} pass.
 
+
+\newcommand{\LifASTMonadPython}{
+\begin{array}{rcl}
+%% \itm{binaryop} &::=& \code{Add()} \MID \code{Sub()} \\
+%% \itm{cmp} &::= & \code{Eq()} \MID \code{NotEq()} \MID \code{Lt()} \MID \code{LtE()} \MID \code{Gt()} \MID \code{GtE()} \\
+%% \itm{unaryop} &::=& \code{USub()} \MID \code{Not()} \\
+%% \itm{bool} &::=& \code{True} \MID \code{False} \\
+\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}}\\
+\Exp &::=& \Atm \MID \READ{} \\
+  &\MID& \BINOP{\itm{binaryop}}{\Atm}{\Atm} \MID \UNIOP{\key{unaryop}}{\Atm} \\
+  &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm} \MID \IF{\Exp}{\Exp}{\Exp} \\
+  &\MID& \LET{\Var}{\Exp}{\Exp}\\
+\Stmt{} &::=& \PRINT{\Atm} \MID \EXPR{\Exp} \\
+        &\MID& \ASSIGN{\VAR{\Var}}{\Exp} \MID \IFSTMT{\Exp}{\Stmt^{*}}{\Stmt^{*}}\\
+\LangIfANF  &::=& \PROGRAM{\code{()}}{\Stmt^{*}}
+\end{array}
+}
+
 \begin{figure}[tp]
 \centering
 \fbox{
@@ -7603,7 +7621,7 @@ high-quality output in the \code{explicate\_control} pass.
 {\if\edition\racketEd    
 \[
 \begin{array}{rcl}
-\Atm &::=& \gray{ \INT{\Int} \MID \VAR{\Var} } \MID \BOOL{\itm{bool}}\\
+Atm &::=& \gray{ \INT{\Int} \MID \VAR{\Var} } \MID \BOOL{\itm{bool}}\\
 \Exp &::=& \gray{ \Atm \MID \READ{} } \\
      &\MID& \gray{ \NEG{\Atm} \MID \ADD{\Atm}{\Atm} } \\
      &\MID& \gray{ \LET{\Var}{\Exp}{\Exp} } \\
@@ -7615,19 +7633,11 @@ high-quality output in the \code{explicate\_control} pass.
 \fi}
 {\if\edition\pythonEd
 \[
-\begin{array}{rcl}
-\itm{binaryop} &::=& \code{Add()} \MID \code{Sub()} \\
-\itm{cmp} &::= & \code{Eq()} \MID \code{NotEq()} \MID \code{Lt()} \MID \code{LtE()} \MID \code{Gt()} \MID \code{GtE()} \\
-\itm{unaryop} &::=& \code{USub()} \MID \code{Not()} \\
-\itm{bool} &::=& \code{True} \MID \code{False} \\
-\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}}\\
-\Exp &::=& \Atm \MID \READ{} \\
-  &\MID& \BINOP{\itm{binaryop}}{\Atm}{\Atm} \MID \UNIOP{\key{unaryop}}{\Atm} \\
-  &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm} \MID \IF{\Exp}{\Exp}{\Exp} \\
-  &\MID& \LET{\Var}{\Exp}{\Exp}\\
-\Stmt{} &::=& \PRINT{\Atm} \MID \EXPR{\Exp} \\
-        &\MID& \ASSIGN{\VAR{\Var}}{\Exp} \MID \IFSTMT{\Exp}{\Stmt^{*}}{\Stmt^{*}}\\
-\LangIfANF  &::=& \PROGRAM{\code{()}}{\Stmt^{*}}
+\begin{array}{l}
+  \LifASTMonadPython \\
+  \begin{array}{rcl}
+    \LangIfANF  &::=& \PROGRAM{\code{()}}{\Stmt^{*}}
+  \end{array}
 \end{array}
 \]
 \fi}
@@ -11652,6 +11662,14 @@ pass, which is \LangAlloc{} in monadic normal form.
 \section{Explicate Control and the \LangCVec{} language}
 \label{sec:explicate-control-r3}
 
+\newcommand{\CtupASTPython}{
+\begin{array}{lcl}
+\Exp &::= & \GET{\Atm}{\Atm}\MID \ALLOCATE{\Int}{\Type} \\
+      &\MID& \GLOBALVALUE{\Var}\RP \MID \LEN{\Atm} \\
+\Stmt &::=& \COLLECT{\Int} \\
+     &\MID& \ASSIGN{\PUT{\Atm}{\Atm}}{\Atm} 
+\end{array}
+}
 
 \begin{figure}[tp]
 \fbox{
@@ -11680,23 +11698,12 @@ pass, which is \LangAlloc{} in monadic normal form.
 \fi}
 {\if\edition\pythonEd
 \[
+\begin{array}{l}
+  \gray{\CifASTPython} \\ \hline
+  \CtupASTPython \\
 \begin{array}{lcl}
-\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}} \\
-\Exp &::= & \Atm \MID \READ{} \\
-     &\MID& \BINOP{\Atm}{\itm{binaryop}}{\Atm}
-     \MID \UNIOP{\itm{unaryop}}{\Atm} \\
-     &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm} 
-     \MID \BOOLOP{\itm{boolop}}{\Atm}{\Atm} \\
-     &\MID& \GET{\Atm}{\Atm}
-     \MID \ALLOCATE{\Int}{\Type} \MID \GLOBALVALUE{\Var}\RP\\
-     &\MID& \LEN{\Atm} \\
-\Stmt &::=& \PRINT{\Exp} \MID \EXPR{\Exp} \\
-     &\MID& \ASSIGN{\VAR{\Var}}{\Exp}  
-     \MID \RETURN{\Exp} \MID \GOTO{\itm{label}} \\
-     &\MID& \IFSTMT{\CMP{\Atm}{\itm{cmp}}{\Atm}}{\LS\GOTO{\itm{label}}\RS}{\LS\GOTO{\itm{label}}\RS} \\
-     &\MID& \COLLECT{\Int} \\
-     &\MID& \ASSIGN{\PUT{\Atm}{\Atm}}{\Atm} \\
-\LangCVecM{} & ::= & \CPROGRAM{\itm{info}}{\LC\itm{label}\,\key{:}\,\Stmt^{*}, \ldots \RC}
+\LangCVecM{} & ::= & \CPROGRAM{\itm{info}}{\LC\itm{label}\key{:}\,\Stmt^{*}, \ldots \RC}
+\end{array}
 \end{array}
 \]
 \fi}
@@ -11826,6 +11833,10 @@ tag is organized.
 \code{bitwise-ior} and \code{arithmetic-shift} to compute the tag
 during compilation.}
 %
+\python{We recommend using the bitwise-or operator \code{|} and the
+  shift-left operator \code{<<} to compute the tag during
+  compilation.}
+%
 The type annotation in the \code{allocate} form is used to determine
 the pointer mask region of the tag.
 %
@@ -12807,13 +12818,15 @@ nested inside each other.
   \begin{array}{lcl}
    \Type &::=& \key{Callable}\LS \LS \Type \key{,} \ldots \RS \key{, } \Type \RS \\
    \Exp &::=& \CAPPLY{\Exp}{\Exp\code{,} \ldots} \\
+   \Stmt &::=& \CRETURN{\Exp} \\
    \Def &::=& \CDEF{\Var}{\Var \key{:} \Type\key{,} \ldots}{\Type}{\Stmt^{+}} 
   \end{array}
 }
 \newcommand{\LfunASTPython}{
   \begin{array}{lcl}
     \Type &::=& \key{FunctionType}\LP \Type^{*} \key{, } \Type \RP \\
-   \Exp &::& \CALL{\Exp}{\Exp^{*}}\\
+    \Exp &::=& \CALL{\Exp}{\Exp^{*}}\\
+    \Stmt &::=& \RETURN{\Exp} \\
    \Def &::=& \FUNDEF{\Var}{\LS \LP \Var \key{, } \Type \RP \key{, } \ldots \RS}{\Type}{}{\Stmt^{+}} 
   \end{array}
 }
@@ -13524,8 +13537,8 @@ defined in Figure~\ref{fig:f1-syntax}.
 {\if\edition\pythonEd  
 \[
 \begin{array}{lcl}
-\Exp &::=& \ldots \MID \FUNREF{\Var}\\
-  \LangFunM{} &::=& \PROGRAM{}{\LS \Def \ldots \RS}
+\Exp &::=& \FUNREF{\Var}\\
+  \LangFunM{} &::=& \PROGRAM{}{\LS \Def \code{,} \ldots \RS}
 \end{array}
 \]
 \fi}
@@ -13648,9 +13661,13 @@ classified as a complex expression so that we generate an assignment
 statement with a left-hand side that can serve as the target of the
 \code{leaq}.
 
-The output of this pass, \LangFunANF{}, extends \LangAllocANF{} with
-\code{FunRef} and \racket{\code{Apply}}\python{\code{Call}} in the
-grammar for expressions.
+The output of this pass, \LangFunANF{}, extends \LangAllocANF{}
+(Figure~\ref{fig:Lvec-anf-syntax}) with \code{FunRef}
+and \racket{\code{Apply}}\python{\code{Call}} in the grammar for expressions.
+%
+\python{Also, \LangFunANF{} adds \code{Return} to the grammar for statements.}
+
+% TODO: Return?
 
 
 %% Figure~\ref{fig:Rfun-anf-syntax} defines the output language
@@ -13693,24 +13710,50 @@ output of \code{explicate\_control}.
 \racket{(The concrete syntax is given in
   Figure~\ref{fig:c3-concrete-syntax} of the Appendix.)}
 %
-The auxiliary functions for assignment and tail contexts should be
-updated with cases for \racket{\code{Apply}}\python{\code{Call}} and
-\code{FunRef} and the function for predicate context should be updated
-for \racket{\code{Apply}}\python{\code{Call}} but not \code{FunRef}.
-(A \code{FunRef} can't be a Boolean.)  In assignment and predicate
-contexts, \code{Apply} becomes \code{Call}, whereas in tail position
-\code{Apply} becomes \code{TailCall}.  We recommend defining a new
+The auxiliary functions for assignment\racket{and tail contexts} should
+be updated with cases for
+\racket{\code{Apply}}\python{\code{Call}} and \code{FunRef} and the
+function for predicate context should be updated for
+\racket{\code{Apply}}\python{\code{Call}} but not \code{FunRef}.  (A
+\code{FunRef} can't be a Boolean.) In assignment and predicate
+contexts, \code{Apply} becomes \code{Call}\racket{, whereas in tail position
+\code{Apply} becomes \code{TailCall}}.  We recommend defining a new
 auxiliary function for processing function definitions.  This code is
 similar to the case for \code{Program} in \LangVec{}.  The top-level
 \code{explicate\_control} function that handles the \code{ProgramDefs}
 form of \LangFun{} can then apply this new function to all the
 function definitions.
 
+{\if\edition\pythonEd
+
+The translation of \code{Return} statements requires a new auxiliary
+function to handle expressions in tail context, called
+\code{explicate\_tail}. The function should take an expression and the
+dictionary of basic blocks and produce a list of statements in the
+\LangCFun{} language.  The \code{explicate\_tail} function should
+include cases for \code{Begin}, \code{IfExp}, \code{Let}, \code{Call},
+and a default case for other kinds of expressions. The default case
+should produce a \code{Return} statement. The case for \code{Call}
+should change it into \code{TailCall}.  The other cases should
+recursively process their subexpressions and statements, choosing the
+appropriate explicate functions for the various contexts.
+  
+\fi}
+
+
+\newcommand{\CfunASTPython}{
+\begin{array}{lcl}
+\Exp &::= & \FUNREF{\itm{label}} \MID \CALL{\Atm}{\LS\Atm\code{,}\ldots\RS} \\
+\Stmt &::= & \TAILCALL{\Atm}{\LS\Atm\code{,}\ldots\RS} \\
+\Def &::=& \DEF{\itm{label}}{\LS\LP\Var\key{,}\Type\RP\code{,}\ldots\RS}{\LC\itm{label}\key{:}\Stmt^{*}\code{,}\ldots\RC}{\_}{\Type}{\_} 
+\end{array}
+}
 
 \begin{figure}[tp]
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \small
+{\if\edition\racketEd
 \[
 \begin{array}{lcl}
 \Atm &::=& \gray{ \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}} }\\
@@ -13733,6 +13776,19 @@ function definitions.
 \LangCFunM{} & ::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP} 
 \end{array}
 \]
+\fi}
+{\if\edition\pythonEd
+\[
+  \begin{array}{l}
+  \gray{\CifASTPython} \\ \hline
+  \gray{\CtupASTPython} \\ \hline
+  \CfunASTPython \\
+  \begin{array}{lcl}
+    \LangCFunM{} & ::= & \CPROGRAMDEFS{\LS\Def\code{,}\ldots\RS} 
+  \end{array}
+  \end{array}
+\]
+\fi}
 \end{minipage}
 }
 \caption{The abstract syntax of \LangCFun{}, extending \LangCVec{} (Figure~\ref{fig:c2-syntax}).}
@@ -13754,8 +13810,7 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
 \small
 \[
 \begin{array}{lcl}
-  \Arg &::=& \gray{ \key{\$}\Int \MID \key{\%}\Reg \MID \Int\key{(}\key{\%}\Reg\key{)} \MID \key{\%}\itm{bytereg} } \MID \Var \key{(\%rip)} 
-   \MID \LP\key{fun-ref}\; \itm{label}\RP\\
+  \Arg &::=& \gray{ \key{\$}\Int \MID \key{\%}\Reg \MID \Int\key{(}\key{\%}\Reg\key{)} \MID \key{\%}\itm{bytereg} } \MID \Var \key{(\%rip)} \\
 \itm{cc} & ::= & \gray{  \key{e} \MID \key{l} \MID \key{le} \MID \key{g} \MID \key{ge}  } \\
 \Instr &::=& \ldots
      \MID \key{callq}\;\key{*}\Arg \MID \key{tailjmp}\;\Arg 
@@ -13775,11 +13830,12 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
 \fbox{
   \begin{minipage}{0.96\textwidth}
     \small
+{\if\edition\racketEd
 \[
 \begin{array}{lcl}
   \Arg &::=&  \gray{  \INT{\Int} \MID \REG{\Reg} \MID \DEREF{\Reg}{\Int}
      \MID \BYTEREG{\Reg} } \\
-     &\MID& \gray{ (\key{Global}~\Var) } \MID \FUNREF{\itm{label}} \\
+     &\MID& \gray{ \GLOBAL{\Var} } \MID \FUNREF{\itm{label}} \\
   \Instr &::=& \ldots \MID \INDCALLQ{\Arg}{\itm{int}}
     \MID \TAILJMP{\Arg}{\itm{int}}\\
     &\MID& \BININSTR{\code{'leaq}}{\Arg}{\REG{\Reg}}\\
@@ -13788,6 +13844,21 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
 \LangXIndCallM{} &::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP}
 \end{array}
 \]
+\fi}
+{\if\edition\pythonEd
+\[
+\begin{array}{lcl}
+  \Arg &::=&  \gray{  \INT{\Int} \MID \REG{\Reg} \MID \DEREF{\Reg}{\Int}
+     \MID \BYTEREG{\Reg} } \\
+     &\MID& \gray{ \GLOBAL{\Var} } \MID \FUNREF{\itm{label}} \\
+  \Instr &::=& \ldots \MID \INDCALLQ{\Arg}{\itm{int}}
+    \MID \TAILJMP{\Arg}{\itm{int}}\\
+    &\MID& \BININSTR{\code{leaq}}{\Arg}{\REG{\Reg}}\\
+  \Def &::= & \DEF{\itm{label}}{\LS\RS}{\LC\itm{label}\key{:}\,\Instr^{*}\code{,}\ldots\RC}{\_}{\Type}{\_} \\
+\LangXIndCallM{} &::= & \XPROGRAMDEFS{\LS\Def\code{,}\ldots\RS}
+\end{array}
+\]
+\fi}
 \end{minipage}
 }
 \caption{The abstract syntax of \LangXIndCall{} (extends
@@ -13822,21 +13893,30 @@ Section~\ref{sec:fun-x86}. That is, the arguments are passed in
 registers. We recommend turning the parameters into local variables
 and generating instructions at the beginning of the function to move
 from the argument passing registers to these local variables.
+{\if\edition\racketEd
+\begin{lstlisting}
+  (Def |$f$| '([|$x_1$| : |$T_1$|] [|$x_2$| : |$T_2$|]  |$\ldots$| ) |$T_r$| |$\itm{info}$| |$B$|)
+  |$\Rightarrow$|
+  (Def |$f$| '() 'Integer |$\itm{info}'$| |$B'$|)
+\end{lstlisting}
+\fi}
+{\if\edition\pythonEd
 \begin{lstlisting}
-  (Def |$f$| '([|$x_1$| : |$T_1$|] [|$x_2$| : |$T_2$|]  |$\ldots$| ) |$T_r$| |$\itm{info}$| |$G$|)
+  FunctionDef(|$f$|, [|$(x_1,T_1),\ldots$|], |$B$|, _, |$T_r$|, _)
   |$\Rightarrow$|
-  (Def |$f$| '() 'Integer |$\itm{info}'$| |$G'$|)
+  FunctionDef(|$f$|, [], |$B'$|, _, int, _)
 \end{lstlisting}
-The $G'$ control-flow graph is the same as $G$ except that the
+\fi}
+The basic blocks $B'$ are the same as $B$ except that the
 \code{start} block is modified to add the instructions for moving from
 the argument registers to the parameter variables. So the \code{start}
-block of $G$ shown on the left is changed to the code on the right.
+block of $B$ shown on the left is changed to the code on the right.
 \begin{center}
 \begin{minipage}{0.3\textwidth}
 \begin{lstlisting}
 start:
   |$\itm{instr}_1$|
-  |$\vdots$|
+  |$\cdots$|
   |$\itm{instr}_n$|
 \end{lstlisting}
 \end{minipage}
@@ -13845,10 +13925,9 @@ $\Rightarrow$
 \begin{lstlisting}
 start:
   movq %rdi, |$x_1$|
-  movq %rsi, |$x_2$|
-  |$\vdots$|
+  |$\cdots$|
   |$\itm{instr}_1$|
-  |$\vdots$|
+  |$\cdots$|
   |$\itm{instr}_n$|
 \end{lstlisting}
 \end{minipage}
@@ -13877,7 +13956,7 @@ itself is performed with an indirect function call. The return value
 from the function is stored in \code{rax}, so it needs to be moved
 into the \itm{lhs}.
 \begin{lstlisting}
-  |\itm{lhs}| = (call |\itm{fun}| |$\itm{arg}_1~\itm{arg}_2\ldots$|));
+  |\itm{lhs}| = |$\CALL{\itm{fun}}{\itm{arg}_1\ldots}$|
   |$\Rightarrow$|
   movq |$\itm{arg}_1$|, %rdi
   movq |$\itm{arg}_2$|, %rsi
@@ -13887,7 +13966,7 @@ into the \itm{lhs}.
 \end{lstlisting}
 The \code{IndirectCallq} AST node includes an integer for the arity of
 the function, i.e., the number of parameters. That information is
-useful in the \code{uncover-live} pass for determining which
+useful in the \code{uncover\_live} pass for determining which
 argument-passing registers are potentially read during the call.
 
 For tail calls, the parameter passing is the same as non-tail calls:
@@ -13901,18 +13980,15 @@ means ``pop the frame and then do an indirect jump'', which we name
 argument that specifies where to jump and an integer that represents
 the arity of the function being called.
 
-Recall that in Section~\ref{sec:explicate-control-Lvar} we recommended
-using the label \code{start} for the initial block of a program, and
-in Section~\ref{sec:select-Lvar} we recommended labeling the conclusion
-of the program with \code{conclusion}, so that $(\key{Return}\;\Arg)$
-can be compiled to an assignment to \code{rax} followed by a jump to
-\code{conclusion}. With the addition of function definitions, we will
-have a starting block and conclusion for each function, but their
-labels need to be unique. We recommend prepending the function's name
-to \code{start} and \code{conclusion}, respectively, to obtain unique
-labels. (Alternatively, one could \code{gensym} labels for the start
-and conclusion and store them in the $\itm{info}$ field of the
-function definition.)
+Recall that we use the label \code{start} for the initial block of a
+program, and in Section~\ref{sec:select-Lvar} we recommended labeling
+the conclusion of the program with \code{conclusion}, so that
+$\RETURN{Arg}$ can be compiled to an assignment to \code{rax} followed
+by a jump to \code{conclusion}. With the addition of function
+definitions, there is a start block and conclusion for each function,
+but their labels need to be unique. We recommend prepending the
+function's name to \code{start} and \code{conclusion}, respectively,
+to obtain unique labels.
 
 
 \section{Register Allocation}
@@ -13978,31 +14054,33 @@ register. Additionally, you should ensure that the argument of
 code generation more convenient, because we trample many registers
 before the tail call (as explained in the next section).
 
-\section{Print x86}
+\section{Prelude and Conclusion}
 
-For the \code{print\_x86} pass, the cases for \code{FunRef} and
-\code{IndirectCallq} are straightforward: output their concrete
-syntax.
-\begin{lstlisting}
-  (FunRef |\itm{label}|) |$\Rightarrow$| |\itm{label}|(%rip)
-  (IndirectCallq |\itm{arg}| |\itm{int}|) |$\Rightarrow$| callq *|\itm{arg}'|
-\end{lstlisting}
+%% For the \code{print\_x86} pass, the cases for \code{FunRef} and
+%% \code{IndirectCallq} are straightforward: output their concrete
+%% syntax.
+%% \begin{lstlisting}
+%%   (FunRef |\itm{label}|) |$\Rightarrow$| |\itm{label}|(%rip)
+%%   (IndirectCallq |\itm{arg}| |\itm{int}|) |$\Rightarrow$| callq *|\itm{arg}'|
+%% \end{lstlisting}
 
-The \code{TailJmp} node requires a bit work. A straightforward
-translation of \code{TailJmp} would be \code{jmp *$\itm{arg}$}, but
-before the jump we need to pop the current frame. This sequence of
-instructions is the same as the code for the conclusion of a function,
-except the \code{retq} is replaced with \code{jmp *$\itm{arg}$}.
+Now that register allocation is complete, we can translate the
+\code{TailJmp} into a sequence of instructions. A straightforward
+translation of \code{TailJmp} would simply be \code{jmp *$\itm{arg}$}.
+However, before the jump we need to pop the current frame. This
+sequence of instructions is the same as the code for the conclusion of
+a function, except the \code{retq} is replaced with \code{jmp *$\itm{arg}$}.
 
-Regarding function definitions, you will need to generate a prelude
+Regarding function definitions, you need to generate a prelude
 and conclusion for each one. This code is similar to the prelude and
 conclusion that you generated for the \code{main} function in
 Chapter~\ref{ch:Lvec}. To review, the prelude of every function
 should carry out the following steps.
+% TODO: .align the functions!
 \begin{enumerate}
-\item Start with \code{.global} and \code{.align} directives followed
-  by the label for the function.  (See Figure~\ref{fig:add-fun} for an
-  example.)
+%% \item Start with \code{.global} and \code{.align} directives followed
+%%   by the label for the function.  (See Figure~\ref{fig:add-fun} for an
+  %%   example.)
 \item Push \code{rbp} to the stack and set \code{rbp} to current stack
   pointer.
 \item Push to the stack all of the callee-saved registers that were
@@ -14108,13 +14186,24 @@ function in \LangFun{} to x86. The figure also includes the results of the
 \begin{tabular}{ll}
 \begin{minipage}{0.5\textwidth}
 % s3_2.rkt
+{\if\edition\racketEd
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 (define (add [x : Integer] [y : Integer])
    : Integer
    (+ x y))
 (add 40 2)
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+def add(x:int, y:int) -> int:
+    return x + y
+
+print(add(40, 2))
+\end{lstlisting}
+\fi}
 $\Downarrow$
+{\if\edition\racketEd
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 (define (add86 [x87 : Integer]
                  [y88 : Integer]) : Integer
@@ -14127,10 +14216,26 @@ $\Downarrow$
       (tail-call tmp89 40 2)
    )
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+def add(x:int, y:int) -> int:
+    addstart:
+        return x + y
+
+def main() -> int:
+    mainstart:
+        fun.0 = add
+        tmp.1 = fun.0(40, 2)
+        print(tmp.1)
+        return 0
+\end{lstlisting}
+\fi}
 \end{minipage}
 &
 $\Rightarrow$
 \begin{minipage}{0.5\textwidth}
+{\if\edition\racketEd
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 (define (add86) : Integer
    add86start:
@@ -14148,11 +14253,36 @@ $\Rightarrow$
       tail-jmp tmp89
    )
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+def add() -> int:
+    addstart:
+        movq %rdi, x
+        movq %rsi, y
+        movq x, %rax
+        addq y, %rax
+        jmp addconclusion
+
+def main() -> int:
+    mainstart:
+        leaq add, fun.0
+        movq $40, %rdi
+        movq $2, %rsi
+        callq *fun.0
+        movq %rax, tmp.1
+        movq tmp.1, %rdi
+        callq print_int
+        movq $0, %rax
+        jmp mainconclusion
+\end{lstlisting}
+\fi}
 $\Downarrow$
 \end{minipage}
 \end{tabular}
 \begin{tabular}{ll}
 \begin{minipage}{0.3\textwidth}
+{\if\edition\racketEd
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 	.globl add86
 	.align 16
@@ -14168,9 +14298,32 @@ add86conclusion:
 	popq	%rbp
 	retq
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+  .align 16
+add:
+  pushq %rbp
+  movq %rsp, %rbp
+  subq $0, %rsp
+  jmp addstart
+addstart:
+  movq %rdi, %rdx
+  movq %rsi, %rcx
+  movq %rdx, %rax
+  addq %rcx, %rax
+  jmp addconclusion
+addconclusion:
+  subq $0, %r15
+  addq $0, %rsp
+  popq %rbp
+  retq 
+\end{lstlisting}
+\fi}
 \end{minipage}
 &
 \begin{minipage}{0.5\textwidth}
+{\if\edition\racketEd
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 	.globl main
 	.align 16
@@ -14193,6 +14346,37 @@ mainconclusion:
 	popq	%rbp
 	retq
 \end{lstlisting}
+\fi}
+{\if\edition\pythonEd
+\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
+  .globl main
+  .align 16
+main:
+  pushq %rbp
+  movq %rsp, %rbp
+  subq $0, %rsp
+  movq $65536, %rdi
+  movq $65536, %rsi
+  callq initialize
+  movq rootstack_begin(%rip), %r15
+  jmp mainstart
+mainstart:
+  leaq add(%rip), %rcx
+  movq $40, %rdi
+  movq $2, %rsi
+  callq *%rcx
+  movq %rax, %rcx
+  movq %rcx, %rdi
+  callq print_int
+  movq $0, %rax
+  jmp mainconclusion
+mainconclusion:
+  subq $0, %r15
+  addq $0, %rsp
+  popq %rbp
+  retq 
+\end{lstlisting}
+\fi}
 \end{minipage}
 \end{tabular}
 \caption{Example compilation of a simple function to x86.}

+ 13 - 5
defs.tex

@@ -147,6 +147,7 @@
 \newcommand{\BOOLTY}{{\key{Boolean}}}
 \newcommand{\VECTY}[1]{{\LP\key{Vector}#1\RP}}
 \newcommand{\CPROGRAM}[2]{\LP\code{CProgram}~#1~#2\RP}
+\newcommand{\CPROGRAMDEFS}[2]{\LP\code{CProgramDefs}~#1~#2\RP}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \newcommand{\CLET}[3]{\LP\key{let}~\LP\LS#1~#2\RS\RP~#3\RP}
 \newcommand{\COLLECT}[1]{\LP\key{Collect}~#1\RP}
@@ -174,6 +175,7 @@
 \newcommand{\EXPR}[1]{{\key{Expr}\LP #1\RP}}
 \newcommand{\PROGRAM}[2]{\code{Module}\LP #2\RP}
 \newcommand{\CPROGRAM}[2]{\code{CProgram}\LP #2 \RP}
+\newcommand{\CPROGRAMDEFS}[1]{\code{CProgramDefs}\LP #1 \RP}
 \newcommand{\VAR}[1]{\key{Name}\LP #1\RP}
 \newcommand{\BOOL}[1]{\key{Constant}\LP #1 \RP}
 \newcommand{\UNIOP}[2]{\key{UnaryOp}\LP #1 \code{,} #2 \RP}
@@ -215,6 +217,7 @@
 \newcommand{\APPLY}[2]{\key{Call}\LP#1\code{, }#2\RP}
 \newcommand{\CAPPLY}[2]{#1\LP#2\RP}
 \newcommand{\FUNREF}[1]{\key{FunRef}\LP#1\RP}
+\newcommand{\CFUNREF}[1]{#1\code{(\%rip)}}
 \fi % pythonEd
 
 \if\edition\racketEd
@@ -226,6 +229,7 @@
 \newcommand{\APPLY}[2]{\key{(Apply}~#1~#2\code{)}}
 \newcommand{\CAPPLY}[2]{\LP~#1~#2\RP}
 \newcommand{\FUNREF}[1]{\LP\key{FunRef}~#1\RP}
+\newcommand{\CFUNREF}[1]{\key{(fun-ref}~#1\code{)}}
 \fi
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PROGRAMDEFSEXP}[3]{\code{(ProgramDefsExp}~#1~#2~#3\code{)}}
@@ -253,8 +257,6 @@
 \newcommand{\ALLOCCLOS}[3]{\LP\key{AllocateClosure}~#1~#2~#3\RP}
 
 \newcommand{\VOID}[1]{\key{(Void)}}
-\newcommand{\TAILCALL}[2]{\key{(TailCall}~#1~#2\code{)}}
-\newcommand{\CFUNREF}[1]{\key{(fun-ref}~#1\code{)}}
 \newcommand{\FUNREFARITY}[2]{\key{(FunRefArity}~#1~#2\code{)}}
 \newcommand{\CFUNREFARITY}[2]{\key{(fun-ref-arity}~#1~#2\code{)}}
 \newcommand{\LAMBDA}[3]{\key{(Lambda}~#1~#2~#3\code{)}}
@@ -267,6 +269,7 @@
 \newcommand{\VALUEOF}[2]{\LP\key{ValueOf}~#1~#2\RP}
 
 \if\edition\racketEd
+\newcommand{\TAILCALL}[2]{\key{(TailCall}~#1~#2\code{)}}
 \newcommand{\CASSIGN}[2]{#1~\key{=}~#2\key{;}}
 \newcommand{\ASSIGN}[2]{\key{(Assign}~#1~#2\key{)}}
 \newcommand{\IFSTMT}[3]{\key{(IfStmt}\,#1~#2~#3\key{)}}
@@ -277,6 +280,7 @@
 \newcommand{\FUNDEF}[5]{\key{(Def}~#1~#2~#3~#4~#5\code{)}}
 \fi
 \if\edition\pythonEd
+\newcommand{\TAILCALL}[2]{\key{TailCall}\LP#1\code{,}#2\RP}
 \newcommand{\CASSIGN}[2]{#1~\key{=}~#2}
 \newcommand{\ASSIGN}[2]{\key{Assign}\LP\LS #1\RS\key{, }#2\RP}
 \newcommand{\IFSTMT}[3]{\key{If}\LP #1 \code{, } #2 \code{, } #3 \RP}
@@ -308,8 +312,13 @@
 \newcommand{\XPROGRAM}[2]{\LP\code{X86Program}~#1~#2\RP}
 \newcommand{\BYTEREG}[1]{\key{(ByteReg}~#1\key{)}}
 \newcommand{\CDEF}[4]{\LP\key{define}~\LP#1~#2\RP\,\key{:}\,#3~#4\RP}
+\newcommand{\DEF}[5]{\LP\key{Def}~#1~#2~#3~#4~#5\RP}
+\newcommand{\INDCALLQ}[2]{\key{(IndirectCallq}~#1~#2\key{)}}
+\newcommand{\TAILJMP}[2]{\key{(TailJmp}~#1~#2\key{)}}
 \fi
 \if\edition\pythonEd
+\newcommand{\TAILJMP}[2]{\key{TailJmp}\LP#1\code{, }#2\RP}
+\newcommand{\INDCALLQ}[2]{\key{IndirectCallq}\LP#1\code{, }#2\RP}
 \newcommand{\IMM}[1]{\key{Constant}\LP #1\RP}
 \newcommand{\REG}[1]{\key{Reg}\LP #1\RP}
 \newcommand{\DEREF}[2]{\key{Deref}\LP #1 \key{,} #2 \RP}
@@ -323,21 +332,20 @@
 \newcommand{\RETQ}{\key{Retq}\LP\RP}
 % TODO: change \XPROGRAM to 1 parameter
 \newcommand{\XPROGRAM}[2]{\code{X86Program}\LP #2 \RP}
+\newcommand{\XPROGRAMDEFS}[1]{\code{X86ProgramDefs}\LP #1 \RP}
 \newcommand{\BYTEREG}[1]{\key{ByteReg}\LP #1 \RP}
 \newcommand{\CDEF}[4]{\key{def}~#1\LP #2 \RP ~\key{->}~ #3 \key{:}~#4}
+\newcommand{\DEF}[6]{\key{FunctionDef}\LP#1\key{, }#2\key{, }#3\key{, }#4\key{, }#5\key{, }#6\RP}
 \fi
 
 
 
-\newcommand{\DEF}[5]{\LP\key{Def}~#1~#2~#3~#4~#5\RP}
 \newcommand{\CGDEF}[4]{\LP\key{define}~\LP#1~#2\RP\,#3~#4\RP}
 \newcommand{\DECL}[2]{\LP\key{Decl}~#1~#2\RP}
 \newcommand{\INST}[3]{\LP\key{Inst}~#1~#2~#3\RP}
 \newcommand{\CFG}[1]{\key{(CFG}~#1\key{)}}
 \newcommand{\BLOCK}[2]{\key{(Block}~#1~#2\key{)}}
 \newcommand{\STACKLOC}[1]{(\key{stack}~#1)}
-\newcommand{\INDCALLQ}[2]{\key{(IndirectCallq}~#1~#2\key{)}}
-\newcommand{\TAILJMP}[2]{\key{(TailJmp}~#1~#2\key{)}}