handouts/ho07.tex
changeset 377 a052a83f562e
parent 376 af65ffff9cdd
child 383 a6a6bf32fade
equal deleted inserted replaced
376:af65ffff9cdd 377:a052a83f562e
   400 \noindent 
   400 \noindent 
   401 The generated code is as follows:
   401 The generated code is as follows:
   402 
   402 
   403 \begin{lstlisting}[mathescape,language={}]
   403 \begin{lstlisting}[mathescape,language={}]
   404    ldc 1
   404    ldc 1
   405    ldc 2
   405    ldc 1
   406    if_icmpne L_ifelse $\quad\tikz[remember picture] \node (C) {\mbox{}};$
   406    if_icmpne L_ifelse $\quad\tikz[remember picture] \node (C) {\mbox{}};$
   407    ldc 2
   407    ldc 2
   408    istore 0
   408    istore 0
   409    goto L_ifend $\quad\tikz[remember picture] \node (A) {\mbox{}};$
   409    goto L_ifend $\quad\tikz[remember picture] \node (A) {\mbox{}};$
   410 L_ifelse: $\quad\tikz[remember picture] \node[] (D) {\mbox{}};$
   410 L_ifelse: $\quad\tikz[remember picture] \node[] (D) {\mbox{}};$
   418            -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (B.east);
   418            -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (B.east);
   419   \draw[->,very thick] (C) edge [->,to path={-- ++(10mm,0mm) 
   419   \draw[->,very thick] (C) edge [->,to path={-- ++(10mm,0mm) 
   420            -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (D.east);
   420            -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (D.east);
   421 \end{tikzpicture}
   421 \end{tikzpicture}
   422 
   422 
   423 \noindent The first three lines correspond to the the boolean 
   423 \noindent The first three lines correspond to the the boolean
   424 expression $1 = 1$. The jump for when this boolean expression
   424 expression $1 = 1$. The jump for when this boolean expression
   425 is false is in Line~3. Lines 4-6 corresponds to the if-branch; 
   425 is false is in Line~3. Lines 4-6 corresponds to the if-branch;
   426 the else-branch is in Lines 8 and 9. Note carefully how the
   426 the else-branch is in Lines 8 and 9. Note carefully how the
   427 environment $E$ is threaded through the calls of 
   427 environment $E$ is threaded through the recursive calls of
   428 \textit{compile}. The function receives an environment $E$, 
   428 \textit{compile}. The function receives an environment $E$,
   429 but it might extend it when compiling the if-branch, yielding 
   429 but it might extend it when compiling the if-branch, yielding
   430 $E'$. This happens for example in the if-statement above 
   430 $E'$. This happens for example in the if-statement above
   431 whenever the variable \code{x} has not been used before. 
   431 whenever the variable \code{x} has not been used before.
   432 Similarly with the environment $E''$ for the second call
   432 Similarly with the environment $E''$ for the second call to
   433 to \textit{compile}. $E''$ is also the environment that need
   433 \textit{compile}. $E''$ is also the environment that needs to
   434 to be returned.
   434 be returned as part of the answer.
   435 
   435 
   436 The compilation of the while-loops, say 
   436 The compilation of the while-loops, say 
   437 \pcode{while} $b$ \pcode{do} $cs$, is very similar. In case
   437 \pcode{while} $b$ \pcode{do} $cs$, is very similar. In case
   438 the condition is true and we need to do another iteration, the 
   438 the condition is true and we need to do another iteration, 
   439 control-flow needs to be as follows
   439 and the control-flow needs to be as follows
   440 
   440 
   441 \begin{center}
   441 \begin{center}
   442 \begin{tikzpicture}[node distance=2mm and 4mm,
   442 \begin{tikzpicture}[node distance=2mm and 4mm,
   443  block/.style={rectangle, minimum size=1cm, draw=black, line width=1mm},
   443  block/.style={rectangle, minimum size=1cm, draw=black, line width=1mm},
   444  point/.style={rectangle, inner sep=0mm, minimum size=0mm, fill=red},
   444  point/.style={rectangle, inner sep=0mm, minimum size=0mm, fill=red},
   456 \draw (cs1) edge [->, black, line width=1mm] (A3);
   456 \draw (cs1) edge [->, black, line width=1mm] (A3);
   457 \draw (A3) edge [->,skip loop] (A1);
   457 \draw (A3) edge [->,skip loop] (A1);
   458 \end{tikzpicture}
   458 \end{tikzpicture}
   459 \end{center}
   459 \end{center}
   460 
   460 
   461 \noindent While if the condition is \emph{not} true we
   461 \noindent Whereas if the condition is \emph{not} true, we
   462 need to jump out of the loop, which gives the following
   462 need to jump out of the loop, which gives the following
   463 control flow.
   463 control flow.
   464 
   464 
   465 \begin{center}
   465 \begin{center}
   466 \begin{tikzpicture}[node distance=2mm and 4mm,
   466 \begin{tikzpicture}[node distance=2mm and 4mm,
   482 \end{tikzpicture}
   482 \end{tikzpicture}
   483 \end{center}
   483 \end{center}
   484 
   484 
   485 \noindent Again we can use the \textit{compile}-function for
   485 \noindent Again we can use the \textit{compile}-function for
   486 boolean expressions to insert the appropriate jump to the
   486 boolean expressions to insert the appropriate jump to the
   487 end of the loop (label $L_{wend}$).
   487 end of the loop (label $L_{wend}$ below).
   488 
   488 
   489 \begin{center}
   489 \begin{center}
   490 \begin{tabular}{lcl}
   490 \begin{tabular}{lcl}
   491 $\textit{compile}(\pcode{while}\; b\; \pcode{do} \;cs, E)$ & $\dn$\\ 
   491 $\textit{compile}(\pcode{while}\; b\; \pcode{do} \;cs, E)$ & $\dn$\\ 
   492 \multicolumn{3}{l}{$\qquad L_{wbegin}\;$ (fresh label)}\\
   492 \multicolumn{3}{l}{$\qquad L_{wbegin}\;$ (fresh label)}\\
   493 \multicolumn{3}{l}{$\qquad L_{wend}\;$ (fresh label)}\\
   493 \multicolumn{3}{l}{$\qquad L_{wend}\;$ (fresh label)}\\
   494 \multicolumn{3}{l}{$\qquad (is, E') = \textit{compile}(cs_1, E)$}\\
   494 \multicolumn{3}{l}{$\qquad (is, E') = \textit{compile}(cs_1, E)$}\\
   495 \multicolumn{3}{l}{$\qquad(L_{wbegin}:$}\\
   495 \multicolumn{3}{l}{$\qquad(L_{wbegin}:$}\\
   496 \multicolumn{3}{l}{$\qquad\phantom{(}@\;\textit{compile}(b, E, L_{wend})$}\\
   496 \multicolumn{3}{l}{$\qquad\phantom{(}@\;\textit{compile}(b, E, L_{wend})$}\\
   497 \multicolumn{3}{l}{$\qquad\phantom{(}@\;is$}\\
   497 \multicolumn{3}{l}{$\qquad\phantom{(}@\;is$}\\
   498 \multicolumn{3}{l}{$\qquad\phantom{(}@\; \text{goto}\;l_{wbegin}$}\\
   498 \multicolumn{3}{l}{$\qquad\phantom{(}@\; \text{goto}\;L_{wbegin}$}\\
   499 \multicolumn{3}{l}{$\qquad\phantom{(}@\;L_{wend}:, E')$}\\
   499 \multicolumn{3}{l}{$\qquad\phantom{(}@\;L_{wend}:, E')$}\\
   500 \end{tabular}
   500 \end{tabular}
   501 \end{center}
   501 \end{center}
   502 
   502 
       
   503 \noindent I let you go through how this clause works. As an example
       
   504 you can consider the while-loop
       
   505 
       
   506 \begin{lstlisting}[mathescape,numbers=none,language={}]
       
   507 while x <= 10 do x := x + 1
       
   508 \end{lstlisting}
       
   509 
       
   510 \noindent yielding the following code
       
   511 
       
   512 \begin{lstlisting}[mathescape,language={}]
       
   513 L_wbegin: $\quad\tikz[remember picture] \node[] (LB) {\mbox{}};$
       
   514    iload 0
       
   515    ldc 10
       
   516    if_icmpgt L_wend $\quad\tikz[remember picture] \node (LC) {\mbox{}};$
       
   517    iload 0
       
   518    ldc 1
       
   519    iadd
       
   520    istore 0
       
   521    goto L_wbegin $\quad\tikz[remember picture] \node (LA) {\mbox{}};$
       
   522 L_wend: $\quad\tikz[remember picture] \node[] (LD) {\mbox{}};$
       
   523 \end{lstlisting}
       
   524  
       
   525 \begin{tikzpicture}[remember picture,overlay]
       
   526   \draw[->,very thick] (LA) edge [->,to path={-- ++(10mm,0mm) 
       
   527            -- ++(0mm,17.3mm) |- (\tikztotarget)},line width=1mm] (LB.east);
       
   528   \draw[->,very thick] (LC) edge [->,to path={-- ++(10mm,0mm) 
       
   529            -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (LD.east);
       
   530 \end{tikzpicture}
       
   531 
       
   532 
   503 Next we need to consider the statement \pcode{write x}, which
   533 Next we need to consider the statement \pcode{write x}, which
   504 can be used to write out the content of a variable. For this
   534 can be used to print out the content of a variable. For this
   505 we need to use a Java library function. In order to avoid
   535 we need to use a Java library function. In order to avoid
   506 having to generate a lot of code for each
   536 having to generate a lot of code for each
   507 \pcode{write}-command, we use a separate method and just call
   537 \pcode{write}-command, we use a separate helper-method and
   508 this method with an argument (which needs to be placed on the
   538 just call this method with an argument (which needs to be
   509 stack). The code is as follows.
   539 placed onto the stack). The code of the helper-method is as
       
   540 follows.
   510 
   541 
   511 
   542 
   512 \begin{lstlisting}[language=JVMIS]
   543 \begin{lstlisting}[language=JVMIS]
   513 .method public static write(I)V 
   544 .method public static write(I)V 
   514     .limit locals 1 
   545     .limit locals 1 
   531 \pcode{java/io/PrintStream}. A reference to this value will be
   562 \pcode{java/io/PrintStream}. A reference to this value will be
   532 placed on the stack. Line~5 copies the integer we want to
   563 placed on the stack. Line~5 copies the integer we want to
   533 print out onto the stack. In the next line we call the method
   564 print out onto the stack. In the next line we call the method
   534 \pcode{println} (from the class \pcode{java/io/PrintStream}).
   565 \pcode{println} (from the class \pcode{java/io/PrintStream}).
   535 We want to print out an integer and do not expect anything
   566 We want to print out an integer and do not expect anything
   536 back (that is why the type annotation \pcode{(I)V}). The
   567 back (that is why the type annotation is \pcode{(I)V}). The
   537 \pcode{return}-instruction in the next line changes the
   568 \pcode{return}-instruction in the next line changes the
   538 control-flow back to the place from where \pcode{write} was
   569 control-flow back to the place from where \pcode{write} was
   539 called. This method needs to be part of a header that is
   570 called. This method needs to be part of a header that is
   540 included in any code we generate. The method \pcode{write} can
   571 included in any code we generate. The helper-method
   541 be invoked with the two instructions
   572 \pcode{write} can be invoked with the two instructions
   542 
   573 
   543 \begin{lstlisting}[mathescape,language=JVMIS]
   574 \begin{lstlisting}[mathescape,language=JVMIS]
   544 iload $E(x)$ 
   575 iload $E(x)$ 
   545 invokestatic XXX/XXX/write(I)V
   576 invokestatic XXX/XXX/write(I)V
   546 \end{lstlisting}
   577 \end{lstlisting}
   547 
   578 
   548 \noindent where we first place the variable to be printed on
   579 \noindent where we first place the variable to be printed on
   549 the stack and then call \pcode{write}. The \pcode{XXX} need to
   580 top of the stack and then call \pcode{write}. The \pcode{XXX}
   550 be replaced by appropriate class name (this will be explained
   581 need to be replaced by an appropriate class name (this will be
   551 shortly).
   582 explained shortly).
   552 
   583 
   553 
   584 
   554 \begin{figure}[t]
   585 \begin{figure}[t]
   555 \begin{lstlisting}[mathescape,language=JVMIS]
   586 \begin{lstlisting}[mathescape,language=JVMIS]
   556 .class public XXX.XXX
   587 .class public XXX.XXX
   576 
   607 
   577 
   608 
   578 By generating code for a While-program, we end up with a list
   609 By generating code for a While-program, we end up with a list
   579 of (JVM assembly) instructions. Unfortunately, there is a bit
   610 of (JVM assembly) instructions. Unfortunately, there is a bit
   580 more boilerplate code needed before these instructions can be
   611 more boilerplate code needed before these instructions can be
   581 run. The code is shown in Figure~\ref{boiler}. This
   612 run. The complete code is shown in Figure~\ref{boiler}. This
   582 boilerplate code is very specific to the JVM. Lines 4 to 8 
   613 boilerplate code is very specific to the JVM. If we target any
   583 contains a method for object creation in the JVM and is called 
   614 other virtual machine or a machine language, then we would
   584 \emph{before} the \pcode{main}-method in Lines 10 to 17. 
   615 need to change this code. Lines 4 to 8 in Figure~\ref{boiler}
   585 Interesting are the Lines 11 and 12 where we hardwire that the 
   616 contain a method for object creation in the JVM; this method
   586 stack of our program will never be larger than 200 and that 
   617 is called \emph{before} the \pcode{main}-method in Lines 10 to
   587 the maximum number of variables is also 200. This seem 
   618 17. Interesting are the Lines 11 and 12 where we hardwire that
   588 conservative default values that allow is to run some simple
   619 the stack of our programs will never be larger than 200 and
   589 While-programs. In a real compiler, we would of course need to
   620 that the maximum number of variables is also 200. This seem to
   590 work harder and find out appropriate values for the stack and 
   621 be conservative default values that allow is to run some
   591 local variables.
   622 simple While-programs. In a real compiler, we would of course
       
   623 need to work harder and find out appropriate values for the
       
   624 stack and local variables.
   592 
   625 
   593 To sum up, in Figure~\ref{test} is the complete code generated
   626 To sum up, in Figure~\ref{test} is the complete code generated
   594 for the slightly non-sensical program
   627 for the slightly non-sensical program
   595 
   628 
   596 \begin{lstlisting}[mathescape,language=While]
   629 \begin{lstlisting}[mathescape,language=While]
   597 x := 1 + 2;
   630 x := 1 + 2;
   598 write x
   631 write x
   599 \end{lstlisting}
   632 \end{lstlisting}
   600 
   633 
   601 \noindent Having this code at our disposal, we need the
   634 \noindent Having this code at our disposal, we need the
   602 assembler to translate the generated code into bytecode (a
   635 assembler to translate the generated code into JVM bytecode (a
   603 class file) that can be understood by the JVM.
   636 class file). This bytecode is understood by the JVM and can be
       
   637 run by just invoking the \pcode{java}-program.
   604 
   638 
   605 
   639 
   606 \begin{figure}[p]
   640 \begin{figure}[p]
   607 \lstinputlisting{../progs/test-small.j}
   641 \lstinputlisting{../progs/test-small.j}
   608 \caption{Generated code for a test program.\label{test}}
   642 \caption{Generated code for a test program. This code can be 
       
   643 processed by an Java assembler producing a class-file, which
       
   644 can be run by the \pcode{java}-program.\label{test}}
   609 \end{figure}
   645 \end{figure}
   610 
   646 
   611 \end{document}
   647 \end{document}
   612 
   648 
   613 %%% Local Variables: 
   649 %%% Local Variables: