Jelajahi Sumber

explanation regarding r11

Jeremy Siek 4 tahun lalu
induk
melakukan
a4abb7fa99
2 mengubah file dengan 199 tambahan dan 138 penghapusan
  1. 196 138
      book.tex
  2. 3 0
      defs.tex

+ 196 - 138
book.tex

@@ -1260,9 +1260,9 @@ Figure~\ref{fig:x86-0-concrete} defines the concrete syntax for the subset of
 the x86 assembly language needed for this chapter, which we call x86$_0$.
 %
 An x86 program begins with a \code{main} label followed by a sequence
-of instructions.  In the grammar, the superscript $+$ is used to
-indicate a sequence of one or more items, e.g., $\Instr^{+}$ is a
-sequence of instructions.
+of instructions.  In the grammar, elipses such as $\ldots$ are used to
+indicate a sequence of items, e.g., $\Instr \ldots$ is a sequence of
+instructions.
 %
 An x86 program is stored in the computer's memory and the computer has
 a \emph{program counter} that points to the address of the next
@@ -1311,7 +1311,7 @@ the x86 instructions used in this book.
       \key{pushq}\;\Arg \mid \key{popq}\;\Arg \mid \key{retq} \mid \key{jmp}\,\itm{label} \\
   && \itm{label}\key{:}\; \Instr \\
 x86_0 &::= & \key{.globl main}\\
-      &    & \key{main:} \; \Instr^{+}
+      &    & \key{main:} \; \Instr\ldots
 \end{array}
 \]
 \end{minipage}
@@ -1520,8 +1520,8 @@ the $\itm{info}$ field should just contain an empty list.
        \mid \UNIINSTR{\code{'negq}}{\Arg}\\
        &\mid& \CALLQ{\itm{label}} \mid \RETQ{} 
        \mid \PUSHQ{\Arg} \mid \POPQ{\Arg} \mid \JMP{\itm{label}} \\
-\Block &::= & \BLOCK{\itm{info}}{\Instr^{+}} \\
-x86_0 &::= & \PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label} \,\key{.}\, \Block \key{)}^{+}}}
+\Block &::= & \BLOCK{\itm{info}}{\Instr\ldots} \\
+x86_0 &::= & \PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label} \,\key{.}\, \Block \key{)}\ldots}}
 \end{array}
 \]
 \end{minipage}
@@ -1755,7 +1755,7 @@ assignment.
 \Exp &::=& \Atm \mid \key{(read)} \mid \key{(-}~\Atm\key{)} \mid \key{(+}~\Atm~\Atm\key{)}\\
 \Stmt &::=& \Var~\key{=}~\Exp\key{;} \\
 \Tail &::= & \key{return}~\Exp\key{;} \mid \Stmt~\Tail \\
-C_0 & ::= & (\itm{label}\key{:}~ \Tail)^{+}
+C_0 & ::= & (\itm{label}\key{:}~ \Tail)\ldots
 \end{array}
 \]
 \end{minipage}
@@ -1774,7 +1774,7 @@ C_0 & ::= & (\itm{label}\key{:}~ \Tail)^{+}
  &\mid& \ADD{\Atm}{\Atm}\\
 \Stmt &::=& \ASSIGN{\VAR{\Var}}{\Exp} \\
 \Tail &::= & \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail} \\
-C_0 & ::= & \PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label}\,\key{.}\,\Tail\key{)}^{+}}}
+C_0 & ::= & \PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label}\,\key{.}\,\Tail\key{)}\ldots}}
 \end{array}
 \]
 \end{minipage}
@@ -4111,7 +4111,7 @@ the first argument:
      \mid \key{j}cc~\itm{label}
      \\
 x86_1 &::= & \gray{ \key{.globl main} }\\
-      &    & \gray{ \key{main:} \; \Instr^{+} }
+      &    & \gray{ \key{main:} \; \Instr\ldots }
 \end{array}
 \]
 \end{minipage}
@@ -4142,8 +4142,8 @@ x86_1 &::= & \gray{ \key{.globl main} }\\
        &\mid& \BININSTR{\code{'set}}{\itm{cc}}{\Arg} 
        \mid \BININSTR{\code{'movzbq}}{\Arg}{\Arg}\\
        &\mid&  \JMPIF{\itm{cc}}{\itm{label}} \\
-\Block &::= & \gray{\BLOCK{\itm{info}}{\Instr^{+}}} \\
-x86_1 &::= & \gray{\PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label} \,\key{.}\, \Block \key{)}^{+}}}}
+\Block &::= & \gray{\BLOCK{\itm{info}}{\Instr\ldots}} \\
+x86_1 &::= & \gray{\PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label} \,\key{.}\, \Block \key{)}\ldots}}}
 \end{array}
 \]
 \end{minipage}
@@ -4220,7 +4220,7 @@ and \key{goto}'s.
 \Tail &::= & \gray{ \key{return}~\Exp\key{;} \mid \Stmt~\Tail } 
    \mid \key{goto}~\itm{label}\key{;}\\
    &\mid& \key{if}~\LP \itm{cmp}~\Atm~\Atm \RP~ \key{goto}~\itm{label}\key{;} ~\key{else}~\key{goto}~\itm{label}\key{;} \\
-C_1 & ::= & \gray{ (\itm{label}\key{:}~ \Tail)^{+} }
+C_1 & ::= & \gray{ (\itm{label}\key{:}~ \Tail)\ldots }
 \end{array}
 \]
 \end{minipage}
@@ -4245,7 +4245,7 @@ C_1 & ::= & \gray{ (\itm{label}\key{:}~ \Tail)^{+} }
 \Tail &::= & \gray{\RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail} } 
     \mid \GOTO{\itm{label}} \\
     &\mid& \IFSTMT{\BINOP{\itm{cmp}}{\Atm}{\Atm}}{\GOTO{\itm{label}}}{\GOTO{\itm{label}}} \\
-C_1 & ::= & \gray{\PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label}\,\key{.}\,\Tail\key{)}^{+}}}}
+C_1 & ::= & \gray{\PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label}\,\key{.}\,\Tail\key{)}\ldots}}}
 \end{array}
 \]
 \end{minipage}
