handouts/ho08.tex
author Christian Urban <christian.urban@kcl.ac.uk>
Tue, 19 Oct 2021 22:51:51 +0100
changeset 846 3a535de22816
parent 711 6f3f3dd01786
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
603
155430aea517 updated
Christian Urban <urbanc@in.tum.de>
parents: 600
diff changeset
     1
% !TEX program = xelatex
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
\documentclass{article}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
\usepackage{../style}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
\usepackage{../langs}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
\usepackage{../grammar}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
\usepackage{../graphics}
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
     7
\usepackage{amssymb}
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
     8
\usepackage{xcolor}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
     9
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    10
\usepackage[most]{tcolorbox}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    11
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    12
\newtcbox{\hm}[1][]{%
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    13
     size=fbox,
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    14
    tcbox raise base, nobeforeafter, 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    15
    enhanced, colframe=gray,
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    16
    colback=gray!30, boxrule=1pt,
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    17
    fontupper=\ttfamily,
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    18
    #1}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
405
30dd644ba71a updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 383
diff changeset
    20
% modern compilers are different
30dd644ba71a updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 383
diff changeset
    21
% https://channel9.msdn.com/Blogs/Seth-Juarez/Anders-Hejlsberg-on-Modern-Compiler-Construction
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    22
492
39b7ff2cf1bc updated
Christian Urban <urbanc@in.tum.de>
parents: 405
diff changeset
    23
%halting problem
39b7ff2cf1bc updated
Christian Urban <urbanc@in.tum.de>
parents: 405
diff changeset
    24
%https://dfilaretti.github.io/2017-04-30/halting-problem
39b7ff2cf1bc updated
Christian Urban <urbanc@in.tum.de>
parents: 405
diff changeset
    25
39b7ff2cf1bc updated
Christian Urban <urbanc@in.tum.de>
parents: 405
diff changeset
    26
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    27
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    28
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
\begin{document}
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    30
\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
    31
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
\section*{Handout 8 (A Functional Language)}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    35
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    36
The language we looked at in the previous lecture was rather
603
155430aea517 updated
Christian Urban <urbanc@in.tum.de>
parents: 600
diff changeset
    37
primitive and the compiler rather crude---everything was
604
9e75249e96f2 updated
Christian Urban <urbanc@in.tum.de>
parents: 603
diff changeset
    38
essentially compiled into a big monolithic chunk of code
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    39
inside the main function. In this handout we like to have a
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    40
look at a slightly more comfortable language, which I call
603
155430aea517 updated
Christian Urban <urbanc@in.tum.de>
parents: 600
diff changeset
    41
Fun-language, and a tiny-teeny bit more realistic compiler.
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    42
The Fun-language is a small functional programming language. A small
604
9e75249e96f2 updated
Christian Urban <urbanc@in.tum.de>
parents: 603
diff changeset
    43
collection of programs we want to be able to write and compile
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    44
is as follows:
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
    46
\begin{lstlisting}[numbers=none]
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    47
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
    48
             else if n == 1 then 1 
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    49
             else fib(n - 1) + fib(n - 2);
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    51
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
    52
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    53
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
    54
                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
    55
                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
    56
                
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    57
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
    58
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    60
\noindent Compare the code of the fib-program with the same program
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
    61
written in the WHILE-language\ldots Fun is definitely more comfortable.
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    62
We will still focus on programs involving integers only, that means for
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    63
example that every function in Fun is expected to return an integer. The
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    64
point of the Fun language is to compile each function to a separate
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    65
method in JVM bytecode (not just a big monolithic code chunk). The means
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    66
we need to adapt to some of the conventions of the JVM about methods.
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    67
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    68
The grammar of the Fun-language is slightly simpler than the
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
    69
WHILE-language, because the main syntactic category are
699
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
    70
expressions (we do not have statements in Fun). The grammar rules are
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
    71
as follows:\footnote{We of course have a slightly different (non-left-recursive)
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
    72
grammar for our parsing combinators. But for simplicity sake we leave
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
    73
these details to the implementation.}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    76
\begin{plstx}[rhs style=,margin=1.5cm]
600
d488a3e7b0ec updated
Christian Urban <urbanc@in.tum.de>
parents: 492
diff changeset
    77
: \meta{Exp} ::= \meta{Id} | \meta{Num} {\hspace{3.7cm}}
d488a3e7b0ec updated
Christian Urban <urbanc@in.tum.de>
parents: 492
diff changeset
    78
             |   \meta{Exp} + \meta{Exp} | ... | (\meta{Exp}) {\hspace{3.7cm}}
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
    79
             |   \code{if} \; \meta{BExp} \; \code{then} \; \meta{Exp} \; \code{else} \; \meta{Exp}
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    80
             |   \code{write} \meta{Exp} {\hspace{5cm}}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    81
             |   \meta{Exp} ; \meta{Exp}  {\hspace{5cm}}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    82
             |   \textit{FunName} (\meta{Exp}, ..., \meta{Exp})\\
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    83
: \meta{BExp} ::= ...\\
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    84
: \meta{Decl} ::= \meta{Def} ; \meta{Decl}
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    85
             | \meta{Exp}\\
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    86
: \meta{Def} ::= \code{def} \textit{FunName} ($x_1$, ..., $x_n$) = \meta{Exp}\\               
379
fa2589ec0fae updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 378
diff changeset
    87
\end{plstx}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    89
\noindent where, as usual, \meta{Id} stands for variables and
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    90
\meta{Num} for numbers. We can call a function by applying the
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    91
arguments to a function name (as shown in the last clause of
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    92
\meta{Exp}). The arguments in such a function call can be
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    93
again expressions, including other function calls. In
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    94
contrast, when defining a function (see \meta{Def}-clause) the
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    95
arguments need to be variables, say $x_1$ to $x_n$. We call
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    96
the expression on the right of = in a function definition as
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    97
the \emph{body of the function}. We have the restriction that
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    98
the variables inside a function body can only be those that
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
    99
are mentioned as arguments of the function. A Fun-program is
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   100
then a sequence of function definitions separated by
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   101
semicolons, and a final ``main'' call of a function that
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   102
starts the computation in the program. For example
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
\begin{lstlisting}[numbers=none]
699
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   105
def fact(n) = if n == 0 then 1 
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   106
              else n * fact(n - 1);
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   107
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   108
write(fact(5))
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   109
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   110
699
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   111
\noindent is a valid Fun-program. The parser of the
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   112
Fun-language produces abstract syntax trees which in Scala
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   113
can be represented as follows:
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   114
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   115
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   116
{\small
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   117
\begin{lstlisting}[numbers=none]
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   118
abstract class Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   119
abstract class BExp 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   120
abstract class Decl
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   121
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   122
case class Var(s: String) extends Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   123
case class Num(i: Int) extends Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   124
case class Aop(o: String, a1: Exp, a2: Exp) extends Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   125
case class If(a: BExp, e1: Exp, e2: Exp) extends Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   126
case class Write(e: Exp) extends Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   127
case class Sequ(e1: Exp, e2: Exp) extends Exp
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   128
case class Call(name: String, args: List[Exp]) extends Exp
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   129
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   130
case class Bop(o: String, a1: Exp, a2: Exp) extends BExp
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   131
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   132
case class Def(name: String, 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   133
               args: List[String], 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   134
               body: Exp) extends Decl
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   135
case class Main(e: Exp) extends Decl
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   136
\end{lstlisting}}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   137
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   138
The rest of the hand out is about compiling this language. Let us first
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   139
look at some clauses for compiling expressions. The compilation of
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   140
arithmetic and boolean expressions is just like for the WHILE-language
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   141
and does not need any modification (recall that the
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   142
\textit{compile}-function for boolean expressions takes a third argument
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   143
for the label where the control-flow should jump when the boolean
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   144
expression is \emph{not} true---this is needed for compiling
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   145
\pcode{if}s). One additional feature in the Fun-language are sequences.
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   146
Their purpose is to do one calculation after another or printing out an
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   147
intermediate result. The reason why we need to be careful however is the
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   148
convention that every expression can only produce a single result
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   149
(including sequences). Since this result will be on the top of the
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   150
stack, we need to generate a \pcode{pop}-instruction for sequences in
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   151
order to clean-up the stack. For example, for an expression of the form
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   152
\pcode{exp1 ; exp2} we need to generate code where after the first code
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   153
chunk a \pcode{pop}-instruction is needed. 
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   154
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   155
\begin{lstlisting}[language=JVMIS, numbers=none,mathescape]
383
a6a6bf32fade updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 382
diff changeset
   156
$\textrm{\textit{compile}}($exp1$)$
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   157
pop
383
a6a6bf32fade updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 382
diff changeset
   158
$\textrm{\textit{compile}}($exp2$)$
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   159
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   160
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   161
\noindent In effect we ``forget'' about the result the first
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   162
expression calculates. I leave you to think about why this
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   163
sequence operator is still useful in the Fun-language, even 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   164
if the first result is just ``discarded''. 
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   165
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   166
There is also one small modification we have to perform when
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   167
calling the write method. Remember in the Fun-language we have
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   168
the convention that every expression needs to return an
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   169
integer as a result (located on the top of the stack). Our
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   170
helper function implementing write, however, ``consumes'' the
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   171
top element of the stack and violates this convention.
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   172
Therefore before we call, say, \pcode{write(1+2)}, we need to
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   173
duplicate the top element of the stack like so
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   174
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   175
\begin{figure}[t]
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   176
\begin{lstlisting}[language=JVMIS, 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   177
                   xleftmargin=2mm, 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   178
                   numbers=none]
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   179
.method public static write(I)V 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   180
   .limit locals 1
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   181
   .limit stack 2
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   182
   getstatic java/lang/System/out Ljava/io/PrintStream; 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   183
   iload 0 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   184
   invokevirtual java/io/PrintStream/println(I)V 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   185
   return 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   186
.end method
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   187
\end{lstlisting}
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   188
\caption{The helper function for printing out integers.\label{write}}
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   189
\end{figure}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   190
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   191
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   192
\begin{lstlisting}[language=JVMIS, numbers=none,mathescape]
383
a6a6bf32fade updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 382
diff changeset
   193
$\textrm{\textit{compile}}($1+2$)$
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   194
dup
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   195
invokestatic XXX/XXX/write(I)V
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   196
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   197
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   198
\noindent We also need to first generate code for the
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   199
argument-expression of write, which in the WHILE-language was
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   200
only allowed to be a single variable.
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   201
603
155430aea517 updated
Christian Urban <urbanc@in.tum.de>
parents: 600
diff changeset
   202
Most of the new code in the compiler for the Fun-language
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   203
comes from function definitions and function calls. For this
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   204
have a look again at the helper function in
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   205
Figure~\ref{write}. Assuming we have a function definition
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   206
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   207
\begin{lstlisting}[numbers=none,mathescape]
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   208
def fname (x1, ... , xn) = ...
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   209
\end{lstlisting}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   210
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   211
\noindent then we have to generate
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   212
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   213
\begin{lstlisting}[numbers=none,mathescape,language=JVMIS]
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   214
.method public static fname (I...I)I
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   215
   .limit locals ??
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   216
   .limit stack ?? 
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   217
   ...
699
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   218
   ireturn
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   219
.method end  
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   220
\end{lstlisting}
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   221
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   222
\noindent where the number of \pcode{I}s corresponds to the
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   223
number of arguments the function has, say \pcode{x1} to
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   224
\pcode{xn}. The final \pcode{I} is needed in order to indicate
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   225
that the function returns an integer. Therefore we also have
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   226
to use \pcode{ireturn} instead of \pcode{return}. However,
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   227
more interesting are the two \pcode{.limit} lines.
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   228
\pcode{Locals} refers to the local variables of the method,
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   229
which can be queried and overwritten using the JVM
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   230
instructions \pcode{iload} and \pcode{istore}, respectively.
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   231
Before we call a function with, say, three arguments, we need
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   232
to ensure that these three arguments are pushed onto the stack
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   233
(we will come to the corresponding code shortly). Once we are
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   234
inside the method, the arguments on the stack turn into local
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   235
variables. So in case we have three arguments on the stack, we 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   236
will have inside the function three local variables that can 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   237
be referenced by the indices $0..2$. Determining the limit for
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   238
local variables is the easy bit. Harder is the stack limit.
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   239
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   240
Calculating how much stack a program needs is equivalent to 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   241
the Halting problem, and thus undecidable in general. 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   242
Fortunately, we are only asked how much stack a \emph{single} 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   243
call of the function requires. This can be relatively easily
604
9e75249e96f2 updated
Christian Urban <urbanc@in.tum.de>
parents: 603
diff changeset
   244
compiled by recursively analysing which instructions we 
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   245
generate and how much stack they might require.
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   246
 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   247
\begin{center}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   248
\begin{tabular}{lcl}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   249
$\textit{estimate}(n)$ & $\dn$ & $1$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   250
$\textit{estimate}(x)$ & $\dn$ & $1$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   251
$\textit{estimate}(a_1\;aop\;a_2)$ & $\dn$ &
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   252
$\textit{estimate}(a_1) + \textit{estimate}(a_2)$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   253
$\textit{estimate}(\pcode{if}\;b\;\pcode{then}\;e_1\;\pcode{else}\;e_2)$ & $\dn$ & 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   254
$\textit{estimate}(b) +$\\ 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   255
& & $\quad max(\textit{estimate}(e_1), \textit{estimate}(e_2))$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   256
$\textit{estimate}(\pcode{write}(e))$ & $\dn$ & 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   257
$\textit{estimate}(e) + 1$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   258
$\textit{estimate}(e_1 ; e_2)$ & $\dn$ & 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   259
$max(\textit{estimate}(e_1), \textit{estimate}(e_2))$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   260
$\textit{estimate}(f(e_1, ..., e_n))$ & $\dn$ & 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   261
$\sum_{i = 1..n}\;estimate(e_i)$\medskip\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   262
$\textit{estimate}(a_1\;bop\;a_2)$ & $\dn$ &
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   263
$\textit{estimate}(a_1) + \textit{estimate}(a_2)$\\
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   264
\end{tabular}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   265
\end{center} 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   266
 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   267
\noindent This function overestimates the stack size, for
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   268
example, in the case of \pcode{if}s. Since we cannot predict
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   269
which branch will be run, we have to allocate the maximum 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   270
of stack each branch might take. I leave you also to think 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   271
about whether the estimate in case of function calls is the 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   272
best possible estimate. Note also that in case of \pcode{write}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   273
we need to add one, because we duplicate the top-most element
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   274
in the stack.
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   275
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   276
With this all in place, we can start generating code, for
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   277
example, for the two functions:
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   278
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   279
\begin{lstlisting}[numbers=none]
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   280
def suc(x) = x + 1;
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   281
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   282
def add(x, y) = if x == 0 then y
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   283
                else suc(add(x - 1, y));
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   284
\end{lstlisting}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   285
603
155430aea517 updated
Christian Urban <urbanc@in.tum.de>
parents: 600
diff changeset
   286
\noindent The successor function is a simple loading of the
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   287
argument $x$ (index $0$) onto the stack, as well as the number
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   288
$1$. Then we add both elements leaving the result of the 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   289
addition on top of the stack. This value will be returned by 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   290
the \pcode{suc}-function. See below:
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   291
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   292
\begin{lstlisting}[language=JVMIS]
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   293
.method public static suc(I)I 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   294
.limit locals 1
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   295
.limit stack 2
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   296
  iload 0
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   297
  ldc 1
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   298
  iadd
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   299
  ireturn
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   300
.end method 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   301
\end{lstlisting}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   302
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   303
\noindent The addition function is a bit more interesting
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   304
since in the last line we have to call the function
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   305
recursively and ``wrap around'' a call to the successor
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   306
function. The code is as follows:
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   307
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   308
\begin{lstlisting}[language=JVMIS]
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   309
.method public static add(II)I 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   310
.limit locals 2
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   311
.limit stack 5
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   312
  iload 0
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   313
  ldc 0
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   314
  if_icmpne If_else
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   315
  iload 1
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   316
  goto If_end
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   317
If_else:
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   318
  iload 0
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   319
  ldc 1
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   320
  isub
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   321
  iload 1
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   322
  invokestatic XXX/XXX/add(II)I
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   323
  invokestatic XXX/XXX/suc(I)I
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   324
If_end:
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   325
  ireturn
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   326
.end method
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   327
\end{lstlisting}
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   328
382
38e368dc9b10 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 381
diff changeset
   329
\noindent The locals limit is 2 because add takes two arguments.
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   330
The stack limit is a simple calculation using the estimate
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   331
function. We first generate code for the boolean expression
382
38e368dc9b10 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 381
diff changeset
   332
\pcode{x == 0}, that is loading the local variable 0 and the
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   333
number 0 onto the stack (Lines 4 and 5). If the not-equality
382
38e368dc9b10 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 381
diff changeset
   334
test fails, we continue with returning $y$, which is the local
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   335
variable 1 (followed by a jump to the return instruction). If
382
38e368dc9b10 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 381
diff changeset
   336
the not-equality test succeeds, then we jump to the label 
381
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   337
\pcode{If_else} (Line 9). After that label is the code for
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   338
\pcode{suc(add(x - 1, y))}. We first have to evaluate the
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   339
argument of the suc-function. But this means we first have to
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   340
evaluate the two arguments of the add-function. This means
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   341
loading $x$ and $1$ onto the stack and subtracting them.
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   342
Then loading $y$ onto the stack. We can then make a recursive 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   343
call to add (its two arguments are on the stack). When this
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   344
call returns we have the result of the addition on the top of 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   345
the stack and just need to call suc. Finally, we can return 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   346
the result on top of the stack as the result of the 
47eceea734c5 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 380
diff changeset
   347
add-function.
380
1e88390e81aa updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 379
diff changeset
   348
 
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   349
\subsection*{Tail-Call Optimisations}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   350
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   351
Let us now briefly touch again upon the vast topic of compiler
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   352
optimisations. As an example, let's perform tail-call optimisations for
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   353
our Fun-language. Consider the following version of the factorial
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   354
function:
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   355
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   356
\begin{lstlisting}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   357
def facT(n, acc) = 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   358
  if n == 0 then acc 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   359
  else facT(n - 1, n * acc);
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   360
\end{lstlisting}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   361
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   362
\noindent 
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   363
The corresponding JVM code for this function is below:
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   364
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   365
\begin{lstlisting}[language=JVMIS, numbers=left]
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   366
.method public static facT(II)I 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   367
.limit locals 2
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   368
.limit stack 6
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   369
  iload 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   370
  ldc 0	
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   371
  if_icmpne If_else_2
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   372
  iload 1
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   373
  goto If_end_3
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   374
If_else_2:
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   375
  iload 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   376
  ldc 1
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   377
  isub
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   378
  iload 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   379
  iload 1
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   380
  imul
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   381
  invokestatic fact/fact/facT(II)I
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   382
If_end_3:
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   383
  ireturn
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   384
.end method 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   385
\end{lstlisting}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   386
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   387
\noindent
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   388
The interesting part is in Lines 10 to 16. Since the \code{facT}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   389
function is recursive, we have also a recursive call in Line 16 in the
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   390
JVM code. The problem is that before we can make the recursive call, we
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   391
need to put the two arguments, namely \code{n - 1} and \code{n * acc},
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   392
onto the stack. That is how we communicate arguments to a function. To
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   393
see the the difficulty, imagine you call this function 1000 times
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   394
recursively. Each call results in some hefty overhead on the
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   395
stack---ultimately leading to a stack overflow. Well, it is possible to
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   396
avoid this overhead completely in many circumstances. This is what
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   397
\emph{tail-call optimisations} are about.   
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   398
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   399
Note that the call to \code{facT} in the program is the last instruction
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   400
before the \code{ireturn} (the label in Line 17 does not count since it
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   401
is not an instruction). Also remember, before we make the recursive call
711
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   402
the arguments of \code{facT} need to be put on the stack. Once we are
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   403
``inside'' the function, the arguments on the stack turn into local
6f3f3dd01786 updated
Christian Urban <urbanc@in.tum.de>
parents: 699
diff changeset
   404
variables. Therefore 
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   405
\code{n} and \code{acc} are referenced inside the function with \pcode{iload 0}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   406
and \pcode{iload 1} respectively.
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   407
699
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   408
The idea of tail-call optimisation is to eliminate the expensive
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   409
recursive functions call and replace it by a simple jump back to the
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   410
beginning of the function. To make this work we have to change how we
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   411
communicate the arguments to the next level of the recursion/iteration:
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   412
we cannot use the stack, but have to load the arguments into the
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   413
corresponding local variables. This gives the following code
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   414
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   415
\begin{lstlisting}[language=JVMIS, numbers=left, escapeinside={(*@}{@*)}]
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   416
.method public static facT(II)I 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   417
.limit locals 2
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   418
.limit stack 6
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   419
(*@\hm{facT\_Start:} @*)
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   420
  iload 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   421
  ldc 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   422
  if_icmpne If_else_2
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   423
  iload 1
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   424
  goto If_end_3
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   425
If_else_2:
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   426
  iload 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   427
  ldc 1
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   428
  isub
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   429
  iload 0
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   430
  iload 1
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   431
  imul
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   432
  (*@\hm{istore 1} @*)
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   433
  (*@\hm{istore 0} @*)
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   434
  (*@\hm{goto facT\_Start} @*)
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   435
If_end_3:
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   436
  ireturn
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   437
.end method 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   438
\end{lstlisting}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   439
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   440
\noindent
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   441
In Line 4 we introduce a label for indicating where the start of the
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   442
function is. Important are Lines 17 and 18 where we store the values
699
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   443
from the stack into local variables. When we then jump back to the
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   444
beginning of the function (in Line 19) it will look to the function as
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   445
if it had been called the normal way via values on the stack. But
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   446
because of the jump, clearly, no memory on the stack is needed. In
7dac350b20a1 updated
Christian Urban <urbanc@in.tum.de>
parents: 693
diff changeset
   447
effect we replaced a recursive call with a simple loop.
693
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   448
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   449
Can this optimisation always be applied? Unfortunately not. The 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   450
recursive call needs to be in tail-call position, that is the last
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   451
operation needs to be the recursive call. This is for example
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   452
not the case with the usual formulation of the factorial function.
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   453
Consider again the Fun-program
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   454
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   455
\begin{lstlisting}[numbers=none]
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   456
def fact(n) = if n == 0 then 1 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   457
              else n * fact(n - 1)
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   458
\end{lstlisting}            
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   459
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   460
\noindent
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   461
In this version of the factorial function the recursive call is
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   462
\emph{not} the last operation (which can also been seen very clearly
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   463
in the generated JVM code). Because of this, the plumbing of local 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   464
variables would not work and in effect the optimisation is not applicable. 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   465
Very roughly speaking the tail-position of a function is in the two 
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   466
highlighted places
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   467
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   468
\begin{itemize}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   469
\item \texttt{if Bexp then \hm{Exp} else \hm{Exp}}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   470
\item \texttt{Exp ; \hm{Exp}}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   471
\end{itemize}
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   472
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   473
To sum up, the compiler needs to recognise when a recursive call
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   474
is in tail-position. It then can apply the tail-call optimisations
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   475
technique, which is well known and widely implemented in compilers
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   476
for functional programming languages.
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   477
605d971e98fd updated
Christian Urban <urbanc@in.tum.de>
parents: 604
diff changeset
   478
378
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   479
\end{document}
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   480
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   481
%%% Local Variables: 
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   482
%%% mode: latex  
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   483
%%% TeX-master: t
e8ac05fe2630 updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   484
%%% End: