Jeremy Siek 4 年之前
父節點
當前提交
b6315c25ba
共有 2 個文件被更改,包括 85 次插入39 次删除
  1. 72 34
      book.tex
  2. 13 5
      defs.tex

+ 72 - 34
book.tex

@@ -2428,7 +2428,7 @@ register allocation (Chapter~\ref{ch:register-allocation-Rvar}).
 \label{fig:x86-int-ast}
 \label{fig:x86-int-ast}
 \end{figure}
 \end{figure}
 
 
-\section{Planning the trip to x86 via the \LangCVar{} language}
+\section{Planning the trip to x86}
 \label{sec:plan-s0-x86}
 \label{sec:plan-s0-x86}
 
 
 To compile one language to another it helps to focus on the
 To compile one language to another it helps to focus on the
@@ -2437,26 +2437,28 @@ to bridge those differences. What are the differences between \LangVar{}
 and x86 assembly? Here are some of the most important ones:
 and x86 assembly? Here are some of the most important ones:
 
 
 \begin{enumerate}
 \begin{enumerate}
-\item[(a)] x86 arithmetic instructions typically have two arguments
+\item x86 arithmetic instructions typically have two arguments
   and update the second argument in place. In contrast, \LangVar{}
   and update the second argument in place. In contrast, \LangVar{}
   arithmetic operations take two arguments and produce a new value.
   arithmetic operations take two arguments and produce a new value.
   An x86 instruction may have at most one memory-accessing argument.
   An x86 instruction may have at most one memory-accessing argument.
   Furthermore, some instructions place special restrictions on their
   Furthermore, some instructions place special restrictions on their
   arguments.
   arguments.
 
 
-\item[(b)] An argument of an \LangVar{} operator can be a deeply-nested
+\item An argument of an \LangVar{} operator can be a deeply-nested
   expression, whereas x86 instructions restrict their arguments to be
   expression, whereas x86 instructions restrict their arguments to be
   integer constants, registers, and memory locations.
   integer constants, registers, and memory locations.
 
 
+{\if\edition\racketEd\color{olive}      
 \item[(c)] The order of execution in x86 is explicit in the syntax: a
 \item[(c)] The order of execution in x86 is explicit in the syntax: a
   sequence of instructions and jumps to labeled positions, whereas in
   sequence of instructions and jumps to labeled positions, whereas in
   \LangVar{} the order of evaluation is a left-to-right depth-first
   \LangVar{} the order of evaluation is a left-to-right depth-first
   traversal of the abstract syntax tree.
   traversal of the abstract syntax tree.
+\fi}
 
 
-\item[(d)] A program in \LangVar{} can have any number of variables
+\item A program in \LangVar{} can have any number of variables
   whereas x86 has 16 registers and the procedure calls stack.
   whereas x86 has 16 registers and the procedure calls stack.
 {\if\edition\racketEd\color{olive}    
 {\if\edition\racketEd\color{olive}    
-\item[(e)] Variables in \LangVar{} can shadow other variables with the
+\item Variables in \LangVar{} can shadow other variables with the
   same name. In x86, registers have unique names and memory locations
   same name. In x86, registers have unique names and memory locations
   have unique addresses.
   have unique addresses.
 \fi}  
 \fi}  
@@ -2482,10 +2484,10 @@ recursive function per non-terminal in the grammar of the input
 language of the pass.  \index{subject}{intermediate language}
 language of the pass.  \index{subject}{intermediate language}
 
 
 \begin{description}
 \begin{description}
-\item[\key{select\_instructions}] handles the difference between
-  \LangVar{} operations and x86 instructions. This pass converts each
-  \LangVar{} operation to a short sequence of instructions that
-  accomplishes the same task.
+{\if\edition\racketEd\color{olive}
+\item[\key{uniquify}] deals with the shadowing of variables by
+  renaming every variable to a unique name.
+  \fi}
 
 
 \item[\key{remove\_complex\_operands}] ensures that each subexpression
 \item[\key{remove\_complex\_operands}] ensures that each subexpression
   of a primitive operation or function call is a variable or integer,
   of a primitive operation or function call is a variable or integer,
@@ -2494,9 +2496,6 @@ language of the pass.  \index{subject}{intermediate language}
   variables to hold the results of complex
   variables to hold the results of complex
   subexpressions.\index{subject}{atomic
   subexpressions.\index{subject}{atomic
     expression}\index{subject}{complex expression}%
     expression}\index{subject}{complex expression}%
-  \footnote{The subexpressions of an operation are often called
-    operators and operands which explains the presence of
-    \code{opera*} in the name of this pass.}
   
   
 {\if\edition\racketEd\color{olive}
 {\if\edition\racketEd\color{olive}
 \item[\key{explicate\_control}] makes the execution order of the
 \item[\key{explicate\_control}] makes the execution order of the
@@ -2506,13 +2505,13 @@ language of the pass.  \index{subject}{intermediate language}
   to other nodes.
   to other nodes.
 \fi}
 \fi}
 
 
+\item[\key{select\_instructions}] handles the difference between
+  \LangVar{} operations and x86 instructions. This pass converts each
+  \LangVar{} operation to a short sequence of instructions that
+  accomplishes the same task.
+
 \item[\key{assign\_homes}] replaces the variables in \LangVar{} with
 \item[\key{assign\_homes}] replaces the variables in \LangVar{} with
   registers or stack locations in x86.
   registers or stack locations in x86.
-
-{\if\edition\racketEd\color{olive}
-\item[\key{uniquify}] deals with the shadowing of variables by
-  renaming every variable to a unique name.
-\fi}
 \end{description}
 \end{description}
 
 
 The next question is: in what order should we apply these passes? This
 The next question is: in what order should we apply these passes? This
@@ -3395,7 +3394,7 @@ be propagated to the \code{X86Program} node.}
 %
 %
 \python{The \code{assign\_homes} pass should replace all uses of
 \python{The \code{assign\_homes} pass should replace all uses of
   variables with stack locations.}
   variables with stack locations.}
-
+%
 In the process of assigning variables to stack locations, it is
 In the process of assigning variables to stack locations, it is
 convenient for you to compute and store the size of the frame (in
 convenient for you to compute and store the size of the frame (in
 bytes) in%
 bytes) in%
@@ -6135,7 +6134,8 @@ With the addition of \key{if}, programs can have non-trivial control flow which
 \python{impacts liveness analysis and motivates a new pass named
 \python{impacts liveness analysis and motivates a new pass named
   \code{explicate\_control}}. Also, because
   \code{explicate\_control}}. Also, because
 we now have two kinds of values, we need to handle programs that apply
 we now have two kinds of values, we need to handle programs that apply
-an operation to the wrong kind of value, such as \code{(not 1)}.
+an operation to the wrong kind of value, such as
+\racket{\code{(not 1)}}\python{\code{not 1}}.
 
 
 There are two language design options for such situations.  One option
 There are two language design options for such situations.  One option
 is to signal an error and the other is to provide a wider
 is to signal an error and the other is to provide a wider
@@ -6195,11 +6195,11 @@ handled in later passes.
 %
 %
 \python{The largest addition is a new pass named
 \python{The largest addition is a new pass named
   \code{explicate\_control} that translates \code{if} expressions and
   \code{explicate\_control} that translates \code{if} expressions and
-  statements into control-flow graphs
+  statements into conditional \code{goto}'s
   (Section~\ref{sec:explicate-control-Rif}).}
   (Section~\ref{sec:explicate-control-Rif}).}
 %
 %
 Regarding register allocation, there is the interesting question of
 Regarding register allocation, there is the interesting question of
-how to handle conditional jumps during liveness analysis.
+how to handle conditional \code{goto}'s during liveness analysis.
 
 
 
 
 \section{The \LangIf{} Language}
 \section{The \LangIf{} Language}