@@ -5122,7 +5122,7 @@ of the \key{if} is taken.  The element at index $0$ of \code{t} is
 \[
 \begin{array}{lcl}
   \Type &::=& \gray{\key{Integer} \mid \key{Boolean}}
-  \mid (\key{Vector}\;\Type^{+}) \mid \key{Void}\\
+  \mid (\key{Vector}\;\Type\ldots) \mid \key{Void}\\
   \Exp &::=& \gray{  \Int \mid (\key{read}) \mid (\key{-}\;\Exp) \mid (\key{+} \; \Exp\;\Exp) \mid (\key{-}\;\Exp\;\Exp) }  \\
   &\mid&  \gray{  \Var \mid (\key{let}~([\Var~\Exp])~\Exp)  }\\
   &\mid& \gray{ \key{\#t} \mid \key{\#f} 
@@ -5131,7 +5131,7 @@ of the \key{if} is taken.  The element at index $0$ of \code{t} is
    \mid (\key{not}\;\Exp) } \\
   &\mid& \gray{  (\itm{cmp}\;\Exp\;\Exp) 
    \mid (\key{if}~\Exp~\Exp~\Exp)  } \\
-  &\mid& (\key{vector}\;\Exp^{+}) 
+  &\mid& (\key{vector}\;\Exp\ldots) 
    \mid (\key{vector-ref}\;\Exp\;\Int) \\
   &\mid& (\key{vector-set!}\;\Exp\;\Int\;\Exp)\\
   &\mid& (\key{void}) \mid (\key{has-type}~\Exp~\Type)\\
@@ -5658,7 +5658,7 @@ of the \code{vector} form.
   \Exp &::=& \cdots
       \mid (\key{collect} \,\itm{int})
       \mid (\key{allocate} \,\itm{int}\,\itm{type})
-      \mid (\key{global} \,\itm{name})
+      \mid (\key{global-value} \,\itm{name})
 \end{array}
 \]
 The $(\key{collect}\,n)$ form runs the garbage collector, requesting
@@ -5667,7 +5667,7 @@ $n$ bytes. It will become a call to the \code{collect} function in
 $(\key{allocate}\,n\,T)$ form creates an tuple of $n$ elements.  The
 $T$ parameter is the type of the tuple: \code{(Vector $\Type_1 \ldots
   \Type_n$)} where $\Type_i$ is the type of the $i$th element in the
-tuple. The $(\key{global}\,\itm{name})$ form reads the value of
+tuple. The $(\key{global-value}\,\itm{name})$ form reads the value of
 a global variable, such as \code{free\_ptr}.
 
 In the following, we show the transformation for the \code{vector}
@@ -5681,8 +5681,8 @@ vector, which is 8 for the tag plus \itm{len} times 8.
   (has-type (vector |$e_0 \ldots e_{n-1}$|) |\itm{type}|)
 |$\Longrightarrow$|
   (let ([|$x_0$| |$e_0$|]) ... (let ([|$x_{n-1}$| |$e_{n-1}$|])
-  (let ([_ (if (< (+ (global free_ptr) |\itm{bytes}|)
-                  (global fromspace_end))
+  (let ([_ (if (< (+ (global-value free_ptr) |\itm{bytes}|)
+                  (global-value fromspace_end))
                (void)
                (collect |\itm{bytes}|))])
   (let ([|$v$| (allocate |\itm{len}| |\itm{type}|)])
@@ -5708,7 +5708,7 @@ Figure~\ref{fig:expose-alloc-output} shows the output of the
   (let ([vecinit7976
          (let ([vecinit7972 42])
            (let ([collectret7974
-                  (if (< (+ (global free_ptr) 16) (global fromspace_end))
+                  (if (< (+ (global-value free_ptr) 16) (global-value fromspace_end))
                       (void)
                       (collect 16)
                       )])
@@ -5720,7 +5720,7 @@ Figure~\ref{fig:expose-alloc-output} shows the output of the
            )
          ])
     (let ([collectret7978
-           (if (< (+ (global free_ptr) 16) (global fromspace_end))
+           (if (< (+ (global-value free_ptr) 16) (global-value fromspace_end))
                (void)
                (collect 16)
                )])
@@ -5742,7 +5742,7 @@ Figure~\ref{fig:expose-alloc-output} shows the output of the
 \section{Remove Complex Operands}
 \label{sec:remove-complex-opera-R2}
 
-The new forms \code{collect}, \code{allocate}, and \code{global}
+The new forms \code{collect}, \code{allocate}, and \code{global-value}
 should all be treated as complex operands. A new case for
 \code{HasType} is needed and the case for \code{Prim} needs to be
 handled carefully to prevent the \code{Prim} node from being separated
@@ -5764,12 +5764,12 @@ from its enclosing \code{HasType}.
   &\mid& \gray{ \LP \key{not}~\Atm \RP \mid \LP \itm{cmp}~\Atm~\Atm\RP } \\
 &\mid& \LP \key{allocate}~\Int~\Type \RP \\
   &\mid& (\key{vector-ref}\;\Atm\;\Int) \mid (\key{vector-set!}\;\Atm\;\Int\;\Atm)\\
-  &\mid& \LP \key{global}~\Var \RP \mid \LP \key{void} \RP \\
+  &\mid& \LP \key{global-value}~\Var \RP \mid \LP \key{void} \RP \\
 \Stmt &::=& \gray{ \Var~\key{=}~\Exp\key{;} } \mid \LP\key{collect}~\Int \RP\\
 \Tail &::= & \gray{ \key{return}~\Exp\key{;} \mid \Stmt~\Tail } 
    \mid \gray{ \key{goto}~\itm{label}\key{;} }\\
    &\mid& \gray{ \key{if}~\LP \itm{cmp}~\Atm~\Atm \RP~ \key{goto}~\itm{label}\key{;} ~\key{else}~\key{goto}~\itm{label}\key{;} } \\
-C_2 & ::= & \gray{ (\itm{label}\key{:}~ \Tail)^{+} }
+C_2 & ::= & \gray{ (\itm{label}\key{:}~ \Tail)\ldots }
 \end{array}
 \]
 \end{minipage}
@@ -5798,7 +5798,7 @@ C_2 & ::= & \gray{ (\itm{label}\key{:}~ \Tail)^{+} }
 \Tail &::= & \gray{ \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail} 
        \mid \GOTO{\itm{label}} } \\
       &\mid& \gray{ \IFSTMT{\BINOP{\itm{cmp}}{\Atm}{\Atm}}{\GOTO{\itm{label}}}{\GOTO{\itm{label}}}  }\\
-C_2 & ::= & \gray{ \PROGRAM{\itm{info}}{\CFG{(\itm{label}\,\key{.}\,\Tail)^{+}}} }
+C_2 & ::= & \gray{ \PROGRAM{\itm{info}}{\CFG{(\itm{label}\,\key{.}\,\Tail)\ldots}} }
 \end{array}
 \]
 \end{minipage}
@@ -5813,7 +5813,7 @@ intermediate language $C_2$, whose concrete syntax is defined in
 Figure~\ref{fig:c2-concrete-syntax} and whose abstract syntax is
 defined in Figure~\ref{fig:c2-syntax}.  The new forms of $C_2$ include
 the \key{allocate}, \key{vector-ref}, and \key{vector-set!}, and
-\key{global} expressions and the \code{collect} statement.  The
+\key{global-value} expressions and the \code{collect} statement.  The
 \code{explicate-control} pass can treat these new forms much like the
 other forms.
 
@@ -5855,9 +5855,9 @@ block89:
     alloc7971 = (allocate 1 (Vector Integer));
     initret7973 = (vector-set! alloc7971 0 vecinit7972);
     vecinit7976 = alloc7971;
-    tmp7982 = (global free_ptr);
+    tmp7982 = (global-value free_ptr);
     tmp7983 = (+ tmp7982 16);
-    tmp7984 = (global fromspace_end);
+    tmp7984 = (global-value fromspace_end);
     if (< tmp7983 tmp7984) then
        goto block87;
     else
@@ -5875,9 +5875,9 @@ block86:
     return (vector-ref tmp7985 0);
 start:
     vecinit7972 = 42;
-    tmp7979 = (global free_ptr);
+    tmp7979 = (global-value free_ptr);
     tmp7980 = (+ tmp7979 16);
-    tmp7981 = (global fromspace_end);
+    tmp7981 = (global-value fromspace_end);
     if (< tmp7980 tmp7981) then
        goto block90;
     else
@@ -5907,26 +5907,45 @@ the later has a different concrete syntax (see
 Figures~\ref{fig:x86-2-concrete} and \ref{fig:x86-2}).
 
 The \code{vector-ref} and \code{vector-set!} forms translate into
-\code{movq} instructions with the appropriate \key{deref}.  (The
-plus one is to get past the tag at the beginning of the tuple
-representation.)
+\code{movq} instructions.  (The plus one in the offset is to get past
+the tag at the beginning of the tuple representation.)
 \begin{lstlisting}
-   |$\itm{lhs}$| = (vector-ref |$\itm{vec}$| |$n$|);
-   |$\Longrightarrow$|
-   movq |$\itm{vec}'$|, %r11
-   movq |$-8(n+1)$|(%r11), |$\itm{lhs}$|
+|$\itm{lhs}$| = (vector-ref |$\itm{vec}$| |$n$|);
+|$\Longrightarrow$|
+movq |$\itm{vec}'$|, %r11
+movq |$-8(n+1)$|(%r11), |$\itm{lhs}$|
 
-   |$\itm{lhs}$| = (vector-set! |$\itm{vec}$| |$n$| |$\itm{arg}$|);
-   |$\Longrightarrow$|
-   movq |$\itm{vec}'$|, %r11
-   movq |$\itm{arg}'$|, |$8(n+1)$|(%r11)
-   movq $0, |$\itm{lhs}$|
+|$\itm{lhs}$| = (vector-set! |$\itm{vec}$| |$n$| |$\itm{arg}$|);
+|$\Longrightarrow$|
+movq |$\itm{vec}'$|, %r11
+movq |$\itm{arg}'$|, |$8(n+1)$|(%r11)
+movq $0, |$\itm{lhs}$|
 \end{lstlisting}
 The $\itm{vec}'$ and $\itm{arg}'$ are obtained by translating
 $\itm{vec}$ and $\itm{arg}$ to x86.  The move of $\itm{vec}'$ to
-register \code{r11} ensures that offsets are only performed with
-register operands. This requires removing \code{r11} from
-consideration by the register allocating.
+register \code{r11} ensures that offset expression
+\code{$-8(n+1)$(\%r11)} contains a register operand.  This requires
+removing \code{r11} from consideration by the register allocating.
+
+Why not use \code{rax} instead of \code{r11}? Suppose we instead used
+\code{rax}. Then the generated code for \code{vector-set!} would be
+\begin{lstlisting}
+movq |$\itm{vec}'$|, %rax
+movq |$\itm{arg}'$|, |$8(n+1)$|(%rax)
+movq $0, |$\itm{lhs}$|
+\end{lstlisting}
+Next, suppose that $\itm{arg}'$ ends up as a stack location, so
+\code{patch-instructions} would insert a move through \code{rax}
+as follows.
+\begin{lstlisting}
+movq |$\itm{vec}'$|, %rax
+movq |$\itm{arg}'$|, %rax
+movq %rax, |$8(n+1)$|(%rax)
+movq $0, |$\itm{lhs}$|
+\end{lstlisting}
+But the above sequence of instructions does not work because we're
+trying to use \code{rax} for two different values ($\itm{vec}'$ and
+$\itm{arg}'$) at the same time!
 
 We compile the \code{allocate} form to operations on the
 \code{free\_ptr}, as shown below. The address in the \code{free\_ptr}
@@ -5936,9 +5955,9 @@ allocated, which is $8(\itm{len}+1)$ bytes because each element is 8
 bytes (64 bits) and we use 8 bytes for the tag. Last but not least, we
 initialize the \itm{tag}. Refer to Figure~\ref{fig:tuple-rep} to see
 how the tag is organized. We recommend using the Racket operations
-\code{bitwise-ior} and \code{arithmetic-shift} to compute the tag.
-The type annotation in the \code{vector} form is used to determine the
-pointer mask region of the tag.
+\code{bitwise-ior} and \code{arithmetic-shift} to compute the tag
+during compilation.  The type annotation in the \code{vector} form is
+used to determine the pointer mask region of the tag.
 \begin{lstlisting}
    |$\itm{lhs}$| = (allocate |$\itm{len}$| (Vector |$\itm{type} \ldots$|));
    |$\Longrightarrow$|
@@ -5949,11 +5968,11 @@ pointer mask region of the tag.
 \end{lstlisting}
 
 The \code{collect} form is compiled to a call to the \code{collect}
-function in the runtime. The arguments to \code{collect} are the top
-of the root stack and the number of bytes that need to be allocated.
-We shall use a dedicated register, \code{r15}, to store the pointer to
-the top of the root stack. So \code{r15} is not available for use by
-the register allocator.
+function in the runtime. The arguments to \code{collect} are 1) the
+top of the root stack and 2) the number of bytes that need to be
+allocated.  We shall use another dedicated register, \code{r15}, to
+store the pointer to the top of the root stack. So \code{r15} is not
+available for use by the register allocator.
 \begin{lstlisting}
    (collect |$\itm{bytes}$|)
    |$\Longrightarrow$|
@@ -5971,7 +5990,7 @@ the register allocator.
 \begin{array}{lcl}
   \Arg &::=& \gray{ \key{\$}\Int \mid \key{\%}\Reg \mid \Int\key{(}\key{\%}\Reg\key{)} \mid \key{\%}\itm{bytereg} } \mid \Var \key{(\%rip)} \\
 x86_1 &::= & \gray{ \key{.globl main} }\\
-      &    & \gray{ \key{main:} \; \Instr^{+} }
+      &    & \gray{ \key{main:} \; \Instr\ldots }
 \end{array}
 \]
 \end{minipage}
@@ -5989,7 +6008,7 @@ x86_1 &::= & \gray{ \key{.globl main} }\\
   \Arg &::=&  \gray{  \INT{\Int} \mid \REG{\Reg} \mid \DEREF{\Reg}{\Int}
    \mid \BYTEREG{\Reg}} \\
    &\mid& (\key{Global}~\Var) \\
-x86_2 &::= & \gray{ \PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label} \,\key{.}\, \Block \key{)}^{+}}} }
+x86_2 &::= & \gray{ \PROGRAM{\itm{info}}{\CFG{\key{(}\itm{label} \,\key{.}\, \Block \key{)}\ldots}} }
 \end{array}
 \]
 \end{minipage}
@@ -6440,25 +6459,31 @@ from the set.
 \chapter{Functions}
 \label{ch:functions}
 
-This chapter studies the compilation of functions at the level of
-abstraction of the C language. This corresponds to a subset of Typed
-Racket in which only top-level function definitions are allowed. These
-kind of functions are an important stepping stone to implementing
+This chapter studies the compilation of functions similar to those of
+the C language. This corresponds to a subset of Typed Racket in which
+only top-level function definitions are allowed. These kind of
+functions are an important stepping stone to implementing
 lexically-scoped functions in the form of \key{lambda} abstractions,
 which is the topic of Chapter~\ref{ch:lambdas}.
 
 \section{The $R_4$ Language}
 
-The syntax for function definitions and function application is shown
-in Figure~\ref{fig:r4-syntax}, where we define the $R_4$ language.
-Programs in $R_4$ start with zero or more function definitions.  The
-function names from these definitions are in-scope for the entire
-program, including all other function definitions (so the ordering of
-function definitions does not matter). The syntax for function
-application does not include an explicit keyword, which is error prone
-when using \code{match}. To alleviate this problem, we change the
-syntax from $(\Exp \; \Exp^{*})$ to $(\key{app}\; \Exp \; \Exp^{*})$
-during type checking.
+The concrete and abstract syntax for function definitions and function
+application is shown in Figures~\ref{fig:r4-concrete-syntax} and
+\ref{fig:r4-syntax}, where we define the $R_4$ language.  Programs in
+$R_4$ begin with zero or more function definitions.  The function
+names from these definitions are in-scope for the entire program,
+including all other function definitions (so the ordering of function
+definitions does not matter). The concrete syntax for function
+application is $(\Exp \; \Exp \ldots)$ where the first expression must
+evaluate to a function and the rest are the arguments.
+The abstract syntax for function application is
+$\APPLY{\Exp}{\Exp\ldots}$.
+
+%% The syntax for function application does not include an explicit
+%% keyword, which is error prone when using \code{match}. To alleviate
+%% this problem, we translate the syntax from $(\Exp \; \Exp \ldots)$ to
+%% $(\key{app}\; \Exp \; \Exp \ldots)$ during type checking.
 
 Functions are first-class in the sense that a function pointer is data
 and can be stored in memory or passed as a parameter to another
@@ -6477,11 +6502,12 @@ inside each other.
 \begin{figure}[tp]
 \centering
 \fbox{
-\begin{minipage}{0.96\textwidth}
+  \begin{minipage}{0.96\textwidth}
+    \small
 \[
 \begin{array}{lcl}
   \Type &::=& \gray{ \key{Integer} \mid \key{Boolean}
-         \mid (\key{Vector}\;\Type^{+}) \mid \key{Void}  } \mid (\Type^{*} \; \key{->}\; \Type) \\
+         \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 (\key{read}) \mid (\key{-}\;\Exp) \mid (\key{+} \; \Exp\;\Exp) \mid (\key{-}\;\Exp\;\Exp)}  \\
     &\mid&  \gray{ \Var \mid \LET{\Var}{\Exp}{\Exp} }\\
@@ -6490,48 +6516,81 @@ inside each other.
     \mid (\key{or}\;\Exp\;\Exp)
     \mid (\key{not}\;\Exp)} \\
    &\mid& \gray{(\itm{cmp}\;\Exp\;\Exp) \mid \IF{\Exp}{\Exp}{\Exp}} \\
-  &\mid& \gray{(\key{vector}\;\Exp^{+}) \mid
+  &\mid& \gray{(\key{vector}\;\Exp\ldots) \mid
     (\key{vector-ref}\;\Exp\;\Int)} \\
-  &\mid& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\mid (\key{void})} \\
-      &\mid& (\Exp \; \Exp^{*}) \\
-  \Def &::=& (\key{define}\; (\Var \; [\Var \key{:} \Type]^{*}) \key{:} \Type \; \Exp) \\
-  R_4 &::=& (\key{program} \;\itm{info}\; \Def^{*} \; \Exp)
+  &\mid& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\mid (\key{void})
+      \mid (\key{has-type}~\Exp~\Type)} \\
+      &\mid& (\Exp \; \Exp \ldots) \\
+  \Def &::=& (\key{define}\; (\Var \; [\Var \key{:} \Type] \ldots) \key{:} \Type \; \Exp) \\
+  R_4 &::=& \Def \ldots \; \Exp
+\end{array}
+\]
+\end{minipage}
+}
+\caption{The concrete syntax of $R_4$, extending $R_3$ (Figure~\ref{fig:r3-concrete-syntax}).}
+\label{fig:r4-concrete-syntax}
+\end{figure}
+
+\begin{figure}[tp]
+\centering
+\fbox{
+  \begin{minipage}{0.96\textwidth}
+    \small
+\[
+\begin{array}{lcl}
+\Exp &::=& \gray{ \INT{\Int} \mid \READ{} \mid \NEG{\Exp} } \\
+     &\mid& \gray{ \ADD{\Exp}{\Exp} 
+      \mid \BINOP{\code{'-}}{\Exp}{\Exp} } \\
+     &\mid& \gray{ \VAR{\Var} \mid \LET{\Var}{\Exp}{\Exp} } \\
+     &\mid& \gray{ \BOOL{\itm{bool}} 
+      \mid \AND{\Exp}{\Exp} }\\
+     &\mid& \gray{ \OR{\Exp}{\Exp}
+      \mid \NOT{\Exp} } \\
+     &\mid& \gray{ \BINOP{\itm{cmp}}{\Exp}{\Exp}
+      \mid \IF{\Exp}{\Exp}{\Exp} } \\
+     &\mid& \gray{ \VECTOR{\Exp} } \\
+     &\mid& \gray{ \VECREF{\Exp}{\Int} }\\
+     &\mid& \gray{ \VECSET{\Exp}{\Int}{\Exp}} \\
+     &\mid& \gray{ \VOID{} \mid \LP\key{HasType}~\Exp~\Type \RP } \\
+     &\mid& \APPLY{\Exp}{\Exp\ldots}\\
+ \Def &::=& \FUNDEF{\Var}{[\Var \code{:} \Type]\ldots}{\Type}{\code{'()}}{\Exp}\\
+  R_4 &::=& \PROGRAMDEFS{\code{'()}}{\Def\ldots}{\Exp}
 \end{array}
 \]
 \end{minipage}
 }
-\caption{Syntax of $R_4$, extending $R_3$ (Figure~\ref{fig:r3-syntax})
-  with functions.}
+\caption{The abstract syntax of $R_4$, extending $R_3$ (Figure~\ref{fig:r3-syntax}).}
 \label{fig:r4-syntax}
 \end{figure}
 
+
 The program in Figure~\ref{fig:r4-function-example} is a
 representative example of defining and using functions in $R_4$.  We
 define a function \code{map-vec} that applies some other function
-\code{f} to both elements of a vector (a 2-tuple) and returns a new
-vector containing the results. We also define a function \code{add1}
-that does what its name suggests. The program then applies
+\code{f} to both elements of a vector and returns a new
+vector containing the results. We also define a function \code{add1}.
+The program applies
 \code{map-vec} to \code{add1} and \code{(vector 0 41)}.  The result is
 \code{(vector 1 42)}, from which we return the \code{42}.
 
 \begin{figure}[tbp]
 \begin{lstlisting}
-(program ()
-  (define (map-vec [f : (Integer -> Integer)]
-                     [v : (Vector Integer Integer)])
-          : (Vector Integer Integer)
-    (vector (f (vector-ref v 0)) (f (vector-ref v 1))))
-  (define (add1 [x : Integer]) : Integer
-    (+ x 1))
-  (vector-ref (map-vec add1 (vector 0 41)) 1)
-  )
+(define (map-vec [f : (Integer -> Integer)]
+                   [v : (Vector Integer Integer)])
+        : (Vector Integer Integer)
+  (vector (f (vector-ref v 0)) (f (vector-ref v 1))))
+
+(define (add1 [x : Integer]) : Integer
+  (+ x 1))
+
+(vector-ref (map-vec add1 (vector 0 41)) 1)
 \end{lstlisting}
 \caption{Example of using functions in $R_4$.}
 \label{fig:r4-function-example}
 \end{figure}
 
 The definitional interpreter for $R_4$ is in
-Figure~\ref{fig:interp-R4}. The case for the \code{program} form is
+Figure~\ref{fig:interp-R4}. The case for the \code{ProgramDefs} form is
 responsible for setting up the mutual recursion between the top-level
 function definitions. We use the classic back-patching approach that
 uses mutable variables and makes two passes over the function
@@ -6540,7 +6599,7 @@ top-level environment using a mutable cons cell for each function
 definition. Note that the \code{lambda} value for each function is
 incomplete; it does not yet include the environment.  Once the
 top-level environment is constructed, we then iterate over it and
-update the \code{lambda} value's to use the top-level environment.
+update the \code{lambda} values to use the top-level environment.
 
 \begin{figure}[tp]
 \begin{lstlisting}
@@ -6549,26 +6608,25 @@ update the \code{lambda} value's to use the top-level environment.
     (define recur (interp-exp env))
     (match e
       ...
-      [`(,fun ,args ...)
-       (define arg-vals (for/list ([e args]) (recur e)))
+      [(Apply fun args)
        (define fun-val (recur fun))
+       (define arg-vals (for/list ([e args]) (recur e)))
        (match fun-val
 	 [`(lambda (,xs ...) ,body ,fun-env)
 	  (define new-env (append (map cons xs arg-vals) fun-env))
-	  ((interp-exp new-env) body)]
-	 [else (error "interp-exp, expected function, not" fun-val)])]
-      [else (error 'interp-exp "unrecognized expression")]
+	  ((interp-exp new-env) body)])]
+      ...
       )))
 
 (define (interp-def d)
   (match d
-    [`(define (,f [,xs : ,ps] ...) : ,rt ,body)
+    [(Def f (list `[,xs : ,ps] ...) rt _ body)
      (mcons f `(lambda ,xs ,body ()))]
     ))
 
 (define (interp-R4 p)
   (match p
-    [`(program ,ds ... ,body)
+    [(ProgramDefs info ds body)
      (let ([top-level (for/list ([d ds]) (interp-def d))])
        (for/list ([b top-level])
          (set-mcdr! b (match (mcdr b)
@@ -6607,8 +6665,8 @@ In Section~\ref{sec:x86} we saw the use of the \code{callq}
 instruction for jumping to a function whose location is given by a
 label. Here we instead will be jumping to a function whose location is
 given by an address, that is, we need to make an \emph{indirect
-  function call}. The x86 syntax is to give the register name prefixed
-with an asterisk.
+  function call}. The x86 syntax for this is a \code{callq}
+instruction but with an asterisk before the register name.
 \begin{lstlisting}
    callq *%rbx
 \end{lstlisting}
@@ -6624,8 +6682,8 @@ coordination between the caller and the callee, which is often
 assembly code written by different programmers or generated by
 different compilers. As a result, people have developed
 \emph{conventions} that govern how functions calls are performed.
-Here we shall use the same conventions used by the \code{gcc}
-compiler~\citep{Matz:2013aa}.
+Here we shall use conventions that are compatible with those used by
+the \code{gcc} compiler~\citep{Matz:2013aa}.
 
 Regarding (1) parameter passing, the convention is to use the
 following six registers: \code{rdi}, \code{rsi}, \code{rdx},
@@ -6643,7 +6701,7 @@ 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. 
+below the stack pointer.
 
 Regarding (3) the sharing of registers between different functions,
 recall from Section~\ref{sec:calling-conventions} that the registers
@@ -6839,18 +6897,18 @@ Figure~\ref{fig:f1-syntax}.
 \[
 \begin{array}{lcl}
   \Type &::=& \gray{ \key{Integer} \mid \key{Boolean}
-         \mid (\key{Vector}\;\Type^{+}) \mid \key{Void}  \mid (\Type^{*} \; \key{->}\; \Type)} \\
+         \mid (\key{Vector}\;\Type \ldots) \mid \key{Void}  \mid (\Type \ldots \; \key{->}\; \Type)} \\
   \Exp &::=& \gray{ \Int \mid (\key{read}) \mid (\key{-}\;\Exp) \mid (\key{+} \; \Exp\;\Exp)}  \\
      &\mid&  \gray{ \Var \mid \LET{\Var}{\Exp}{\Exp} }\\
   &\mid& \gray{ \key{\#t} \mid \key{\#f} \mid
       (\key{not}\;\Exp)} \mid \gray{(\itm{cmp}\;\Exp\;\Exp) \mid \IF{\Exp}{\Exp}{\Exp}} \\
-  &\mid& \gray{(\key{vector}\;\Exp^{+}) \mid
+  &\mid& \gray{(\key{vector}\;\Exp \ldots) \mid
     (\key{vector-ref}\;\Exp\;\Int)} \\
   &\mid& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\mid (\key{void}) \mid
-         (\key{app}\; \Exp \; \Exp^{*})} \\
+         (\key{app}\; \Exp \; \Exp \ldots)} \\
       &\mid& (\key{fun-ref}\, \itm{label}) \\
-  \Def &::=& \gray{(\key{define}\; (\itm{label} \; [\Var \key{:} \Type]^{*}) \key{:} \Type \; \Exp)} \\
-  F_1 &::=& \gray{(\key{program}\;\itm{info} \; \Def^{*})}
+  \Def &::=& \gray{(\key{define}\; (\itm{label} \; [\Var \key{:} \Type] \ldots) \key{:} \Type \; \Exp)} \\
+  F_1 &::=& \gray{(\key{program}\;\itm{info} \; \Def \ldots)}
 \end{array}
 \]
 \end{minipage}
@@ -6942,16 +7000,16 @@ the function definitions.
       \mid (\key{not}\;\Arg) \mid (\itm{cmp}\;\Arg\;\Arg)  } \\
    &\mid& \gray{  (\key{allocate}\,\Int\,\Type)
    \mid (\key{vector-ref}\, \Arg\, \Int)  } \\
-   &\mid& \gray{  (\key{vector-set!}\,\Arg\,\Int\,\Arg) \mid (\key{global} \,\itm{name}) \mid (\key{void}) } \\
-   &\mid& (\key{fun-ref}\,\itm{label}) \mid (\key{call} \,\Arg\,\Arg^{*}) \\
+   &\mid& \gray{  (\key{vector-set!}\,\Arg\,\Int\,\Arg) \mid (\key{global-value} \,\itm{name}) \mid (\key{void}) } \\
+   &\mid& (\key{fun-ref}\,\itm{label}) \mid (\key{call} \,\Arg\,\Arg\ldots) \\
 \Stmt &::=& \gray{ \ASSIGN{\Var}{\Exp} \mid \RETURN{\Exp} 
        \mid (\key{collect} \,\itm{int}) }\\
 \Tail &::= & \gray{\RETURN{\Exp} \mid (\key{seq}\;\Stmt\;\Tail)} \\
       &\mid& \gray{(\key{goto}\,\itm{label})
        \mid \IF{(\itm{cmp}\, \Arg\,\Arg)}{(\key{goto}\,\itm{label})}{(\key{goto}\,\itm{label})}} \\
-      &\mid& (\key{tailcall} \,\Arg\,\Arg^{*}) \\
-  \Def &::=& (\key{define}\; (\itm{label} \; [\Var \key{:} \Type]^{*}) \key{:} \Type \; ((\itm{label}\,\key{.}\,\Tail)^{+})) \\
-C_3 & ::= & (\key{program}\;\itm{info}\;\Def^{*})
+      &\mid& (\key{tailcall} \,\Arg\,\Arg\ldots) \\
+  \Def &::=& (\key{define}\; (\itm{label} \; [\Var \key{:} \Type]\ldots) \key{:} \Type \; ((\itm{label}\,\key{.}\,\Tail)\ldots)) \\
+C_3 & ::= & (\key{program}\;\itm{info}\;\Def\ldots)
 \end{array}
 \]
 \end{minipage}
@@ -7001,9 +7059,9 @@ language, whose syntax is defined in Figure~\ref{fig:x86-3}.
        \mid (\key{label} \; \itm{label})  } \\
      &\mid& (\key{indirect-callq}\;\Arg ) \mid (\key{tail-jmp}\;\Arg) \\
      &\mid& (\key{leaq}\;\Arg\;\Arg)\\
-\Block &::= & \gray{(\key{block} \;\itm{info}\; \Instr^{+})} \\
-\Def &::= & (\key{define} \; (\itm{label}) \;\itm{info}\; ((\itm{label} \,\key{.}\, \Block)^{+}))\\
-x86_3 &::= & (\key{program} \;\itm{info} \;\Def^{*})
+\Block &::= & \gray{(\key{block} \;\itm{info}\; \Instr\ldots)} \\
+\Def &::= & (\key{define} \; (\itm{label}) \;\itm{info}\; ((\itm{label} \,\key{.}\, \Block)\ldots))\\
+x86_3 &::= & (\key{program} \;\itm{info} \;\Def\ldots)
 \end{array}
 \]
 \end{minipage}
@@ -7305,7 +7363,7 @@ of your previously created test programs.
 
 \node (x86-2) at (3,-4)  {\large $\text{x86}^{*}_3$};
 \node (x86-3) at (6,-4)  {\large $\text{x86}^{*}_3$};
-\node (x86-4) at (9,-4) {\large $\text{x86}^{*}_3$};
+\node (x86-4) at (9,-4) {\large $\text{x86}_3$};
 \node (x86-5) at (9,-6) {\large $\text{x86}^{\dagger}_3$};
 
 \node (x86-2-1) at (3,-6)  {\large $\text{x86}^{*}_3$};
@@ -7406,8 +7464,8 @@ $R_3$).
 \[
 \begin{array}{lcl}
   \Type &::=& \gray{\key{Integer} \mid \key{Boolean}
-     \mid (\key{Vector}\;\Type^{+}) \mid \key{Void}
-     \mid (\Type^{*} \; \key{->}\; \Type)} \\
+     \mid (\key{Vector}\;\Type\ldots) \mid \key{Void}
+     \mid (\Type\ldots \; \key{->}\; \Type)} \\
   \Exp &::=& \gray{\Int \mid (\key{read}) \mid (\key{-}\;\Exp)
      \mid (\key{+} \; \Exp\;\Exp) \mid (\key{-} \; \Exp\;\Exp)}  \\
     &\mid&  \gray{\Var \mid \LET{\Var}{\Exp}{\Exp}}\\
@@ -7416,13 +7474,13 @@ $R_3$).
      \mid (\key{or}\;\Exp\;\Exp) 
      \mid (\key{not}\;\Exp) } \\
     &\mid& \gray{(\key{eq?}\;\Exp\;\Exp) \mid \IF{\Exp}{\Exp}{\Exp}} \\
-    &\mid& \gray{(\key{vector}\;\Exp^{+}) \mid
+    &\mid& \gray{(\key{vector}\;\Exp\ldots) \mid
           (\key{vector-ref}\;\Exp\;\Int)} \\
     &\mid& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\mid (\key{void})} \\
-    &\mid& \gray{(\Exp \; \Exp^{*})} \\
-    &\mid& (\key{lambda:}\; ([\Var \key{:} \Type]^{*}) \key{:} \Type \; \Exp) \\
-  \Def &::=& \gray{(\key{define}\; (\Var \; [\Var \key{:} \Type]^{*}) \key{:} \Type \; \Exp)} \\
-  R_5 &::=& \gray{(\key{program} \; \Def^{*} \; \Exp)}
+    &\mid& \gray{(\Exp \; \Exp\ldots)} \\
+    &\mid& (\key{lambda:}\; ([\Var \key{:} \Type]\ldots) \key{:} \Type \; \Exp) \\
+  \Def &::=& \gray{(\key{define}\; (\Var \; [\Var \key{:} \Type]\ldots) \key{:} \Type \; \Exp)} \\
+  R_5 &::=& \gray{(\key{program} \; \Def\ldots \; \Exp)}
 \end{array}
 \]
 \end{minipage}
@@ -7815,14 +7873,14 @@ reference results in a run-time contract violation.
       \mid (\key{or}\;\Exp\;\Exp) 
       \mid (\key{not}\;\Exp) \\
      &\mid& (\itm{cmp}\;\Exp\;\Exp) \mid \IF{\Exp}{\Exp}{\Exp} \\
-     &\mid& (\key{vector}\;\Exp^{+}) \mid
+     &\mid& (\key{vector}\;\Exp\ldots) \mid
       (\key{vector-ref}\;\Exp\;\Exp) \\
      &\mid& (\key{vector-set!}\;\Exp\;\Exp\;\Exp) \mid (\key{void}) \\
-     &\mid& (\Exp \; \Exp^{*}) \mid (\key{lambda}\; (\Var^{*}) \; \Exp) \\
+     &\mid& (\Exp \; \Exp\ldots) \mid (\key{lambda}\; (\Var\ldots) \; \Exp) \\
      & \mid & (\key{boolean?}\;\Exp) \mid (\key{integer?}\;\Exp)\\
      & \mid & (\key{vector?}\;\Exp) \mid (\key{procedure?}\;\Exp) \mid (\key{void?}\;\Exp) \\
-  \Def &::=& (\key{define}\; (\Var \; \Var^{*}) \; \Exp) \\
-R_7  &::=& (\key{program} \; \Def^{*}\; \Exp)
+  \Def &::=& (\key{define}\; (\Var \; \Var\ldots) \; \Exp) \\
+R_7  &::=& (\key{program} \; \Def\ldots\; \Exp)
 \end{array}
 \]
 \end{minipage}
@@ -7972,10 +8030,10 @@ extend our compiler to handle the new features of $R_6$
 \[
 \begin{array}{lcl}
   \Type &::=& \gray{\key{Integer} \mid \key{Boolean}
-     \mid (\key{Vector}\;\Type^{+}) \mid (\key{Vectorof}\;\Type) \mid \key{Void}} \\
-    &\mid& \gray{(\Type^{*} \; \key{->}\; \Type)} \mid \key{Any} \\
-  \FType &::=& \key{Integer} \mid \key{Boolean} \mid \key{Void} \mid (\key{Vectorof}\;\key{Any}) \mid (\key{Vector}\; \key{Any}^{*}) \\
-    &\mid& (\key{Any}^{*} \; \key{->}\; \key{Any})\\
+     \mid (\key{Vector}\;\Type\ldots) \mid (\key{Vectorof}\;\Type) \mid \key{Void}} \\
+    &\mid& \gray{(\Type\ldots \; \key{->}\; \Type)} \mid \key{Any} \\
+  \FType &::=& \key{Integer} \mid \key{Boolean} \mid \key{Void} \mid (\key{Vectorof}\;\key{Any}) \mid (\key{Vector}\; \key{Any}\ldots) \\
+    &\mid& (\key{Any}\ldots \; \key{->}\; \key{Any})\\
   \itm{cmp} &::= & \key{eq?} \mid \key{<} \mid \key{<=} \mid \key{>} \mid \key{>=} \\
   \Exp &::=& \gray{\Int \mid (\key{read}) \mid (\key{-}\;\Exp)
      \mid (\key{+} \; \Exp\;\Exp) \mid (\key{-} \; \Exp\;\Exp)}  \\
