| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Fri, 24 Oct 2025 11:26:43 +0100 | |
| changeset 1018 | fd6a64c53f0e | 
| parent 1009 | 7fd1997bd14c | 
| permissions | -rw-r--r-- | 
| 59 | 1 | \documentclass{article}
 | 
| 292 
7ed2a25dd115
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
206diff
changeset | 2 | \usepackage{../style}
 | 
| 876 | 3 | \usepackage{../langs}
 | 
| 292 
7ed2a25dd115
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
206diff
changeset | 4 | \usepackage{../graphics}
 | 
| 59 | 5 | |
| 6 | \begin{document}
 | |
| 7 | ||
| 75 
898c25a4e399
tuned
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
60diff
changeset | 8 | \section*{Homework 8}
 | 
| 59 | 9 | |
| 916 | 10 | %%\HEADER | 
| 359 
db106e5b7c4d
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
292diff
changeset | 11 | |
| 59 | 12 | \begin{enumerate}
 | 
| 292 
7ed2a25dd115
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
206diff
changeset | 13 | \item Write a program in the WHILE-language that calculates | 
| 955 | 14 | the factorial function. | 
| 15 | ||
| 956 | 16 | %\begin{lstlisting}
 | 
| 17 | %write "factorial: "; | |
| 18 | %read n; | |
| 19 | %minus1 := 1; | |
| 20 | %while n > 0 do {
 | |
| 21 | %minus1 := minus1 * n; | |
| 22 | %n := n - 1 | |
| 23 | %}; | |
| 24 | %write "Result: "; | |
| 25 | %write minus1 ; | |
| 26 | %write "\n" | |
| 27 | %\end{lstlisting}
 | |
| 77 
49c0beef79a1
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
76diff
changeset | 28 | |
| 292 
7ed2a25dd115
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
206diff
changeset | 29 | \item What optimisations could a compiler perform when | 
| 955 | 30 | compiling a WHILE-program? | 
| 31 | ||
| 32 |   \solution{
 | |
| 33 |     \begin{itemize}
 | |
| 34 | \item peephole optimisations (more specific instructions) | |
| 35 | \item common sub-expression elimination %, for example | |
| 36 | ||
| 37 | %\begin{lstlisting}
 | |
| 38 | %x := 3 + a | |
| 39 | %y := 3 + a | |
| 40 | %\end{lstlisting}
 | |
| 41 | ||
| 42 | %can be optimised to | |
| 43 | ||
| 44 |     %\begin{lstlisting}[numbers=none,language={}]
 | |
| 45 | % z := 3 + a | |
| 46 | % x := z | |
| 47 | % y := z | |
| 48 |     %\end{lstlisting}
 | |
| 49 | ||
| 50 | \item constant folding / constant propagation (that is calculate the result of 3 + 4 already during | |
| 51 | compilation) | |
| 52 | \item tail-recursion optimisation cannot be applied to the WHILE language | |
| 53 | because there are no recursive functions | |
| 54 |     \end{itemize}
 | |
| 55 | } | |
| 206 
85b961f1eee9
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
102diff
changeset | 56 | |
| 292 
7ed2a25dd115
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
206diff
changeset | 57 | \item What is the main difference between the Java assembler | 
| 
7ed2a25dd115
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
206diff
changeset | 58 | (as processed by Jasmin) and Java Byte Code? | 
| 206 
85b961f1eee9
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
102diff
changeset | 59 | |
| 955 | 60 |       \solution{ The main difference is that the j-files have symbols
 | 
| 61 | for places where to jump, while class files have this resolved | |
| 62 | to concrete addresses (or relative jumps). That is what the | |
| 63 | assembler has to generate. } | |
| 64 | ||
| 940 | 65 | \item Remember symbolic labels in the Jasmin-assembler are meant to | 
| 66 | be used for jumps (like in loops or if-conditions). Assume | |
| 67 | you generated a Jasmin-file with some redundant | |
| 68 | labels, that is some labels are not used in your code for any jumps. For | |
| 69 |       example \texttt{L\_begin} and \texttt{L\_end} are not used
 | |
| 955 | 70 | in the following code-snippet: | 
| 940 | 71 | |
| 72 | \begin{lstlisting}[language=JVMIS,numbers=none]
 | |
| 73 | L_begin: | |
| 74 | ldc 1 | |
| 75 | ldc 2 | |
| 76 | ldc 3 | |
| 77 | imul | |
| 78 | ldc 4 | |
| 79 | ldc 3 | |
| 80 | isub | |
| 81 | iadd | |
| 82 | iadd | |
| 83 | L_end: | |
| 84 | \end{lstlisting}
 | |
