Răsfoiți Sursa

progress on Ch 5

Jeremy Siek 4 ani în urmă
părinte
comite
15a2633e7a
2 a modificat fișierele cu 177 adăugiri și 204 ștergeri
  1. 173 204
      book.tex
  2. 4 0
      defs.tex

+ 173 - 204
book.tex

@@ -1658,7 +1658,7 @@ each of the compiler passes in Figure~\ref{fig:R1-passes}.
 The output of \key{explicate-control} is similar to the $C$
 language~\citep{Kernighan:1988nx} in that it has separate syntactic
 categories for expressions and statements, so we name it $C_0$.  The
-concrete syntax for $C_0$ is define din
+concrete syntax for $C_0$ is defined in
 Figure~\ref{fig:c0-concrete-syntax} and the abstract syntax for $C_0$
 is defined in Figure~\ref{fig:c0-syntax}.
 %
@@ -2055,25 +2055,6 @@ on the body of the \key{program} and then associate the \code{locals}
 symbol with the resulting list of variables in the $\itm{info}$ field,
 as in the above example.
 
-%% \section{Uncover Locals}
-%% \label{sec:uncover-locals-r1}
-
-%% The pass \code{uncover-locals} simply collects all of the variables in
-%% the program and places then in the $\itm{info}$ of the program
-%% construct. Here is the output for the example program of the last
-%% section.
-
-%% \begin{minipage}{0.4\textwidth}
-%% \begin{lstlisting}
-%% (program ((locals . (x.1 x.2 y)))
-%%   ((start . 
-%%    (seq (assign x.1 20)
-%%    (seq (assign x.2 22)
-%%    (seq (assign y (+ x.1 x.2))
-%%    (return y)))))))
-%% \end{lstlisting}
-%% \end{minipage}
-
 \section{Select Instructions}
 \label{sec:select-r1}
 
@@ -3750,22 +3731,6 @@ association list.
 \label{fig:type-check-R2}
 \end{figure}
 
-%% To print the resulting value correctly, the overall type of the
-%% program must be threaded through the remainder of the passes. We can
-%% store the type within the \key{program} form as shown in Figure
-%% \ref{fig:type-check-R2}. Let $R^\dagger_2$ be the name for the
-%% intermediate language produced by the type checker, which we define as
-%% follows: \\[1ex]
-%% \fbox{
-%% \begin{minipage}{0.87\textwidth}
-%% \[
-%% \begin{array}{lcl}
-%%   R^\dagger_2 &::=& (\key{program}\;(\key{type}\;\itm{type})\; \Exp)
-%% \end{array}
-%% \]
-%% \end{minipage}
-%% }
-
 \begin{exercise}\normalfont
 Complete the implementation of \code{type-check-R2} and test it on 10
 new example programs in $R_2$ that you choose based on how thoroughly
