|
@@ -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}
|