| 85 | ||
| 86 | Do these redundant labels affect the size of the generated | |
| 87 | JVM-code? (Hint: What are the labels translated to by | |
| 955 | 88 | the Jasmin-assembler?). | 
| 940 | 89 | |
| 90 |       \solution{The answer is no. The reason is that assemblers
 | |
| 91 | calculate for labels either relative or explicit adresses, | |
| 92 | which are then used in the JVM-byte-code. Relative addresses | |
| 93 | are like ``jump 10 bytes forward'' or ``12 bytes backward''. So | |
| 94 | additional labels do not increase the size of the generated code.} | |
| 95 | ||
| 96 | ||
| 876 | 97 | \item Consider the following Scala snippet. Are the two functions | 
| 98 | \texttt{is\_even} and \texttt{is\_odd} tail-recursive?     
 | |
| 99 | ||
| 100 | \begin{lstlisting}[numbers=none]
 | |
| 901 | 101 | def is_even(n: Int) : Boolean = {
 | 
| 102 | if (n == 0) true else is_odd(n - 1) | |
| 876 | 103 | } | 
| 104 | ||
| 901 | 105 | def is_odd(n: Int) : Boolean = {
 | 
| 876 | 106 | if (n == 0) false | 
| 901 | 107 | else if (n == 1) true else is_even(n - 1) | 
| 876 | 108 | } | 
| 109 | \end{lstlisting}
 | |
| 110 | ||
| 111 | Do they cause stack-overflows when compiled to the JVM (for example by Scala)? | |
| 112 | ||
| 955 | 113 | \solution{
 | 
| 114 | Scala cannot generate jumps in between different methods (to which functions are compiled to). So cannot eliminate the tail-calls. Haskell for example can do this because it compiles the code in a big ``blob'' inside a main-method (similar to the WHILE language). | |
| 115 | } | |
| 116 | ||
| 1009 | 117 | \item The JVM method given below is code for the following recursive function | 
| 118 | ||
| 119 | \begin{lstlisting}[numbers=none]
 | |
| 120 | def add(x, y) = if x == 0 then y else add(x - 1, y + 1) | |
| 121 | \end{lstlisting}
 | |
| 122 | ||
| 123 | Rewrite the JVM code such that the recursive call at the end is removed. | |
| 124 | ||
| 125 | \begin{lstlisting}[language=JVMIS,numbers=none]
 | |
| 126 | .method public static add(II)I | |
| 127 | .limit locals 2 | |
| 128 | .limit stack 7 | |
| 129 | iload 0 | |
| 130 | ldc 0 | |
| 131 | if_icmpne If_else_4 | |
| 132 | iload 1 | |
| 133 | goto If_end_5 | |
| 134 | If_else_4: | |
| 135 | iload 0 | |
| 136 | ldc 1 | |
| 137 | isub | |
| 138 | iload 1 | |
| 139 | ldc 1 | |
| 140 | iadd | |
| 141 | invokestatic defs/defs/add(II)I ;; recursive call | |
| 142 | If_end_5: | |
| 143 | ireturn | |
| 144 | .end method | |
| 145 | \end{lstlisting}
 | |
| 146 | ||
| 147 | \solution{
 | |
| 148 | \begin{lstlisting}[language=JVMIS,numbers=none]
 | |
| 149 | .method public static add(II)I | |
| 150 | .limit locals 2 | |
| 151 | .limit stack 7 | |
| 152 | add2_Start: | |
| 153 | iload 0 | |
| 154 | ldc 0 | |
| 155 | if_icmpne If_else_4 | |
| 156 | iload 1 | |
| 157 | goto If_end_5 | |
| 158 | If_else_4: | |
| 159 | iload 0 | |
| 160 | ldc 1 | |
| 161 | isub | |
| 162 | iload 1 | |
| 163 | ldc 1 | |
| 164 | iadd | |
| 165 | istore 1 | |
| 166 | istore 0 | |
| 167 | goto add2_Start | |
| 168 | If_end_5: | |
| 169 | ireturn | |
| 170 | .end method | |
| 171 | \end{lstlisting}
 | |
| 172 | } | |
| 173 | ||
| 530 | 174 | |
| 175 | \item Explain what is meant by the terms lazy evaluation and eager | |
| 577 | 176 | evaluation. | 
| 177 | ||
| 955 | 178 |   \solution{ Lazy evaluation only evaluates expressions when they are
 | 
| 179 | needed and if they are needed twice, the results will be | |
| 180 | re-used. Eager evaluation immediately evaluates expressions, for | |
| 181 | example if they are arguments to function calls or allocated to | |
| 182 | variables.} | |
| 183 | ||
| 184 | ||
| 577 | 185 | \item \POSTSCRIPT | 
| 59 | 186 | \end{enumerate}
 | 
| 187 | ||
| 188 | \end{document}
 | |
| 189 | ||
| 190 | %%% Local Variables: | |
| 191 | %%% mode: latex | |
| 192 | %%% TeX-master: t | |
| 193 | %%% End: |