@@ -6330,7 +6330,7 @@ is not evaluated if $e_1$ evaluates to \TRUE{}.
 \racket{With the increase in the number of primitive operations, the
 \racket{With the increase in the number of primitive operations, the
   interpreter would become repetitive without some care.  We refactor
   interpreter would become repetitive without some care.  We refactor
   the case for \code{Prim}, moving the code that differs with each
   the case for \code{Prim}, moving the code that differs with each
-  operation into the \code{interp_op} method shown in in
+  operation into the \code{interp\_op} method shown in in
   Figure~\ref{fig:interp-op-Rif}. We handle the \code{and} operation
   Figure~\ref{fig:interp-op-Rif}. We handle the \code{and} operation
   separately because of its short-circuiting behavior.}
   separately because of its short-circuiting behavior.}
 
 
@@ -6864,28 +6864,47 @@ expected.
 \section{The \LangCIf{} Intermediate Language}
 \section{The \LangCIf{} Intermediate Language}
 \label{sec:Cif}
 \label{sec:Cif}
 
 
+{\if\edition\pythonEd\color{purple}
+
+The output of \key{explicate\_control} is similar to the $C$
+language~\citep{Kernighan:1988nx} in that it has labels and \code{goto}
+statements, so we name it \LangCIf{}.  The abstract syntax for
+\LangCIf{} is defined in Figure~\ref{fig:c1-syntax}.  (The concrete
+syntax for \LangCIf{} is in the Appendix,
+Figure~\ref{fig:c1-concrete-syntax}.)
+%
+The \LangCIf{} language supports the same operators as \LangIf{} but
+the arguments of operators are restricted to atomic
+expressions. 
+%
+Also, a \LangCIf{} program consists of a dictionary mapping labels to
+lists of statements, instead of simply being a list of statements.
+\fi}
+
+\racket{
 Figure~\ref{fig:c1-syntax} defines the abstract syntax of the
 Figure~\ref{fig:c1-syntax} defines the abstract syntax of the
 \LangCIf{} intermediate language. (The concrete syntax is in the
 \LangCIf{} intermediate language. (The concrete syntax is in the
 Appendix, Figure~\ref{fig:c1-concrete-syntax}.)  Compared to
 Appendix, Figure~\ref{fig:c1-concrete-syntax}.)  Compared to
 \LangCVar{}, the \LangCIf{} language adds logical and comparison
 \LangCVar{}, the \LangCIf{} language adds logical and comparison
-operators to the \Exp{} non-terminal and the literals \key{\#t} and
-\key{\#f} to the \Arg{} non-terminal.
+operators to the \Exp{} non-terminal and the literals \TRUE{} and
+\FALSE{} to the \Arg{} non-terminal.
 
 
 Regarding control flow, \LangCIf{} adds \key{goto} and \code{if}
 Regarding control flow, \LangCIf{} adds \key{goto} and \code{if}
 statements to the \Tail{} non-terminal. The condition of an \code{if}
 statements to the \Tail{} non-terminal. The condition of an \code{if}
 statement is a comparison operation and the branches are \code{goto}
 statement is a comparison operation and the branches are \code{goto}
 statements, making it straightforward to compile \code{if} statements
 statements, making it straightforward to compile \code{if} statements
 to x86.
 to x86.
-
+}
 
 
 \begin{figure}[tp]
 \begin{figure}[tp]
 \fbox{
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 \small    
 \small    
+{\if\edition\racketEd\color{olive}    
 \[
 \[
 \begin{array}{lcl}
 \begin{array}{lcl}
 \Atm &::=& \gray{\INT{\Int} \MID \VAR{\Var}} \MID \BOOL{\itm{bool}} \\
 \Atm &::=& \gray{\INT{\Int} \MID \VAR{\Var}} \MID \BOOL{\itm{bool}} \\
-\itm{cmp} &::= & \key{eq?} \MID \key{<}  \\
+\itm{cmp} &::= & \key{eq?} \MID \key{<} \\
 \Exp &::= & \gray{ \Atm \MID \READ{} }\\
 \Exp &::= & \gray{ \Atm \MID \READ{} }\\
      &\MID& \gray{ \NEG{\Atm} \MID \ADD{\Atm}{\Atm} } \\
      &\MID& \gray{ \NEG{\Atm} \MID \ADD{\Atm}{\Atm} } \\
      &\MID& \UNIOP{\key{'not}}{\Atm} 
      &\MID& \UNIOP{\key{'not}}{\Atm} 
@@ -6897,10 +6916,29 @@ to x86.
 \LangCIfM{} & ::= & \gray{\CPROGRAM{\itm{info}}{\LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP}}
 \LangCIfM{} & ::= & \gray{\CPROGRAM{\itm{info}}{\LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP}}
 \end{array}
 \end{array}
 \]
 \]
+\fi}
+{\if\edition\pythonEd\color{purple}
+\[
+\begin{array}{lcl}
+\Atm &::=& \INT{\Int} \MID \VAR{\Var} \MID \BOOL{\itm{bool}} \\
+\itm{cmp} &::= & \key{eq?} \MID \key{<}  \\
+\Exp &::= & \Atm \MID \READ{} \\
+     &\MID& \BINOP{\Atm}{\itm{binop}}{\Atm}
+     \MID \UNIOP{\itm{uniop}}{\Atm} \\
+     &\MID& \CMP{\Atm}{\itm{cmp}}{\Atm} 
+     \MID \BOOLOP{\itm{boolop}}{\Atm}{\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} \\
+\LangCIfM{} & ::= & \CPROGRAM{\itm{info}}{\LC\itm{label}\,\key{:}\,\Stmt^{+}, \ldots \RC}
+\end{array}
+\]
+\fi}
 \end{minipage}
 \end{minipage}
 }
 }
-\caption{The abstract syntax of \LangCIf{}, an extension of \LangCVar{}
-  (Figure~\ref{fig:c0-syntax}).}
+\caption{The abstract syntax of \LangCIf{}\racket{, an extension of \LangCVar{}
+  (Figure~\ref{fig:c0-syntax})}.}
 \label{fig:c1-syntax}
 \label{fig:c1-syntax}
 \end{figure}
 \end{figure}
 
 
@@ -6934,7 +6972,7 @@ for the bit $1$, the result is the opposite of the second bit.  Thus,
 the \code{not} operation can be implemented by \code{xorq} with $1$ as
 the \code{not} operation can be implemented by \code{xorq} with $1$ as
 the first argument:
 the first argument:
 \[
 \[
-\Var~ \key{=}~ \LP\key{not}~\Arg\RP\key{;}
+\CASSIGN{\Var}{\CUNIOP{\key{not}}{\Arg}}
 \qquad\Rightarrow\qquad
 \qquad\Rightarrow\qquad
 \begin{array}{l}
 \begin{array}{l}
 \key{movq}~ \Arg\key{,} \Var\\
 \key{movq}~ \Arg\key{,} \Var\\
@@ -6995,7 +7033,7 @@ the first argument:
        \MID \BININSTR{\code{cmpq}}{\Arg}{\Arg}\\
        \MID \BININSTR{\code{cmpq}}{\Arg}{\Arg}\\
        &\MID& \BININSTR{\code{set}}{\itm{cc}}{\Arg} 
        &\MID& \BININSTR{\code{set}}{\itm{cc}}{\Arg} 
        \MID \BININSTR{\code{movzbq}}{\Arg}{\Arg}\\
        \MID \BININSTR{\code{movzbq}}{\Arg}{\Arg}\\
-       &\MID&  \JMPIF{\itm{cc}}{\itm{label}} \\
+       &\MID&  \JMPIF{'\itm{cc}'}{\itm{label}} \\
 \Block &::= & \gray{\BLOCK{\itm{info}}{\LP\Instr\ldots\RP}} \\
 \Block &::= & \gray{\BLOCK{\itm{info}}{\LP\Instr\ldots\RP}} \\
 \LangXIfM{} &::= & \gray{\XPROGRAM{\itm{info}}{\LP\LP\itm{label} \,\key{.}\, \Block \RP\ldots\RP}}
 \LangXIfM{} &::= & \gray{\XPROGRAM{\itm{info}}{\LP\LP\itm{label} \,\key{.}\, \Block \RP\ldots\RP}}
 \end{array}
 \end{array}
@@ -7037,10 +7075,10 @@ the EFLAGS register matches the condition code \itm{cc}, otherwise the
 jump instruction falls through to the next instruction.  Like the
 jump instruction falls through to the next instruction.  Like the
 abstract syntax for \code{set}, the abstract syntax for conditional
 abstract syntax for \code{set}, the abstract syntax for conditional
 jump separates the instruction name from the condition code. For
 jump separates the instruction name from the condition code. For
-example, \code{(JmpIf le foo)} corresponds to \code{jle foo}.  Because
-the conditional jump instruction relies on the EFLAGS register, it is
-common for it to be immediately preceded by a \key{cmpq} instruction
-to set the EFLAGS register.
+example, \JMPIF{\key{'le'}}{\key{foo}} corresponds to \code{jle foo}.
+Because the conditional jump instruction relies on the EFLAGS
+register, it is common for it to be immediately preceded by a
+\key{cmpq} instruction to set the EFLAGS register.
 
 
 
 
 \section{Shrink the \LangIf{} Language}
 \section{Shrink the \LangIf{} Language}

+ 13 - 5
defs.tex

@@ -122,6 +122,8 @@
 \newcommand{\RP}{\key{)}}
 \newcommand{\RP}{\key{)}}
 \newcommand{\LS}{\key{[}}
 \newcommand{\LS}{\key{[}}
 \newcommand{\RS}{\key{]}}
 \newcommand{\RS}{\key{]}}
+\newcommand{\LC}{\key{\{}}
+\newcommand{\RC}{\key{\}}}
 
 
 \newcommand{\MID}{\;\;\mid\;\;}
 \newcommand{\MID}{\;\;\mid\;\;}
 
 
@@ -148,6 +150,7 @@
 \newcommand{\COR}[2]{\CBINOP{\key{or}}{#1}{#2}}
 \newcommand{\COR}[2]{\CBINOP{\key{or}}{#1}{#2}}
 \newcommand{\INTTY}{{\color{olive}\key{Integer}}}
 \newcommand{\INTTY}{{\color{olive}\key{Integer}}}
 \newcommand{\BOOLTY}{{\color{olive}\key{Boolean}}}
 \newcommand{\BOOLTY}{{\color{olive}\key{Boolean}}}
+\newcommand{\CPROGRAM}[2]{\LP\code{CProgram}~#1~#2\RP}
 \fi
 \fi
 
 
 \if\edition\pythonEd
 \if\edition\pythonEd
@@ -159,13 +162,14 @@
 \newcommand{\PRINT}[1]{{\color{purple}\key{Expr}\LP\key{Call}\LP\key{Name}\LP\key{'print'}\RP\key{,}\LS#1\RS\RP\RP}}
 \newcommand{\PRINT}[1]{{\color{purple}\key{Expr}\LP\key{Call}\LP\key{Name}\LP\key{'print'}\RP\key{,}\LS#1\RS\RP\RP}}
 \newcommand{\EXPR}[1]{{\color{purple}\key{Expr}\LP #1\RP}}
 \newcommand{\EXPR}[1]{{\color{purple}\key{Expr}\LP #1\RP}}
 \newcommand{\PROGRAM}[2]{\code{Module}\LP #2\RP}
 \newcommand{\PROGRAM}[2]{\code{Module}\LP #2\RP}
+\newcommand{\CPROGRAM}[2]{\code{Program}\LP #2 \RP}
 \newcommand{\VAR}[1]{\key{Name}\LP #1\RP}
 \newcommand{\VAR}[1]{\key{Name}\LP #1\RP}
 \newcommand{\BOOL}[1]{\key{Constant}\LP #1 \RP}
 \newcommand{\BOOL}[1]{\key{Constant}\LP #1 \RP}
 \newcommand{\UNIOP}[2]{\key{UnaryOp}\LP #1 \code{,} #2 \RP}
 \newcommand{\UNIOP}[2]{\key{UnaryOp}\LP #1 \code{,} #2 \RP}
 \newcommand{\CUNIOP}[2]{#1~#2}
 \newcommand{\CUNIOP}[2]{#1~#2}
 \newcommand{\BINOP}[3]{\key{BinOp}\LP #1 \code{,} #2 \code{,} #3 \RP}
 \newcommand{\BINOP}[3]{\key{BinOp}\LP #1 \code{,} #2 \code{,} #3 \RP}
 \newcommand{\BOOLOP}[3]{\key{BoolOp}\LP #1 \code{,} \LS #2 \code{,} #3 \RS \RP}
 \newcommand{\BOOLOP}[3]{\key{BoolOp}\LP #1 \code{,} \LS #2 \code{,} #3 \RS \RP}
-\newcommand{\CMP}[3]{\key{Compare}\LP #1\code{,}\LS #2 \RS \code{,} #3\RP}
+\newcommand{\CMP}[3]{\key{Compare}\LP #1\code{,}\LS #2 \RS \code{,} \LS #3 \RS\RP}
 \newcommand{\CBINOP}[3]{#1 #2 #3}
 \newcommand{\CBINOP}[3]{#1 #2 #3}
 \newcommand{\TRUE}{\key{True}}
 \newcommand{\TRUE}{\key{True}}
 \newcommand{\FALSE}{\key{False}}
 \newcommand{\FALSE}{\key{False}}
@@ -182,7 +186,6 @@
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\CREAD}{\key{(read)}}
 \newcommand{\CREAD}{\key{(read)}}
 \newcommand{\CNEG}[1]{\LP\key{-}~#1\RP}
 \newcommand{\CNEG}[1]{\LP\key{-}~#1\RP}
-\newcommand{\CPROGRAM}[2]{\LP\code{CProgram}~#1~#2\RP}
 \newcommand{\PROGRAMDEFSEXP}[3]{\code{(ProgramDefsExp}~#1~#2~#3\code{)}}
 \newcommand{\PROGRAMDEFSEXP}[3]{\code{(ProgramDefsExp}~#1~#2~#3\code{)}}
 \newcommand{\PROGRAMDEFS}[2]{\code{(ProgramDefs}~#1~#2\code{)}}
 \newcommand{\PROGRAMDEFS}[2]{\code{(ProgramDefs}~#1~#2\code{)}}
 \newcommand{\CADD}[2]{\LP\key{+}~#1~#2\RP}
 \newcommand{\CADD}[2]{\LP\key{+}~#1~#2\RP}
@@ -230,17 +233,21 @@
 \newcommand{\VALUEOF}[2]{\LP\key{ValueOf}~#1~#2\RP}
 \newcommand{\VALUEOF}[2]{\LP\key{ValueOf}~#1~#2\RP}
 
 
 \if\edition\racketEd
 \if\edition\racketEd
+\newcommand{\CASSIGN}[2]{#1~\key{=}~#2\key{;}}
 \newcommand{\ASSIGN}[2]{\key{(Assign}~#1~#2\key{)}}
 \newcommand{\ASSIGN}[2]{\key{(Assign}~#1~#2\key{)}}
 \newcommand{\IFSTMT}[3]{\key{(IfStmt}\,#1~#2~#3\key{)}}
 \newcommand{\IFSTMT}[3]{\key{(IfStmt}\,#1~#2~#3\key{)}}
+\newcommand{\RETURN}[1]{\key{(Return}~#1\key{)}}
+\newcommand{\GOTO}[1]{\key{(Goto}~#1\key{)}}
 \fi
 \fi
 \if\edition\pythonEd
 \if\edition\pythonEd
+\newcommand{\CASSIGN}[2]{#1~\key{=}~#2}
 \newcommand{\ASSIGN}[2]{\key{Assign}\LP\LS #1\RS\key{,}#2\RP}
 \newcommand{\ASSIGN}[2]{\key{Assign}\LP\LS #1\RS\key{,}#2\RP}
 \newcommand{\IFSTMT}[3]{\key{If}\LP #1 \code{,} #2 \code{,} #3 \RP}
 \newcommand{\IFSTMT}[3]{\key{If}\LP #1 \code{,} #2 \code{,} #3 \RP}
+\newcommand{\RETURN}[1]{\key{Return}\LP #1 \RP}
+\newcommand{\GOTO}[1]{\key{Goto}\LP #1 \RP}
 \fi
 \fi
 
 
-\newcommand{\RETURN}[1]{\key{(Return}~#1\key{)}}
 \newcommand{\SEQ}[2]{\key{(Seq}~#1~#2\key{)}}
 \newcommand{\SEQ}[2]{\key{(Seq}~#1~#2\key{)}}
-\newcommand{\GOTO}[1]{\key{(Goto}~#1\key{)}}
 
 
 \if\edition\racketEd
 \if\edition\racketEd
 \newcommand{\IMM}[1]{\key{(Imm}~#1\key{)}}
 \newcommand{\IMM}[1]{\key{(Imm}~#1\key{)}}
@@ -252,6 +259,7 @@
 \newcommand{\PUSHQ}[1]{\key{(Pushq}~#1\key{)}}
 \newcommand{\PUSHQ}[1]{\key{(Pushq}~#1\key{)}}
 \newcommand{\POPQ}[1]{\key{(Popq}~#1\key{)}}
 \newcommand{\POPQ}[1]{\key{(Popq}~#1\key{)}}
 \newcommand{\JMP}[1]{\key{(Jmp}~#1\key{)}}
 \newcommand{\JMP}[1]{\key{(Jmp}~#1\key{)}}
+\newcommand{\JMPIF}[2]{\key{(JmpIf}~#1~#2\key{)}}
 \newcommand{\RETQ}{\key{(Retq)}}
 \newcommand{\RETQ}{\key{(Retq)}}
 \newcommand{\XPROGRAM}[2]{\LP\code{X86Program}~#1~#2\RP}
 \newcommand{\XPROGRAM}[2]{\LP\code{X86Program}~#1~#2\RP}
 \fi
 \fi
@@ -265,6 +273,7 @@
 \newcommand{\PUSHQ}[1]{\key{Pushq}\LP #1 \RP}
 \newcommand{\PUSHQ}[1]{\key{Pushq}\LP #1 \RP}
 \newcommand{\POPQ}[1]{\key{Popq}\LP #1 \RP}
 \newcommand{\POPQ}[1]{\key{Popq}\LP #1 \RP}
 \newcommand{\JMP}[1]{\key{Jump}\LP #1 \RP}
 \newcommand{\JMP}[1]{\key{Jump}\LP #1 \RP}
+\newcommand{\JMPIF}[2]{\key{JumpIf}\LP #1 \key{,} #2 \RP}
 \newcommand{\RETQ}{\key{Retq}\LP\RP}
 \newcommand{\RETQ}{\key{Retq}\LP\RP}
 % TODO: change \XPROGRAM to 1 parameter
 % TODO: change \XPROGRAM to 1 parameter
 \newcommand{\XPROGRAM}[2]{\code{X86Program}\LP #1 \RP}
 \newcommand{\XPROGRAM}[2]{\code{X86Program}\LP #1 \RP}
@@ -282,7 +291,6 @@
 \newcommand{\STACKLOC}[1]{(\key{stack}~#1)}
 \newcommand{\STACKLOC}[1]{(\key{stack}~#1)}
 \newcommand{\INDCALLQ}[2]{\key{(IndirectCallq}~#1~#2\key{)}}
 \newcommand{\INDCALLQ}[2]{\key{(IndirectCallq}~#1~#2\key{)}}
 \newcommand{\TAILJMP}[2]{\key{(TailJmp}~#1~#2\key{)}}
 \newcommand{\TAILJMP}[2]{\key{(TailJmp}~#1~#2\key{)}}
-\newcommand{\JMPIF}[2]{\key{(JmpIf}~#1~#2\key{)}}