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: |