@@ -7985,16 +8043,16 @@ extend our compiler to handle the new features of $R_6$
      \mid (\key{or}\;\Exp\;\Exp) 
      \mid (\key{not}\;\Exp)} \\
     &\mid& \gray{(\itm{cmp}\;\Exp\;\Exp) \mid \IF{\Exp}{\Exp}{\Exp}} \\
-    &\mid& \gray{(\key{vector}\;\Exp^{+}) \mid
+    &\mid& \gray{(\key{vector}\;\Exp\ldots) \mid
           (\key{vector-ref}\;\Exp\;\Int)} \\
     &\mid& \gray{(\key{vector-set!}\;\Exp\;\Int\;\Exp)\mid (\key{void})} \\
-    &\mid& \gray{(\Exp \; \Exp^{*})
-    \mid (\key{lambda:}\; ([\Var \key{:} \Type]^{*}) \key{:} \Type \; \Exp)} \\
+    &\mid& \gray{(\Exp \; \Exp\ldots)
+    \mid (\key{lambda:}\; ([\Var \key{:} \Type]\ldots) \key{:} \Type \; \Exp)} \\
   & \mid & (\key{inject}\; \Exp \; \FType) \mid (\key{project}\;\Exp\;\FType) \\
   & \mid & (\key{boolean?}\;\Exp) \mid (\key{integer?}\;\Exp)\\
   & \mid & (\key{vector?}\;\Exp) \mid (\key{procedure?}\;\Exp) \mid (\key{void?}\;\Exp) \\
-  \Def &::=& \gray{(\key{define}\; (\Var \; [\Var \key{:} \Type]^{*}) \key{:} \Type \; \Exp)} \\
-  R_6 &::=& \gray{(\key{program} \; \Def^{*} \; \Exp)}
+  \Def &::=& \gray{(\key{define}\; (\Var \; [\Var \key{:} \Type]\ldots) \key{:} \Type \; \Exp)} \\
+  R_6 &::=& \gray{(\key{program} \; \Def\ldots \; \Exp)}
 \end{array}
 \]
 \end{minipage}

+ 3 - 0
defs.tex

@@ -28,6 +28,7 @@
 \newcommand{\READ}{\key{(Prim}\;\code{'read}\;\key{'())}}
 \newcommand{\NEG}[1]{\key{(Prim}\;\code{'-}\;\code{(list}\;#1\;\code{))}}
 \newcommand{\PROGRAM}[2]{\code{(Program}\;#1\;#2\code{)}}
+\newcommand{\PROGRAMDEFS}[3]{\code{(ProgramDefs}~#1~#2~#3\code{)}}
 \newcommand{\ADD}[2]{\key{(Prim}\;\code{'+}\;\code{(list}\;#1\;#2\code{))}}
 \newcommand{\AND}[2]{\key{(Prim}\;\code{'and}\;\code{(list}\;#1\;#2\code{))}}
 \newcommand{\OR}[2]{\key{(Prim}\;\code{'or}\;\code{(list}\;#1\;#2\code{))}}
@@ -41,6 +42,8 @@
 \newcommand{\VECREF}[2]{\key{(Prim}\;\code{'vector-ref}\;\code{(list}\;#1\;#2\code{))}}
 \newcommand{\VECSET}[3]{\key{(Prim}\;\code{'vector-set}\;\code{(list}\;#1\;#2\;#3\code{))}}
 \newcommand{\VOID}[1]{\key{(Void)}}
+\newcommand{\APPLY}[2]{\key{(Apply}\;#1\;#2\code{)}}
+\newcommand{\FUNDEF}[5]{\key{(Def}~#1~#2~#3~#4~#5\code{)}}
 
 \newcommand{\ASSIGN}[2]{\key{(Assign}~#1\;#2\key{)}}
 \newcommand{\RETURN}[1]{\key{(Return}~#1\key{)}}