@@ -4125,7 +4090,8 @@ new kind of context to deal with: the predicate position of the
 \key{if}. We need another function, \code{explicate-pred}, that takes
 an $R_2$ expression and two pieces of $C_1$ code (two $\Tail$'s) for
 the then-branch and else-branch. The output of \code{explicate-pred}
-is a $C_1$ $\Tail$.  However, these three functions also need to
+is a $C_1$ $\Tail$ and a list of formerly \key{let}-bound variables.
+However, these three functions also need to
 construct the control-flow graph, which we recommend they do via
 updates to a global variable (be careful!). Next we consider the
 specific additions to the tail and assign functions, and some of cases
@@ -4134,30 +4100,29 @@ for the pred function.
 The \code{explicate-tail} function needs an additional case for
 \key{if}. The branches of the \key{if} inherit the current context, so
 they are in tail position.  Let $B_1$ be the result of
-\code{explicate-tail} on the $\itm{thn}$ branch and $B_2$ be the
-result of apply \code{explicate-tail} to the $\itm{else}$ branch. Then
-the \key{if} as a whole translates to the block $B_3$ which is the
-result of applying \code{explicate-pred} to the predicate $\itm{cnd}$
-and the blocks $B_1$ and $B_2$.
+\code{explicate-tail} on the ``then'' branch of the \key{if} and $B_2$
+be the result of apply \code{explicate-tail} to the ``else''
+branch. Then the \key{if} as a whole translates to the block $B_3$
+which is the result of applying \code{explicate-pred} to the predicate
+$\itm{cnd}$ and the blocks $B_1$ and $B_2$.
 \[
     (\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_3
 \]
 
-Next we consider the case for \key{if} in the
-\code{explicate-assign} function. The context of the
-\key{if} is an assignment to some variable $x$ and then the control
-continues to some block $B_1$.  The code that we generate for the
-$\itm{thn}$ and $\itm{els}$ branches needs to continue to
-$B_1$, so we add $B_1$ to the control flow graph with a fresh label
-$\ell_1$.  Again, the branches of the \key{if} inherit the current
-context, so that are in assignment positions.  Let $B_2$ be the result
-of applying \code{explicate-assign} to the $\itm{thn}$ branch,
-variable $x$, and the block \GOTO{$\ell_1$}.  Let $B_3$ be the
-result of applying \code{explicate-assign} to the $\itm{else}$
-branch, variable $x$, and the block \GOTO{$\ell_1$}. The
+Next we consider the case for \key{if} in the \code{explicate-assign}
+function. The context of the \key{if} is an assignment to some
+variable $x$ and then the control continues to some block $B_1$.  The
+code that we generate for the $\itm{thn}$ and $\itm{els}$ branches
+needs to continue to $B_1$, so we add $B_1$ to the control flow graph
+with a fresh label $\ell_1$.  Again, the branches of the \key{if}
+inherit the current context, so that are in assignment positions.  Let
+$B_2$ be the result of applying \code{explicate-assign} to the
+$\itm{thn}$ branch, variable $x$, and the block \GOTO{$\ell_1$}.  Let
+$B_3$ be the result of applying \code{explicate-assign} to the
+$\itm{else}$ branch, variable $x$, and the block \GOTO{$\ell_1$}. The
 \key{if} translates to the block $B_4$ which is the result of applying
-\code{explicate-pred} to the predicate $\itm{cnd}$ and the
-blocks $B_2$ and $B_3$.
+\code{explicate-pred} to the predicate $\itm{cnd}$ and the blocks
+$B_2$ and $B_3$.
 \[
 (\key{if}\; \itm{cnd}\; \itm{thn}\; \itm{els}) \quad\Rightarrow\quad B_4
 \]
@@ -4166,11 +4131,21 @@ The function \code{explicate-pred} will need a case for every
 expression that can have type \code{Boolean}. We detail a few cases
 here and leave the rest for the reader. The input to this function is
 an expression and two blocks, $B_1$ and $B_2$, for the branches of the
-enclosing \key{if}. One of the base cases of this function is when the
+enclosing \key{if}. Suppose the expression is the Boolean \code{\#t}.
+Then we can perform a kind of partial evaluation and translate it to the
+``then'' branch $B_1$. Likewise, we translate
+\code{\#f} to the ``else`` branch $B_2$.
+\[
+\key{\#t} \quad\Rightarrow\quad B_1,
+\qquad\qquad\qquad
+\key{\#f} \quad\Rightarrow\quad B_2
+\]
+Next, suppose the
 expression is a less-than comparison. We translate it to a conditional
 goto. We need labels for the two branches $B_1$ and $B_2$, so we add
-them to the control flow graph and obtain some labels $\ell_1$ and
-$\ell_2$. The translation of the less-than comparison is as follows.
+those blocks to the control flow graph and obtain some labels $\ell_1$
+and $\ell_2$. The translation of the less-than comparison is as
+follows.
 \[
 (\key{<}~e_1~e_2) \quad\Rightarrow\quad
 \begin{array}{l}
@@ -4201,10 +4176,10 @@ B_5
 \]
 
 \begin{exercise}\normalfont
-  Implement the pass \code{explicate-code} by adding the cases for
+  Implement the pass \code{explicate-control} by adding the cases for
   \key{if} to the functions for tail and assignment contexts, and
-  implement the function for predicate contexts. Create test cases
-  that exercise all of the new cases in the code for this pass.
+  implement \code{explicate-pred} for predicate contexts. Create test
+  cases that exercise all of the new cases in the code for this pass.
 \end{exercise}
 
 
@@ -4383,52 +4358,6 @@ and test your compiler using your previously created programs on the
 \end{exercise}
 
 
-%% \section{Lower Conditionals (New Pass)}
-%% \label{sec:lower-conditionals}
-
-%% In the \code{select-instructions} pass we decided to procrastinate in
-%% the lowering of the \key{if} statement, thereby making liveness
-%% analysis easier. Now we need to make up for that and turn the \key{if}
-%% statement into the appropriate instruction sequence.  The following
-%% translation gives the general idea. If the condition is true, we need
-%% to execute the $\itm{thns}$ branch and otherwise we need to execute
-%% the $\itm{elss}$ branch. So we use \key{cmpq} and do a conditional
-%% jump to the $\itm{thenlabel}$, choosing the condition code $cc$ that
-%% is appropriate for the comparison operator \itm{cmp}.  If the
-%% condition is false, we fall through to the $\itm{elss}$ branch. At the
-%% end of the $\itm{elss}$ branch we need to take care to not fall
-%% through to the $\itm{thns}$ branch. So we jump to the
-%% $\itm{endlabel}$. All of the labels in the generated code should be
-%% created with \code{gensym}.
-
-%% \begin{tabular}{lll}
-%% \begin{minipage}{0.4\textwidth}
-%% \begin{lstlisting}
-%%  (if (|\itm{cmp}| |$\Arg_1$| |$\Arg_2$|) |$\itm{thns}$| |$\itm{elss}$|)
-%% \end{lstlisting}
-%% \end{minipage}
-%% &
-%% $\Rightarrow$
-%% &
-%% \begin{minipage}{0.4\textwidth}
-%% \begin{lstlisting}
-%%  (cmpq |$\Arg_2$| |$\Arg_1$|)
-%%  (jmp-if |$cc$| |$\itm{thenlabel}$|)
-%%  |$\itm{elss}$|
-%%  (jmp |$\itm{endlabel}$|)
-%%  (label |$\itm{thenlabel}$|)
-%%  |$\itm{thns}$|
-%%  (label |$\itm{endlabel}$|)
-%% \end{lstlisting}
-%% \end{minipage}
-%% \end{tabular}
-
-%% \begin{exercise}\normalfont
-%% Implement the \code{lower-conditionals} pass. Test your compiler using
-%% your previously created programs on the \code{interp-x86} interpreter
-%% (Appendix~\ref{appendix:interp}).
-%% \end{exercise}
-
 \section{Patch Instructions}
 
 The second argument of the \key{cmpq} instruction must not be an
@@ -4542,7 +4471,7 @@ conclusion:
 \node (R2-4) at (9,2)  {\large $R_2$};
 \node (R2-5) at (12,2)  {\large $R_2$};
 \node (C1-1) at (6,0)  {\large $C_1$};
-\node (C1-2) at (3,0)  {\large $C_1$};
+%\node (C1-2) at (3,0)  {\large $C_1$};
 
 \node (x86-2) at (3,-2)  {\large $\text{x86}^{*}$};
 \node (x86-3) at (6,-2)  {\large $\text{x86}^{*}$};
@@ -4557,8 +4486,8 @@ conclusion:
 \path[->,bend left=15] (R2-3) edge [above] node {\ttfamily\footnotesize uniquify} (R2-4);
 \path[->,bend left=15] (R2-4) edge [above] node {\ttfamily\footnotesize remove-complex.} (R2-5);
 \path[->,bend left=15] (R2-5) edge [right] node {\ttfamily\footnotesize\color{red} explicate-control} (C1-1);
-\path[->,bend right=15] (C1-1) edge [above] node {\ttfamily\footnotesize uncover-locals} (C1-2);
-\path[->,bend right=15] (C1-2) edge [left] node {\ttfamily\footnotesize\color{red} select-instr.} (x86-2);
+%\path[->,bend right=15] (C1-1) edge [above] node {\ttfamily\footnotesize uncover-locals} (C1-2);
+\path[->,bend right=15] (C1-1) edge [left] node {\ttfamily\footnotesize\color{red} select-instructions} (x86-2);
 \path[->,bend left=15] (x86-2) edge [right] node {\ttfamily\footnotesize\color{red} uncover-live} (x86-2-1);
 \path[->,bend right=15] (x86-2-1) edge [below] node {\ttfamily\footnotesize build-inter.} (x86-2-2);
 \path[->,bend right=15] (x86-2-2) edge [right] node {\ttfamily\footnotesize allocate-reg.} (x86-3);
@@ -4804,9 +4733,10 @@ program in Figure~\ref{fig:vector-eg} shows the usage of tuples in
 Racket. We create a 3-tuple \code{t} and a 1-tuple. The 1-tuple is
 stored at index $2$ of the 3-tuple, demonstrating that tuples are
 first-class values.  The element at index $1$ of \code{t} is
-\code{\#t}, so the ``then'' branch is taken.  The element at index $0$
-of \code{t} is $40$, to which we add the $2$, the element at index $0$
-of the 1-tuple.
+\code{\#t}, so the ``then'' branch of the \key{if} is taken.  The
+element at index $0$ of \code{t} is $40$, to which we add $2$, the
+element at index $0$ of the 1-tuple. So the result of the program is
+$42$.
 
 \begin{figure}[tbp]
 \begin{lstlisting}
@@ -4869,6 +4799,10 @@ of the 1-tuple.
       \mid \NOT{\Exp} } \\
      &\mid& \gray{ \BINOP{\code{'}\itm{cmp}}{\Exp}{\Exp}
       \mid \IF{\Exp}{\Exp}{\Exp} } \\
+     &\mid& \VECTOR{\Exp} \\
+     &\mid& \VECREF{\Exp}{\Int}\\
+     &\mid& \VECSET{\Exp}{\Int}{\Exp}\\
+      &\mid& \VOID{} \\
   R_3 &::=& \PROGRAM{\key{'()}}{\Exp}
 \end{array}
 \]
@@ -4887,12 +4821,16 @@ be \emph{aliases} for the same thing. Consider the following example
 in which both \code{t1} and \code{t2} refer to the same tuple.  Thus,
 the mutation through \code{t2} is visible when referencing the tuple
 from \code{t1}, so the result of this program is \code{42}.
+\begin{center}
+\begin{minipage}{0.96\textwidth}
 \begin{lstlisting}
     (let ([t1 (vector 3 7)])
       (let ([t2 t1])
         (let ([_ (vector-set! t2 0 42)])
           (vector-ref t1 0))))
 \end{lstlisting}
+\end{minipage}
+\end{center}
 
 The next issue concerns the lifetime of tuples. Of course, they are
 created by the \code{vector} form, but when does their lifetime end?
@@ -4901,12 +4839,17 @@ an operation for deleting tuples. Furthermore, the lifetime of a tuple
 is not tied to any notion of static scoping. For example, the
 following program returns \code{3} even though the variable \code{t}
 goes out of scope prior to accessing the vector.
+\begin{center}
+\begin{minipage}{0.96\textwidth}
 \begin{lstlisting}
     (vector-ref
       (let ([t (vector 3 7)])
         t)
       0)
 \end{lstlisting}
+\end{minipage}
+\end{center}
+
 From the perspective of programmer-observable behavior, tuples live
 forever. Of course, if they really lived forever, then many programs
 would run out of memory.\footnote{The $R_3$ language does not have
@@ -4926,20 +4869,6 @@ in $R_3$. In contrast, Racket defines the \code{void?} predicate that
 returns \code{\#t} when applied to \code{\#<void>} and \code{\#f}
 otherwise.
 
-Figure~\ref{fig:typecheck-R3} shows the type checker for $R_3$ , which
-deserves some explanation. As we shall see in Section~\ref{sec:GC}, we
-need to know which variables are pointers into the heap, that is,
-which variables are vectors. Also, when allocating a vector, we shall
-need to know which elements of the vector are pointers. We can obtain
-this information during type checking and when we uncover local
-variables. The type checker in Figure~\ref{fig:typecheck-R3} not only
-computes the type of an expression, it also wraps every sub-expression
-$e$ with the form $(\key{has-type}\; e\; T)$, where $T$ is $e$'s
-type. Subsequently, in the \code{uncover-locals} pass
-(Section~\ref{sec:uncover-locals-r3}) this type information is
-propagated to all variables (including the temporaries generated by
-\code{remove-complex-opera*}).
-
 \begin{figure}[tbp]
 \begin{lstlisting}
     (define primitives (set ... 'vector 'vector-ref 'vector-set!))
@@ -4963,6 +4892,21 @@ propagated to all variables (including the temporaries generated by
 \label{fig:interp-R3}
 \end{figure}
 
+Figure~\ref{fig:typecheck-R3} shows the type checker for $R_3$, which
+deserves some explanation. As we shall see in Section~\ref{sec:GC}, we
+need to know which variables are pointers into the heap, that is,
+which variables are vectors. Also, when allocating a vector, we need
+to know which elements of the vector are pointers. We can obtain this
+information during type checking. The type checker in
+Figure~\ref{fig:typecheck-R3} not only computes the type of an
+expression, it also wraps every sub-expression $e$ with the form
+$(\key{HasType}~e~T)$, where $T$ is $e$'s type.
+% TODO: UPDATE? -Jeremy
+Subsequently, in the \code{uncover-locals} pass
+(Section~\ref{sec:uncover-locals-r3}) this type information is
+propagated to all variables (including the temporaries generated by
+\code{remove-complex-opera*}).
+
 \begin{figure}[tbp]
 \begin{lstlisting}
 (define (type-check-exp env)
@@ -4970,30 +4914,30 @@ propagated to all variables (including the temporaries generated by
     (define recur (type-check-exp env))
     (match e
       ...
-      ['(void) (values '(has-type (void) Void) 'Void)]
-      [`(vector ,es ...)
+      [(Void) (values (HasType (Void) 'Void) 'Void)]
+      [(Prim 'vector es)
        (define-values (e* t*) (for/lists (e* t*) ([e es])
                                 (recur e)))
        (let ([t `(Vector ,@t*)])
-         (debug "vector/type-check-exp finished vector" t)
-         (values `(has-type (vector ,@e*) ,t) t))]
-      [`(vector-ref ,e ,i)
+         (values (HasType (Prim 'vector e*) t) t))]
+      [(Prim 'vector-ref (list e (Int i)))
        (define-values (e^ t) (recur e))
        (match t
          [`(Vector ,ts ...)
           (unless (and (exact-nonnegative-integer? i) (< i (length ts)))
             (error 'type-check-exp "invalid index ~a" i))
           (let ([t (list-ref ts i)])
-            (values `(has-type (vector-ref ,e^ (has-type ,i Integer)) ,t) 
-                    t))]
+            (values
+             (HasType (Prim 'vector-ref (list e^ (HasType (Int i) 'Integer))) t)
+             t))]
          [else (error "expected a vector in vector-ref, not" t)])]
-      [`(eq? ,arg1 ,arg2)
-       (define-values (e1 t1) (recur arg1))
-       (define-values (e2 t2) (recur arg2))
-       (match* (t1 t2)
-         [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))
-          (values `(has-type (eq? ,e1 ,e2) Boolean) 'Boolean)]
-         [(other wise) ((super type-check-exp env) e)])]
+      [(Prim 'eq? (list e1 e2))
+       (define-values (e1^ T1) (recur e1))
+       (define-values (e2^ T2) (recur e2))
+       (unless (equal? T1 T2)
+         (error "arguments of eq? must have the same type, but are not"
+                (list T1 T2)))
+       (values (HasType (Prim 'eq? (list e1^ e2^)) 'Boolean) 'Boolean)]
       ...
       )))
 \end{lstlisting}
@@ -5298,7 +5242,7 @@ accesses the element in the inner tuple tuple via two vector
 references.
 % tests/s2_17.rkt
 \begin{lstlisting}
-    (vector-ref (vector-ref (vector (vector 42)) 0) 0))
+(vector-ref (vector-ref (vector (vector 42)) 0) 0))
 \end{lstlisting}
 
 Next we proceed to discuss the new \code{expose-allocation} pass.
@@ -5365,34 +5309,40 @@ Figure~\ref{fig:expose-alloc-output} shows the output of the
 \code{expose-allocation} pass on our running example.
 
 \begin{figure}[tbp]
+% tests/s2_17.rkt
 \begin{lstlisting}
-(program ()
+(vector-ref
  (vector-ref
-  (vector-ref
-   (let ((vecinit48
-          (let ((vecinit44 42))
-            (let ((collectret46
-                   (if (<
-                        (+ (global-value free_ptr) 16)
-                        (global-value fromspace_end))
-                     (void)
-                     (collect 16))))
-              (let ((alloc43 (allocate 1 (Vector Integer))))
-                (let ((initret45 (vector-set! alloc43 0 vecinit44)))
-                  alloc43))))))
-     (let ((collectret50
-            (if (< (+ (global-value free_ptr) 16)
-                   (global-value fromspace_end))
-              (void)
-              (collect 16))))
-       (let ((alloc47 (allocate 1 (Vector (Vector Integer)))))
-         (let ((initret49 (vector-set! alloc47 0 vecinit48)))
-           alloc47))))
-   0)
-  0))
+  (let ([vecinit7976
+         (let ([vecinit7972 42])
+           (let ([collectret7974
+                  (if (< (+ free_ptr 16) fromspace_end)
+                      (void)
+                      (collect 16);
+                      )])
+             (let ([alloc7971 (allocate 1 (Vector Integer))])
+               (let ([initret7973 (vector-set! alloc7971 0 vecinit7972)])
+                 alloc7971)
+               )
+             )
+           )
+         ])
+    (let ([collectret7978
+           (if (< (+ free_ptr 16) fromspace_end)
+               (void)
+               (collect 16);
+               )])
+      (let ([alloc7975 (allocate 1 (Vector (Vector Integer)))])
+        (let ([initret7977 (vector-set! alloc7975 0 vecinit7976)])
+          alloc7975)
+        )
+      )
+    )
+  0)
+ 0)
 \end{lstlisting}
 \caption{Output of the \code{expose-allocation} pass, minus
-  all of the \code{has-type} forms.}
+  all of the \code{HasType} forms.}
 \label{fig:expose-alloc-output}
 \end{figure}
 
@@ -5442,47 +5392,66 @@ other forms.
 \section{Uncover Locals}
 \label{sec:uncover-locals-r3}
 
-Recall that the \code{uncover-locals} function collects all of the
+Recall that the \code{explicate-control} function collects all of the
 local variables so that it can store them in the $\itm{info}$ field of
-the \code{program} form. Also recall that we need to know the types of
-all the local variables for purposes of identifying the root set for
-the garbage collector.  Thus, we change \code{uncover-locals} to
-collect not just the variables, but the variables and their types in
-the form of an association list. Thanks to the \code{has-type} forms,
-the types are readily available. Figure~\ref{fig:uncover-locals-r3}
-lists the output of the \code{uncover-locals} pass on the running
-example.
+the \code{Program} structure. Also recall that we need to know the
+types of all the local variables for purposes of identifying the root
+set for the garbage collector.  Thus, we create a pass named
+\code{uncover-locals} to collect not just the variables but the
+variables and their types in the form of an association list. Thanks
+to the \code{HasType} nodes, the types are readily available in the
+AST. Figure~\ref{fig:uncover-locals-r3} lists the output of the
+\code{uncover-locals} pass on the running example.
 
 \begin{figure}[tbp]
+% tests/s2_17.rkt
 \begin{lstlisting}
-(program
- ((locals . ((tmp54 . Integer) (tmp51 . Integer) (tmp53 . Integer)
-             (alloc43 . (Vector Integer)) (tmp55 . Integer)
-             (initret45 . Void) (alloc47 . (Vector (Vector Integer)))
-             (collectret46 . Void) (vecinit48 . (Vector Integer))
-             (tmp52 . Integer) (tmp57 . (Vector Integer))
-             (vecinit44 . Integer) (tmp56 . Integer) (initret49 . Void)
-             (collectret50 . Void))))
- ((block63 . (seq (collect 16) (goto block61)))
-  (block62 . (seq (assign collectret46 (void)) (goto block61)))
-  (block61 . (seq (assign alloc43 (allocate 1 (Vector Integer)))
-               (seq (assign initret45 (vector-set! alloc43 0 vecinit44))
-               (seq (assign vecinit48 alloc43)
-               (seq (assign tmp54 (global-value free_ptr))
-               (seq (assign tmp55 (+ tmp54 16))
-               (seq (assign tmp56 (global-value fromspace_end))
-               (if (< tmp55 tmp56) (goto block59) (goto block60)))))))))
-  (block60 . (seq (collect 16) (goto block58)))
-  (block59 . (seq (assign collectret50 (void)) (goto block58)))
-  (block58 . (seq (assign alloc47 (allocate 1 (Vector (Vector Integer))))
-               (seq (assign initret49 (vector-set! alloc47 0 vecinit48))
-               (seq (assign tmp57 (vector-ref alloc47 0))
-               (return (vector-ref tmp57 0))))))
-  (start . (seq (assign vecinit44 42)
-           (seq (assign tmp51 (global-value free_ptr))
-           (seq (assign tmp52 (+ tmp51 16))
-           (seq (assign tmp53 (global-value fromspace_end))
-           (if (< tmp52 tmp53) (goto block62) (goto block63)))))))))
+program:
+locals:
+    vecinit7976 : '(Vector Integer), tmp7980 : 'Integer,
+    alloc7975 : '(Vector (Vector Integer)), tmp7983 : 'Integer,
+    collectret7974 : 'Void, initret7977 : 'Void,
+    collectret7978 : 'Void, tmp7985 : '(Vector Integer),
+    tmp7984 : 'Integer, tmp7979 : 'Integer, tmp7982 : 'Integer,
+    alloc7971 : '(Vector Integer), tmp7981 : 'Integer, vecinit7972 : 'Integer,
+    initret7973 : 'Void, 
+block7991:
+    (collect 16);
+    goto block7989;
+block7990:
+    collectret7974 = (void);
+    goto block7989;
+block7989:
+    alloc7971 = (allocate 1 (Vector Integer));
+    initret7973 = (vector-set! alloc7971 0 vecinit7972);
+    vecinit7976 = alloc7971;
+    tmp7982 = free_ptr;
+    tmp7983 = (+ tmp7982 16);
+    tmp7984 = fromspace_end;
+    if (< tmp7983 tmp7984) then
+       goto block7987;
+    else
+       goto block7988;
+block7988:
+    (collect 16);
+    goto block7986;
+block7987:
+    collectret7978 = (void);
+    goto block7986;
+block7986:
+    alloc7975 = (allocate 1 (Vector (Vector Integer)));
+    initret7977 = (vector-set! alloc7975 0 vecinit7976);
+    tmp7985 = (vector-ref alloc7975 0);
+    return (vector-ref tmp7985 0);
+start:
+    vecinit7972 = 42;
+    tmp7979 = free_ptr;
+    tmp7980 = (+ tmp7979 16);
+    tmp7981 = fromspace_end;
+    if (< tmp7980 tmp7981) then
+       goto block7990;
+    else
+       goto block7991;
 \end{lstlisting}
 \caption{Output of \code{uncover-locals} for the running example.}
 \label{fig:uncover-locals-r3}

+ 4 - 0
defs.tex

@@ -33,6 +33,10 @@
 \newcommand{\VAR}[1]{\key{(Var}\;#1\key{)}}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \newcommand{\IF}[3]{\key{(If}\,#1\;#2\;#3\key{)}}
+\newcommand{\VECTOR}[1]{\key{(Prim}\;\code{'vector}\;\code{(list}\;#1^{*}\code{))}}
+\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{\ASSIGN}[2]{\key{(Assign}~#1\;#2\key{)}}
 \newcommand{\RETURN}[1]{\key{(Return}~#1\key{)}}