handouts/ho08.tex
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Tue, 17 Nov 2015 19:12:51 +0000
changeset 379 fa2589ec0fae
parent 378 e8ac05fe2630
child 380 1e88390e81aa
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
\documentclass{article}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
\usepackage{../style}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
\usepackage{../langs}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
\usepackage{../grammar}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
\usepackage{../graphics}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
     8
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     9
\begin{document}
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    10
\lstset{morekeywords={def,if,then,else,write,read},keywordstyle=\color{codepurple}\bfseries}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    11
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
\section*{Handout 8 (A Functional Language)}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    15
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    16
The language we looked at in the previous lecture was rather 
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    17
primitive and the compiler rather crude. In this handout
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    18
we like to have a look at a slightly more comfortable
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    19
language and a tiny-teeny bit more realistic compiler. A small
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    20
collection of programs we want to be able to write and compile
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    21
is as follows:
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    23
\begin{lstlisting}[basicstyle=\ttfamily, numbers=none]
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    24
def fib(n) = if n == 0 then 0 
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    25
             else if n == 1 then 1 
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    26
             else fib(n - 1) + fib(n - 2);
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    28
def fact(n) = if n == 0 then 1 else n * fact(n - 1);
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    29
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    30
def ack(m, n) = if m == 0 then n + 1
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    31
                else if n == 0 then ack(m - 1, 1)
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    32
                else ack(m - 1, ack(m, n - 1));
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    33
                
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    34
def gcd(a, b) = if b == 0 then a else gcd(b, a % b);                
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    37
\noindent We will still restrict us to just programs about
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    38
integers, that means for example that every function needs to
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    39
return an integer. The grammar of the Fun-language is slightly 
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    40
simpler than the While-language, because almost everything is 
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    41
an expression. The grammar rules are as follows:
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    44
\begin{plstx}[rhs style=,margin=1.5cm]
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    45
: \meta{Exp} ::= \meta{Var} | \meta{Num} {\hspace{3cm}}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    46
             |   \meta{Exp} + \meta{Exp} | ... | (\meta{ExP})
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    47
             |   \code{if} \meta{BExp} \code{then} \meta{Exp} \code{else} \meta{Exp}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    48
             |   \code{write} \meta{Exp} {\hspace{5cm}}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    49
             |   \meta{Exp} ; \meta{Exp}  {\hspace{5cm}}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    50
             |   \textit{FunName} (\meta{Exp}, ..., \meta{Exp})\\
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    51
: \meta{BExp} ::= ...\\
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    52
: \meta{Decl} ::= \meta{Def} ; \meta{Decl}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    53
             | \meta{Exp}\\
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    54
: \meta{Def} ::= \code{def} \textit{FunName} ($x_1$, ..., $x_2$)\\               
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    55
\end{plstx}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57
\noindent where \meta{Id} stands for variables and \meta{Num}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
for numbers. For the moment let us omit variables from
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
arithmetic expressions. Our parser will take this grammar and
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
given an input produce abstract syntax trees. For example for
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
the expression $1 + ((2 * 3) + (4 - 3))$ it will produce the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
following tree.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
\begin{tikzpicture}
\Tree [.$+$ [.$1$ ] [.$+$ [.$*$ $2$ $3$ ] [.$-$ $4$ $3$ ]]]
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    66
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    67
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
\noindent To generate code for this expression, we need to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
traverse this tree in post-order fashion and emit code for
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
each node---this traversal in post-order fashion will produce
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
code for a stack-machine (what the JVM is). Doing so for the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
tree above generates the instructions
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    73
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
\begin{lstlisting}[numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
ldc 1 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    76
ldc 2 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
ldc 3 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
imul 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    79
ldc 4 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
ldc 3 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    81
isub 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
iadd 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
iadd
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    85
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
\noindent If we ``run'' these instructions, the result $8$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
will be on top of the stack (I leave this to you to verify;
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
the meaning of each instruction should be clear). The result
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
being on the top of the stack will be a convention we always
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
observe in our compiler, that is the results of arithmetic
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    91
expressions will always be on top of the stack. Note, that a
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    92
different bracketing of the expression, for example $(1 + (2 *
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    93
3)) + (4 - 3)$, produces a different abstract syntax tree and
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
thus potentially also a different list of instructions.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    95
Generating code in this fashion is rather easy to implement:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
it can be done with the following recursive
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    97
\textit{compile}-function, which takes the abstract syntax
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
tree as argument:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   101
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   102
$\textit{compile}(n)$ & $\dn$ & $\pcode{ldc}\; n$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
$\textit{compile}(a_1 + a_2)$ & $\dn$ &
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
$\textit{compile}(a_1) \;@\;\textit{compile}(a_2)\;@\; \pcode{iadd}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
$\textit{compile}(a_1 - a_2)$ & $\dn$ & 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   106
$\textit{compile}(a_1) \;@\; \textit{compile}(a_2)\;@\; \pcode{isub}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   107
$\textit{compile}(a_1 * a_2)$ & $\dn$ & 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   108
$\textit{compile}(a_1) \;@\; \textit{compile}(a_2)\;@\; \pcode{imul}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   109
$\textit{compile}(a_1 \backslash a_2)$ & $\dn$ & 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   110
$\textit{compile}(a_1) \;@\; \textit{compile}(a_2)\;@\; \pcode{idiv}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   111
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   112
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   113
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   114
However, our arithmetic expressions can also contain
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   115
variables. We will represent them as \emph{local variables} in
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   116
the JVM. Essentially, local variables are an array or pointers
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   117
to memory cells, containing in our case only integers. Looking
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   118
up a variable can be done with the instruction
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   119
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   120
\begin{lstlisting}[mathescape,numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   121
iload $index$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   122
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   123
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   124
\noindent 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   125
which places the content of the local variable $index$ onto 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   126
the stack. Storing the top of the stack into a local variable 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   127
can be done by the instruction
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   128
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   129
\begin{lstlisting}[mathescape,numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   130
istore $index$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   131
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   132
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   133
\noindent Note that this also pops off the top of the stack.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   134
One problem we have to overcome, however, is that local
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   135
variables are addressed, not by identifiers, but by numbers
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   136
(starting from $0$). Therefore our compiler needs to maintain
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   137
a kind of environment where variables are associated to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   138
numbers. This association needs to be unique: if we muddle up
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   139
the numbers, then we essentially confuse variables and the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   140
consequence will usually be an erroneous result. Our extended
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   141
\textit{compile}-function for arithmetic expressions will
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   142
therefore take two arguments: the abstract syntax tree and the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   143
environment, $E$, that maps identifiers to index-numbers.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   144
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   145
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   146
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   147
$\textit{compile}(n, E)$ & $\dn$ & $\pcode{ldc}\;n$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   148
$\textit{compile}(a_1 + a_2, E)$ & $\dn$ & 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   149
$\textit{compile}(a_1, E) \;@\;\textit{compile}(a_2, E)\;@\; \pcode{iadd}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   150
$\textit{compile}(a_1 - a_2, E)$ & $\dn$ &
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   151
$\textit{compile}(a_1, E) \;@\; \textit{compile}(a_2, E)\;@\; \pcode{isub}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   152
$\textit{compile}(a_1 * a_2, E)$ & $\dn$ &
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   153
$\textit{compile}(a_1, E) \;@\; \textit{compile}(a_2, E)\;@\; \pcode{imul}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   154
$\textit{compile}(a_1 \backslash a_2, E)$ & $\dn$ & 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   155
$\textit{compile}(a_1, E) \;@\; \textit{compile}(a_2, E)\;@\; \pcode{idiv}$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   156
$\textit{compile}(x, E)$ & $\dn$ & $\pcode{iload}\;E(x)$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   157
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   158
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   159
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   160
\noindent In the last line we generate the code for variables
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   161
where $E(x)$ stands for looking up the environment to which
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   162
index the variable $x$ maps to.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   163
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   164
There is a similar \textit{compile}-function for boolean
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   165
expressions, but it includes a ``trick'' to do with
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   166
\pcode{if}- and \pcode{while}-statements. To explain the issue
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   167
let us first describe the compilation of statements of the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   168
While-language. The clause for \pcode{skip} is trivial, since
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   169
we do not have to generate any instruction
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   170
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   171
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   172
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   173
$\textit{compile}(\pcode{skip}, E)$ & $\dn$ & $([], E)$\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   174
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   175
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   176
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   177
\noindent $[]$ is the empty list of instructions. Note that
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   178
the \textit{compile}-function for statements returns a pair, a
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   179
list of instructions (in this case the empty list) and an
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   180
environment for variables. The reason for the environment is
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   181
that assignments in the While-language might change the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   182
environment---clearly if a variable is used for the first
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   183
time, we need to allocate a new index and if it has been used
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   184
before, we need to be able to retrieve the associated index.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   185
This is reflected in the clause for compiling assignments:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   186
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   187
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   188
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   189
$\textit{compile}(x := a, E)$ & $\dn$ & 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   190
$(\textit{compile}(a, E) \;@\;\pcode{istore}\;index, E')$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   191
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   192
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   193
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   194
\noindent We first generate code for the right-hand side of
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   195
the assignment and then add an \pcode{istore}-instruction at
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   196
the end. By convention the result of the arithmetic expression
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   197
$a$ will be on top of the stack. After the \pcode{istore}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   198
instruction, the result will be stored in the index
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   199
corresponding to the variable $x$. If the variable $x$ has
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   200
been used before in the program, we just need to look up what
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   201
the index is and return the environment unchanged (that is in
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   202
this case $E' = E$). However, if this is the first encounter 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   203
of the variable $x$ in the program, then we have to augment 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   204
the environment and assign $x$ with the largest index in $E$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   205
plus one (that is $E' = E(x \mapsto largest\_index + 1)$). 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   206
That means for the assignment $x := x + 1$ we generate the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   207
following code
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   208
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   209
\begin{lstlisting}[mathescape,numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   210
iload $n_x$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   211
ldc 1
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   212
iadd
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   213
istore $n_x$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   214
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   215
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   216
\noindent 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   217
where $n_x$ is the index for the variable $x$.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   218
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   219
More complicated is the code for \pcode{if}-statments, say
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   220
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   221
\begin{lstlisting}[mathescape,language={},numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   222
if $b$ then $cs_1$ else $cs_2$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   223
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   224
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   225
\noindent where $b$ is a boolean expression and the $cs_{1/2}$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   226
are the statements for each \pcode{if}-branch. Lets assume
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   227
we already generated code for $b$ and $cs_{1/2}$. Then in the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   228
true-case the control-flow of the program needs to be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   229
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   230
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   231
\begin{tikzpicture}[node distance=2mm and 4mm,
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   232
 block/.style={rectangle, minimum size=1cm, draw=black, line width=1mm},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   233
 point/.style={rectangle, inner sep=0mm, minimum size=0mm, fill=red},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   234
 skip loop/.style={black, line width=1mm, to path={-- ++(0,-10mm) -| (\tikztotarget)}}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   235
\node (A1) [point] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   236
\node (b) [block, right=of A1] {code of $b$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   237
\node (A2) [point, right=of b] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   238
\node (cs1) [block, right=of A2] {code of $cs_1$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   239
\node (A3) [point, right=of cs1] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   240
\node (cs2) [block, right=of A3] {code of $cs_2$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   241
\node (A4) [point, right=of cs2] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   242
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   243
\draw (A1) edge [->, black, line width=1mm] (b);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   244
\draw (b) edge [->, black, line width=1mm] (cs1);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   245
\draw (cs1) edge [->, black, line width=1mm] (A3);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   246
\draw (A3) edge [->, black, skip loop] (A4);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   247
\node [below=of cs2] {\raisebox{-5mm}{\small{}jump}};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   248
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   249
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   250
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   251
\noindent where we start with running the code for $b$; since
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   252
we are in the true case we continue with running the code for
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   253
$cs_1$. After this however, we must not run the code for
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   254
$cs_2$, but always jump after the last instruction of $cs_2$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   255
(the code for the \pcode{else}-branch). Note that this jump is
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   256
unconditional, meaning we always have to jump to the end of
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   257
$cs_2$. The corresponding instruction of the JVM is
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   258
\pcode{goto}. In case $b$ turns out to be false we need the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   259
control-flow
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   260
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   261
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   262
\begin{tikzpicture}[node distance=2mm and 4mm,
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   263
 block/.style={rectangle, minimum size=1cm, draw=black, line width=1mm},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   264
 point/.style={rectangle, inner sep=0mm, minimum size=0mm, fill=red},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   265
 skip loop/.style={black, line width=1mm, to path={-- ++(0,-10mm) -| (\tikztotarget)}}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   266
\node (A1) [point] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   267
\node (b) [block, right=of A1] {code of $b$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   268
\node (A2) [point, right=of b] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   269
\node (cs1) [block, right=of A2] {code of $cs_1$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   270
\node (A3) [point, right=of cs1] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   271
\node (cs2) [block, right=of A3] {code of $cs_2$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   272
\node (A4) [point, right=of cs2] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   273
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   274
\draw (A1) edge [->, black, line width=1mm] (b);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   275
\draw (b) edge [->, black, line width=1mm] (A2);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   276
\draw (A2) edge [skip loop] (A3);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   277
\draw (A3) edge [->, black, line width=1mm] (cs2);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   278
\draw (cs2) edge [->,black, line width=1mm] (A4);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   279
\node [below=of cs1] {\raisebox{-5mm}{\small{}conditional jump}};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   280
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   281
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   282
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   283
\noindent where we now need a conditional jump (if the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   284
if-condition is false) from the end of the code for the 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   285
boolean to the beginning of the instructions $cs_2$. Once we 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   286
are finished with running $cs_2$ we can continue with whatever
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   287
code comes after the if-statement.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   288
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   289
The \pcode{goto} and the conditional jumps need addresses to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   290
where the jump should go. Since we are generating assembly
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   291
code for the JVM, we do not actually have to give (numeric)
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   292
addresses, but can just attach (symbolic) labels to our code.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   293
These labels specify a target for a jump. Therefore the labels
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   294
need to be unique, as otherwise it would be ambiguous where a
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   295
jump should go to. A label, say \pcode{L}, is attached to code
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   296
like
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   297
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   298
\begin{lstlisting}[mathescape,numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   299
L:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   300
  $instr_1$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   301
  $instr_2$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   302
    $\vdots$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   303
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   304
 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   305
\noindent where a label is indicated by a colon. 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   306
 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   307
Recall the ``trick'' with compiling boolean expressions: the 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   308
\textit{compile}-function for boolean expressions takes three
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   309
arguments: an abstract syntax tree, an environment for 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   310
variable indices and also the label, $lab$, to where an conditional 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   311
jump needs to go. The clause for the expression $a_1 = a_2$, 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   312
for example, is as follows:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   313
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   314
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   315
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   316
$\textit{compile}(a_1 = a_2, E, lab)$ & $\dn$\\ 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   317
\multicolumn{3}{l}{$\qquad\textit{compile}(a_1, E) \;@\;\textit{compile}(a_2, E)\;@\; \pcode{if_icmpne}\;lab$}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   318
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   319
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   320
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   321
\noindent where we are first generating code for the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   322
subexpressions $a_1$ and $a_2$. This will mean after running
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   323
the corresponding code there will be two integers on top of
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   324
the stack. If they are equal, we do not have to do anything
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   325
(except for popping them off from the stack) and just continue
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   326
with the next instructions (see control-flow of ifs above).
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   327
However if they are \emph{not} equal, then we need to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   328
(conditionally) jump to the label $lab$. This can be done with
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   329
the instruction
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   330
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   331
\begin{lstlisting}[mathescape,numbers=none]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   332
if_icmpne $lab$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   333
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   334
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   335
\noindent Other jump instructions for boolean operators are
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   336
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   337
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   338
\begin{tabular}{l@{\hspace{10mm}}c@{\hspace{10mm}}l}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   339
$\not=$ & $\Rightarrow$ & \pcode{if_icmpeq}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   340
$<$ & $\Rightarrow$ & \pcode{if_icmpge}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   341
$\le$ & $\Rightarrow$ & \pcode{if_icmpgt}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   342
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   343
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   344
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   345
\noindent and so on. I leave it to you to extend the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   346
\textit{compile}-function for the other boolean expressions.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   347
Note that we need to jump whenever the boolean is \emph{not}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   348
true, which means we have to ``negate'' the jump
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   349
condition---equals becomes not-equal, less becomes
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   350
greater-or-equal. If you do not like this design (it can be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   351
the source of some nasty, hard-to-detect errors), you can also
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   352
change the layout of the code and first give the code for the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   353
else-branch and then for the if-branch. However in the case
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   354
of while-loops this way of generating code still seems
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   355
the most convenient.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   356
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   357
We are now ready to give the compile function for 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   358
if-statments---remember this function returns for staments a 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   359
pair consisting of the code and an environment:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   360
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   361
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   362
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   363
$\textit{compile}(\pcode{if}\;b\;\pcode{then}\; cs_1\;\pcode{else}\; cs_2, E)$ & $\dn$\\ 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   364
\multicolumn{3}{l}{$\qquad L_\textit{ifelse}\;$ (fresh label)}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   365
\multicolumn{3}{l}{$\qquad L_\textit{ifend}\;$ (fresh label)}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   366
\multicolumn{3}{l}{$\qquad (is_1, E') = \textit{compile}(cs_1, E)$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   367
\multicolumn{3}{l}{$\qquad (is_2, E'') = \textit{compile}(cs_2, E')$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   368
\multicolumn{3}{l}{$\qquad(\textit{compile}(b, E, L_\textit{ifelse})$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   369
\multicolumn{3}{l}{$\qquad\phantom{(}@\;is_1$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   370
\multicolumn{3}{l}{$\qquad\phantom{(}@\; \pcode{goto}\;L_\textit{ifend}$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   371
\multicolumn{3}{l}{$\qquad\phantom{(}@\;L_\textit{ifelse}:$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   372
\multicolumn{3}{l}{$\qquad\phantom{(}@\;is_2$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   373
\multicolumn{3}{l}{$\qquad\phantom{(}@\;L_\textit{ifend}:, E'')$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   374
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   375
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   376
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   377
\noindent In the first two lines we generate two fresh labels
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   378
for the jump addresses (just before the else-branch and just
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   379
after). In the next two lines we generate the instructions for
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   380
the two branches, $is_1$ and $is_2$. The final code will
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   381
be first the code for $b$ (including the label 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   382
just-before-the-else-branch), then the \pcode{goto} for after
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   383
the else-branch, the label $L_\textit{ifesle}$, followed by
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   384
the instructions for the else-branch, followed by the 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   385
after-the-else-branch label. Consider for example the 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   386
if-statement:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   387
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   388
\begin{lstlisting}[mathescape,numbers=none,language={}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   389
if 1 = 1 then x := 2 else y := 3
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   390
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   391
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   392
\noindent 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   393
The generated code is as follows:
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   394
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   395
\begin{lstlisting}[mathescape,language={}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   396
   ldc 1
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   397
   ldc 1
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   398
   if_icmpne L_ifelse $\quad\tikz[remember picture] \node (C) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   399
   ldc 2
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   400
   istore 0
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   401
   goto L_ifend $\quad\tikz[remember picture] \node (A) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   402
L_ifelse: $\quad\tikz[remember picture] \node[] (D) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   403
   ldc 3
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   404
   istore 1
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   405
L_ifend: $\quad\tikz[remember picture] \node[] (B) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   406
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   407
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   408
\begin{tikzpicture}[remember picture,overlay]
  \draw[->,very thick] (A) edge [->,to path={-- ++(10mm,0mm) 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   409
           -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (B.east);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   410
  \draw[->,very thick] (C) edge [->,to path={-- ++(10mm,0mm) 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   411
           -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (D.east);
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   412
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   413
\noindent The first three lines correspond to the the boolean
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   414
expression $1 = 1$. The jump for when this boolean expression
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   415
is false is in Line~3. Lines 4-6 corresponds to the if-branch;
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   416
the else-branch is in Lines 8 and 9. Note carefully how the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   417
environment $E$ is threaded through the recursive calls of
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   418
\textit{compile}. The function receives an environment $E$,
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   419
but it might extend it when compiling the if-branch, yielding
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   420
$E'$. This happens for example in the if-statement above
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   421
whenever the variable \code{x} has not been used before.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   422
Similarly with the environment $E''$ for the second call to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   423
\textit{compile}. $E''$ is also the environment that needs to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   424
be returned as part of the answer.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   425
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   426
The compilation of the while-loops, say 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   427
\pcode{while} $b$ \pcode{do} $cs$, is very similar. In case
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   428
the condition is true and we need to do another iteration, 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   429
and the control-flow needs to be as follows
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   430
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   431
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   432
\begin{tikzpicture}[node distance=2mm and 4mm,
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   433
 block/.style={rectangle, minimum size=1cm, draw=black, line width=1mm},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   434
 point/.style={rectangle, inner sep=0mm, minimum size=0mm, fill=red},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   435
 skip loop/.style={black, line width=1mm, to path={-- ++(0,-10mm) -| (\tikztotarget)}}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   436
\node (A0) [point, left=of A1] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   437
\node (A1) [point] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   438
\node (b) [block, right=of A1] {code of $b$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   439
\node (A2) [point, right=of b] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   440
\node (cs1) [block, right=of A2] {code of $cs$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   441
\node (A3) [point, right=of cs1] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   442
\node (A4) [point, right=of A3] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   443
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   444
\draw (A0) edge [->, black, line width=1mm] (b);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   445
\draw (b) edge [->, black, line width=1mm] (cs1);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   446
\draw (cs1) edge [->, black, line width=1mm] (A3);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   447
\draw (A3) edge [->,skip loop] (A1);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   448
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   449
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   450
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   451
\noindent Whereas if the condition is \emph{not} true, we
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   452
need to jump out of the loop, which gives the following
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   453
control flow.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   454
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   455
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   456
\begin{tikzpicture}[node distance=2mm and 4mm,
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   457
 block/.style={rectangle, minimum size=1cm, draw=black, line width=1mm},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   458
 point/.style={rectangle, inner sep=0mm, minimum size=0mm, fill=red},
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   459
 skip loop/.style={black, line width=1mm, to path={-- ++(0,-10mm) -| (\tikztotarget)}}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   460
\node (A0) [point, left=of A1] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   461
\node (A1) [point] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   462
\node (b) [block, right=of A1] {code of $b$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   463
\node (A2) [point, right=of b] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   464
\node (cs1) [block, right=of A2] {code of $cs$};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   465
\node (A3) [point, right=of cs1] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   466
\node (A4) [point, right=of A3] {};
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   467
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   468
\draw (A0) edge [->, black, line width=1mm] (b);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   469
\draw (b) edge [->, black, line width=1mm] (A2);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   470
\draw (A2) edge [skip loop] (A3);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   471
\draw (A3) edge [->, black, line width=1mm] (A4);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   472
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   473
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   474
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   475
\noindent Again we can use the \textit{compile}-function for
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   476
boolean expressions to insert the appropriate jump to the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   477
end of the loop (label $L_{wend}$ below).
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   478
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   479
\begin{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   480
\begin{tabular}{lcl}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   481
$\textit{compile}(\pcode{while}\; b\; \pcode{do} \;cs, E)$ & $\dn$\\ 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   482
\multicolumn{3}{l}{$\qquad L_{wbegin}\;$ (fresh label)}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   483
\multicolumn{3}{l}{$\qquad L_{wend}\;$ (fresh label)}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   484
\multicolumn{3}{l}{$\qquad (is, E') = \textit{compile}(cs_1, E)$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   485
\multicolumn{3}{l}{$\qquad(L_{wbegin}:$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   486
\multicolumn{3}{l}{$\qquad\phantom{(}@\;\textit{compile}(b, E, L_{wend})$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   487
\multicolumn{3}{l}{$\qquad\phantom{(}@\;is$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   488
\multicolumn{3}{l}{$\qquad\phantom{(}@\; \text{goto}\;L_{wbegin}$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   489
\multicolumn{3}{l}{$\qquad\phantom{(}@\;L_{wend}:, E')$}\\
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   490
\end{tabular}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   491
\end{center}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   492
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   493
\noindent I let you go through how this clause works. As an example
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   494
you can consider the while-loop
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   495
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   496
\begin{lstlisting}[mathescape,numbers=none,language={}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   497
while x <= 10 do x := x + 1
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   498
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   499
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   500
\noindent yielding the following code
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   501
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   502
\begin{lstlisting}[mathescape,language={}]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   503
L_wbegin: $\quad\tikz[remember picture] \node[] (LB) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   504
   iload 0
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   505
   ldc 10
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   506
   if_icmpgt L_wend $\quad\tikz[remember picture] \node (LC) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   507
   iload 0
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   508
   ldc 1
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   509
   iadd
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   510
   istore 0
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   511
   goto L_wbegin $\quad\tikz[remember picture] \node (LA) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   512
L_wend: $\quad\tikz[remember picture] \node[] (LD) {\mbox{}};$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   513
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   514
 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   515
\begin{tikzpicture}[remember picture,overlay]
  \draw[->,very thick] (LA) edge [->,to path={-- ++(10mm,0mm) 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   516
           -- ++(0mm,17.3mm) |- (\tikztotarget)},line width=1mm] (LB.east);
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   517
  \draw[->,very thick] (LC) edge [->,to path={-- ++(10mm,0mm) 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   518
           -- ++(0mm,-17.3mm) |- (\tikztotarget)},line width=1mm] (LD.east);
\end{tikzpicture}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   519
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   520
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   521
Next we need to consider the statement \pcode{write x}, which
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   522
can be used to print out the content of a variable. For this
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   523
we need to use a Java library function. In order to avoid
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   524
having to generate a lot of code for each
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   525
\pcode{write}-command, we use a separate helper-method and
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   526
just call this method with an argument (which needs to be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   527
placed onto the stack). The code of the helper-method is as
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   528
follows.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   529
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   530
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   531
\begin{lstlisting}[language=JVMIS]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   532
.method public static write(I)V 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   533
    .limit locals 1 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   534
    .limit stack 2 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   535
    getstatic java/lang/System/out Ljava/io/PrintStream; 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   536
    iload 0
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   537
    invokevirtual java/io/PrintStream/println(I)V 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   538
    return 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   539
.end method
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   540
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   541
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   542
\noindent The first line marks the beginning of the method,
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   543
called \pcode{write}. It takes a single integer argument
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   544
indicated by the \pcode{(I)} and returns no result, indicated
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   545
by the \pcode{V}. Since the method has only one argument, we
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   546
only need a single local variable (Line~2) and a stack with
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   547
two cells will be sufficient (Line 3). Line 4 instructs the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   548
JVM to get the value of the field \pcode{out} of the class
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   549
\pcode{java/lang/System}. It expects the value to be of type
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   550
\pcode{java/io/PrintStream}. A reference to this value will be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   551
placed on the stack. Line~5 copies the integer we want to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   552
print out onto the stack. In the next line we call the method
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   553
\pcode{println} (from the class \pcode{java/io/PrintStream}).
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   554
We want to print out an integer and do not expect anything
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   555
back (that is why the type annotation is \pcode{(I)V}). The
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   556
\pcode{return}-instruction in the next line changes the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   557
control-flow back to the place from where \pcode{write} was
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   558
called. This method needs to be part of a header that is
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   559
included in any code we generate. The helper-method
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   560
\pcode{write} can be invoked with the two instructions
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   561
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   562
\begin{lstlisting}[mathescape,language=JVMIS]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   563
iload $E(x)$ 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   564
invokestatic XXX/XXX/write(I)V
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   565
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   566
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   567
\noindent where we first place the variable to be printed on
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   568
top of the stack and then call \pcode{write}. The \pcode{XXX}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   569
need to be replaced by an appropriate class name (this will be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   570
explained shortly).
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   571
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   572
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   573
\begin{figure}[t]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   574
\begin{lstlisting}[mathescape,language=JVMIS]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   575
.class public XXX.XXX
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   576
.super java/lang/Object
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   577
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   578
.method public <init>()V
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   579
    aload_0
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   580
    invokenonvirtual java/lang/Object/<init>()V
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   581
    return
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   582
.end method
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   583
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   584
.method public static main([Ljava/lang/String;)V
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   585
    .limit locals 200
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   586
    .limit stack 200
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   587
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   588
      $\textit{\ldots{}here comes the compiled code\ldots}$
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   589
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   590
    return
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   591
.end method
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   592
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   593
\caption{Boilerplate code needed for running generated code.\label{boiler}}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   594
\end{figure}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   595
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   596
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   597
By generating code for a While-program, we end up with a list
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   598
of (JVM assembly) instructions. Unfortunately, there is a bit
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   599
more boilerplate code needed before these instructions can be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   600
run. The complete code is shown in Figure~\ref{boiler}. This
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   601
boilerplate code is very specific to the JVM. If we target any
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   602
other virtual machine or a machine language, then we would
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   603
need to change this code. Lines 4 to 8 in Figure~\ref{boiler}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   604
contain a method for object creation in the JVM; this method
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   605
is called \emph{before} the \pcode{main}-method in Lines 10 to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   606
17. Interesting are the Lines 11 and 12 where we hardwire that
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   607
the stack of our programs will never be larger than 200 and
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   608
that the maximum number of variables is also 200. This seem to
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   609
be conservative default values that allow is to run some
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   610
simple While-programs. In a real compiler, we would of course
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   611
need to work harder and find out appropriate values for the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   612
stack and local variables.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   613
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   614
To sum up, in Figure~\ref{test} is the complete code generated
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   615
for the slightly non-sensical program
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   616
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   617
\begin{lstlisting}[mathescape,language=While]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   618
x := 1 + 2;
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   619
write x
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   620
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   621
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   622
\noindent Having this code at our disposal, we need the
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   623
assembler to translate the generated code into JVM bytecode (a
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   624
class file). This bytecode is understood by the JVM and can be
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   625
run by just invoking the \pcode{java}-program.
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   626
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   627
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   628
\begin{figure}[p]
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   629
\lstinputlisting{../progs/test-small.j}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   630
\caption{Generated code for a test program. This code can be 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   631
processed by an Java assembler producing a class-file, which
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   632
can be run by the \pcode{java}-program.\label{test}}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   633
\end{figure}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   634
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   635
\end{document}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   636
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   637
%%% Local Variables: 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   638
%%% mode: latex  
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   639
%%% TeX-master: t
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   640
%%% End: