13 %% change Console to scala.io.StdIn.readByte() |
13 %% change Console to scala.io.StdIn.readByte() |
14 |
14 |
15 |
15 |
16 \begin{document} |
16 \begin{document} |
17 |
17 |
18 \section*{Part 5 (Scala, 10 Marks)} |
18 \section*{Main Part 5 (Scala, 9 Marks)} |
19 |
19 |
20 \mbox{}\hfill\textit{``If there's one feature that makes Scala, `Scala',}\\ |
20 \mbox{}\hfill\textit{``If there's one feature that makes Scala, `Scala',}\\ |
21 \mbox{}\hfill\textit{ I would pick implicits.''}\smallskip\\ |
21 \mbox{}\hfill\textit{ I would pick implicits.''}\smallskip\\ |
22 \mbox{}\hfill\textit{ --- Martin Odersky (creator of the Scala language)}\bigskip\bigskip |
22 \mbox{}\hfill\textit{ --- Martin Odersky (creator of the Scala language)}\bigskip\bigskip |
23 |
23 |
24 |
24 |
25 \noindent |
25 \noindent |
26 This part is about a small (esoteric) programming language called |
26 This part is about a small (esoteric) programming language called |
27 brainf***. Actually, we will implement an interpreter for our own version |
27 brainf***. We will implement an interpreter and compiler for |
28 of this language called brainf*ck++.\bigskip |
28 this language.\bigskip |
29 |
29 |
30 \IMPORTANT{This part is worth 10\% and you need to submit it on \cwTEN{} at 5pm. |
30 \IMPORTANT{This part is worth 10\% and you need to submit it on \cwTEN{} at 5pm. |
31 Any 1\% you achieve counts as your ``weekly engagement''.} |
31 Any 1\% you achieve counts as your ``weekly engagement''.} |
32 |
32 |
33 \noindent |
33 \noindent |
42 As usual, this Scala assignment comes with a reference implementation in |
42 As usual, this Scala assignment comes with a reference implementation in |
43 form of two \texttt{jar}-files. You can download them from KEATS. They |
43 form of two \texttt{jar}-files. You can download them from KEATS. They |
44 allow you to run any test cases on your own computer. For example you |
44 allow you to run any test cases on your own computer. For example you |
45 can call Scala on the command line with the option \texttt{-cp bf.jar} |
45 can call Scala on the command line with the option \texttt{-cp bf.jar} |
46 and then query any function from the \texttt{bf.scala} template file. |
46 and then query any function from the \texttt{bf.scala} template file. |
47 You have to prefix the calls with \texttt{CW10a} and \texttt{CW10b}, |
47 You have to prefix the calls with \texttt{M5a} and \texttt{M5b}, |
48 respectively. For example |
48 respectively. For example |
49 |
49 |
50 |
50 |
51 \begin{lstlisting}[language={},xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small] |
51 \begin{lstlisting}[language={},xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small] |
52 $ scala -cp bf.jar |
52 $ scala -cp bf.jar |
53 scala> import CW10a._ |
53 scala> import M5a._ |
54 scala> run(load_bff("sierpinski.bf")) ; () |
54 scala> run(load_bff("sierpinski.bf")) ; () |
55 * |
55 * |
56 * * |
56 * * |
57 * * |
57 * * |
58 * * * * |
58 * * * * |
122 \end{center} \bigskip |
122 \end{center} \bigskip |
123 |
123 |
124 |
124 |
125 \noindent |
125 \noindent |
126 As mentioned above, the original brainf*** has 8 single-character |
126 As mentioned above, the original brainf*** has 8 single-character |
127 commands. Our version of bf++ will contain the commands \texttt{'>'}, |
127 commands. Our version of bf will contain the commands \texttt{'>'}, |
128 \texttt{'<'}, \texttt{'+'}, \texttt{'-'}, \texttt{'.'}, \texttt{'['} |
128 \texttt{'<'}, \texttt{'+'}, \texttt{'-'}, \texttt{'.'}, \texttt{'['} |
129 and \texttt{']'} from the original, and in addition the commands |
129 and \texttt{']'}. Every other character |
130 \texttt{'@'}, \texttt{'*'} and \texttt{'\#'}. Every other character |
|
131 is considered a comment. |
130 is considered a comment. |
132 |
131 |
133 Our interpreter for bf++ operates on memory cells containing |
132 Our interpreter for bf operates on memory cells containing |
134 integers. For this it uses a single memory pointer, called |
133 integers. For this it uses a single memory pointer, called |
135 \texttt{mp}, that points at each stage to one memory cell. |
134 \texttt{mp}, that points at each stage to one memory cell. |
136 |
135 |
137 \begin{center} |
136 \begin{center} |
138 \begin{tikzpicture} |
137 \begin{tikzpicture} |
159 \noindent |
158 \noindent |
160 This pointer can be moved forward by one memory cell by using the |
159 This pointer can be moved forward by one memory cell by using the |
161 command \texttt{'>'}, and backward by using \texttt{'<'}. The commands |
160 command \texttt{'>'}, and backward by using \texttt{'<'}. The commands |
162 \texttt{'+'} and \texttt{'-'} increase, respectively decrease, by 1 |
161 \texttt{'+'} and \texttt{'-'} increase, respectively decrease, by 1 |
163 the content of the memory cell to which the memory pointer currently |
162 the content of the memory cell to which the memory pointer currently |
164 points to. The command for output in bf++ is \texttt{'.'} whereby output works |
163 points to. The command for output in bf is \texttt{'.'} whereby output works |
165 by reading the content of the memory cell to which the memory pointer |
164 by reading the content of the memory cell to which the memory pointer |
166 points to and printing it out as an ASCII character.\footnote{In the |
165 points to and printing it out as an ASCII character.\footnote{In the |
167 original version of bf, there is also a command for input, but we |
166 original version of bf, there is also a command for input, but we |
168 omit it here. All our programs will be ``autonomous''.} The |
167 omit it here. All our programs will be ``autonomous''.} The |
169 commands \texttt{'['} and \texttt{']'} are looping |
168 commands \texttt{'['} and \texttt{']'} are looping |
177 +++++..+++.>>.<-.<.+++.------.--------.>>+.>++. |
176 +++++..+++.>>.<-.<.+++.------.--------.>>+.>++. |
178 \end{verbatim} |
177 \end{verbatim} |
179 \end{center} |
178 \end{center} |
180 |
179 |
181 \noindent |
180 \noindent |
182 This one prints out Hello World\ldots{}obviously \texttt{;o)} We also |
181 This one prints out Hello World\ldots{}obviously \texttt{;o)} |
183 add 3 new commands in the bf++-version of the bf-language. The purpose |
|
184 of these commands we explain later. |
|
185 |
182 |
186 |
183 |
187 \subsubsection*{Tasks (file bf.scala)} |
184 \subsubsection*{Tasks (file bf.scala)} |
188 |
185 |
189 \begin{itemize} |
186 \begin{itemize} |
190 \item[(1)] Write a function that takes a filename (a string) as an argument |
187 \item[(1)] Write a function that takes a filename (a string) as an argument |
191 and requests the corresponding file from disk. It returns the |
188 and requests the corresponding file from disk. It returns the |
192 content of the file as a string. If the file does not exists, |
189 content of the file as a string. If the file does not exists, |
193 the function should return the empty string. |
190 the function should return the empty string. |
194 \mbox{}\hfill[1 Mark] |
191 \mbox{}\hfill[0.5 Marks] |
195 |
192 |
196 \item[(2)] Brainf**k++ memory is represented by a \texttt{Map} from |
193 \item[(2)] Brainf**k memory is represented by a \texttt{Map} from |
197 integers to integers. The empty memory is represented by |
194 integers to integers. The empty memory is represented by |
198 \texttt{Map()}, that is nothing is stored in the |
195 \texttt{Map()}, that is nothing is stored in the |
199 memory; \texttt{Map(0 -> 1, 2 -> 3)} stores \texttt{1} at |
196 memory; \texttt{Map(0 -> 1, 2 -> 3)} stores \texttt{1} at |
200 memory location \texttt{0}, and at \texttt{2} it stores \texttt{3}. The |
197 memory location \texttt{0}, and at \texttt{2} it stores \texttt{3}. The |
201 convention is that if we query the memory at a location that is |
198 convention is that if we query the memory at a location that is |
208 Write another function \texttt{write}, which takes a memory, a |
205 Write another function \texttt{write}, which takes a memory, a |
209 memory pointer and an integer value as arguments and updates the |
206 memory pointer and an integer value as arguments and updates the |
210 \texttt{Map} with the value at the given memory location. As usual, |
207 \texttt{Map} with the value at the given memory location. As usual, |
211 the \texttt{Map} is not updated `in-place' but a new map is created |
208 the \texttt{Map} is not updated `in-place' but a new map is created |
212 with the same data, except the new value is stored at the given memory |
209 with the same data, except the new value is stored at the given memory |
213 pointer.\hfill[1 Mark] |
210 pointer.\hfill[0.5 Marks] |
214 |
211 |
215 \item[(3)] Write two functions, \texttt{jumpRight} and |
212 \item[(3)] Write two functions, \texttt{jumpRight} and |
216 \texttt{jumpLeft}, that are needed to implement the loop constructs |
213 \texttt{jumpLeft}, that are needed to implement the loop constructs |
217 in brainf**k++. They take a program (a \texttt{String}) and a program |
214 in brainf**k. They take a program (a \texttt{String}) and a program |
218 counter (an \texttt{Int}) as arguments and move right (respectively |
215 counter (an \texttt{Int}) as arguments and move right (respectively |
219 left) in the string in order to find the \textbf{matching} |
216 left) in the string in order to find the \textbf{matching} |
220 opening/closing bracket. For example, given the following program |
217 opening/closing bracket. For example, given the following program |
221 with the program counter indicated by an arrow: |
218 with the program counter indicated by an arrow: |
222 |
219 |
281 \end{center} |
278 \end{center} |
282 \hfill[2 Marks] |
279 \hfill[2 Marks] |
283 |
280 |
284 |
281 |
285 \item[(4)] Write a recursive function \texttt{compute} that runs a |
282 \item[(4)] Write a recursive function \texttt{compute} that runs a |
286 brain*u*k++ program. It takes a program, a program counter, a memory |
283 brain*u*k program. It takes a program, a program counter, a memory |
287 pointer and a memory as arguments. If the program counter is outside |
284 pointer and a memory as arguments. If the program counter is outside |
288 the program string, the execution stops and \texttt{compute} returns the |
285 the program string, the execution stops and \texttt{compute} returns the |
289 memory. If the program counter is inside the string, it reads the |
286 memory. If the program counter is inside the string, it reads the |
290 corresponding character and updates the program counter \texttt{pc}, |
287 corresponding character and updates the program counter \texttt{pc}, |
291 memory pointer \texttt{mp} and memory \texttt{mem} according to the |
288 memory pointer \texttt{mp} and memory \texttt{mem} according to the |
292 rules shown in Figure~\ref{comms}. It then calls recursively |
289 rules shown in Figure~\ref{comms}. It then calls recursively |
293 \texttt{compute} with the updated data. The most convenient way to |
290 \texttt{compute} with the updated data. The most convenient way to |
294 implement the brainf**k++ rules in Scala is to use pattern-matching |
291 implement the brainf**k rules in Scala is to use pattern-matching |
295 and to calculate a triple consisting of the updated \texttt{pc}, |
292 and to calculate a triple consisting of the updated \texttt{pc}, |
296 \texttt{mp} and \texttt{mem}. |
293 \texttt{mp} and \texttt{mem}. |
297 |
294 |
298 Write another function \texttt{run} that calls \texttt{compute} with a |
295 Write another function \texttt{run} that calls \texttt{compute} with a |
299 given brainfu*k++ program and memory, and the program counter and memory pointer |
296 given brainfu*k program and memory, and the program counter and memory pointer |
300 set to~$0$. Like \texttt{compute}, it returns the memory after the execution |
297 set to~$0$. Like \texttt{compute}, it returns the memory after the execution |
301 of the program finishes. You can test your brainf**k++ interpreter with the |
298 of the program finishes. You can test your brainf**k interpreter with the |
302 Sierpinski triangle or the Hello world programs (they seem to be particularly |
299 Sierpinski triangle or the Hello world programs (they seem to be particularly |
303 useful for debugging purposes), or have a look at |
300 useful for debugging purposes), or have a look at |
304 |
301 |
305 \begin{center} |
302 \begin{center} |
306 \url{https://esolangs.org/wiki/Brainfuck} |
303 \url{https://esolangs.org/wiki/Brainfuck} |
307 \end{center} |
304 \end{center} |
308 |
305 |
309 \noindent for more bf/bf++-programs and the test cases given in \texttt{bf.scala}.\\ |
306 \noindent for more bf-programs and the test cases given in \texttt{bf.scala}.\\ |
310 \mbox{}\hfill[2 Marks] |
307 \mbox{}\hfill[2 Marks] |
311 |
308 |
312 \begin{figure}[p] |
309 \begin{figure}[p] |
313 \begin{center} |
310 \begin{center} |
314 \begin{tabular}{|@{\hspace{0.5mm}}p{0.8cm}|l|} |
311 \begin{tabular}{|@{\hspace{0.5mm}}p{0.8cm}|l|} |
359 $\bullet$ & $\texttt{mp}$ and \texttt{mem} unchanged\medskip\\ |
356 $\bullet$ & $\texttt{mp}$ and \texttt{mem} unchanged\medskip\\ |
360 \multicolumn{2}{@{}l}{otherwise if \texttt{mem(mp) == 0} then}\\ |
357 \multicolumn{2}{@{}l}{otherwise if \texttt{mem(mp) == 0} then}\\ |
361 $\bullet$ & $\texttt{pc} + 1$\\ |
358 $\bullet$ & $\texttt{pc} + 1$\\ |
362 $\bullet$ & $\texttt{mp}$ and \texttt{mem} unchanged\\ |
359 $\bullet$ & $\texttt{mp}$ and \texttt{mem} unchanged\\ |
363 \end{tabular}\\\hline |
360 \end{tabular}\\\hline |
364 \hfill\texttt{'*'} & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
361 %\hfill\texttt{'*'} & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
365 $\bullet$ & $\texttt{pc} + 1$\\ |
362 % $\bullet$ & $\texttt{pc} + 1$\\ |
366 $\bullet$ & $\texttt{mp}$ unchanged\\ |
363 % $\bullet$ & $\texttt{mp}$ unchanged\\ |
367 $\bullet$ & \texttt{mem} updated with \texttt{mp -> mem(mp) * mem(mp - 1)}\\ |
364 % $\bullet$ & \texttt{mem} updated with \texttt{mp -> mem(mp) * mem(mp - 1)}\\ |
368 \multicolumn{2}{@{}l}{this multiplies the content of the memory cells at |
365 % \multicolumn{2}{@{}l}{this multiplies the content of the memory cells at |
369 \texttt{mp} and \texttt{mp - 1}}\\ |
366 % \texttt{mp} and \texttt{mp - 1}}\\ |
370 \multicolumn{2}{@{}l}{and stores the result at \texttt{mp}} |
367 % \multicolumn{2}{@{}l}{and stores the result at \texttt{mp}} |
371 \end{tabular}\\\hline |
368 % \end{tabular}\\\hline |
372 \hfill\texttt{'@'} & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
369 %\hfill\texttt{'@'} & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
373 $\bullet$ & $\texttt{pc} + 1$\\ |
370 % $\bullet$ & $\texttt{pc} + 1$\\ |
374 $\bullet$ & $\texttt{mp}$ unchanged\\ |
371 % $\bullet$ & $\texttt{mp}$ unchanged\\ |
375 $\bullet$ & \texttt{mem} updated with |
372 % $\bullet$ & \texttt{mem} updated with |
376 \texttt{mem(mp) -> mem(mp - 1)}\\ |
373 % \texttt{mem(mp) -> mem(mp - 1)}\\ |
377 \multicolumn{2}{@{}l}{this updates the memory cell having the index stored at \texttt{mem(mp)},}\\ |
374 % \multicolumn{2}{@{}l}{this updates the memory cell having the index stored at \texttt{mem(mp)},}\\ |
378 \multicolumn{2}{@{}l}{with the value stored at \texttt{mem(mp - 1)},} |
375 % \multicolumn{2}{@{}l}{with the value stored at \texttt{mem(mp - 1)},} |
379 \end{tabular}\\\hline |
376 % \end{tabular}\\\hline |
380 \hfill\texttt{'\#'} & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
377 %\hfill\texttt{'\#'} & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
381 $\bullet$ & $\texttt{pc} + 1$\\ |
378 % $\bullet$ & $\texttt{pc} + 1$\\ |
382 $\bullet$ & $\texttt{mp}$ and \texttt{mem} unchanged\\ |
379 % $\bullet$ & $\texttt{mp}$ and \texttt{mem} unchanged\\ |
383 $\bullet$ & print out \,\texttt{mem(mp)} as a number\\ |
380 % $\bullet$ & print out \,\texttt{mem(mp)} as a number\\ |
384 \end{tabular}\\\hline |
381 % \end{tabular}\\\hline |
385 any other char & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
382 any other char & \begin{tabular}[t]{@{}l@{\hspace{2mm}}l@{}} |
386 $\bullet$ & $\texttt{pc} + 1$\\ |
383 % $\bullet$ & $\texttt{pc} + 1$\\ |
387 $\bullet$ & \texttt{mp} and \texttt{mem} unchanged |
384 $\bullet$ & \texttt{mp} and \texttt{mem} unchanged |
388 \end{tabular}\\ |
385 \end{tabular}\\ |
389 \hline |
386 \hline |
390 \end{tabular} |
387 \end{tabular} |
391 \\\mbox{}\\[-10mm]\mbox{} |
388 \\\mbox{}\\[-10mm]\mbox{} |
392 \end{center} |
389 \end{center} |
393 \caption{The rules for how commands in the brainf***++ language update the |
390 \caption{The rules for how commands in the brainf*** language update the |
394 program counter \texttt{pc}, |
391 program counter \texttt{pc}, |
395 the memory pointer \texttt{mp} and the memory \texttt{mem}.\label{comms}} |
392 the memory pointer \texttt{mp} and the memory \texttt{mem}.\label{comms}} |
396 \end{figure} |
393 \end{figure} |
397 \end{itemize}\bigskip |
394 \end{itemize}\bigskip |
398 |
395 |
399 %%\newpage |
396 %%\newpage |
400 |
397 |
401 \subsection*{Part B (4 Marks)} |
398 \subsection*{Part B (4 Marks)} |
402 |
399 |
403 I am sure you agree while it is fun to marvel at bf++-programs, like the |
400 I am sure you agree while it is fun to marvel at bf-programs, like the |
404 Sierpinski triangle or the Mandelbrot program, being interpreted, it |
401 Sierpinski triangle or the Mandelbrot program, being interpreted, it |
405 is much more fun to write a compiler for the bf++-language. |
402 is much more fun to write a compiler for the bf-language. |
406 |
403 |
407 |
404 |
408 \subsubsection*{Tasks (file bfc.scala)} |
405 \subsubsection*{Tasks (file bfc.scala)} |
409 |
406 |
410 \begin{itemize} |
407 \begin{itemize} |
413 before running the program. In our case we can precompute the |
410 before running the program. In our case we can precompute the |
414 addresses where we need to jump at the beginning and end of |
411 addresses where we need to jump at the beginning and end of |
415 loops. |
412 loops. |
416 |
413 |
417 For this write a function \texttt{jtable} that precomputes the ``jump |
414 For this write a function \texttt{jtable} that precomputes the ``jump |
418 table'' for a bf++-program. This function takes a bf++-program |
415 table'' for a bf-program. This function takes a bf-program |
419 as an argument and returns a \texttt{Map[Int, Int]}. The |
416 as an argument and returns a \texttt{Map[Int, Int]}. The |
420 purpose of this Map is to record the information, in cases |
417 purpose of this Map is to record the information, in cases |
421 a pc-position points to a '\texttt{[}' or a '\texttt{]}', |
418 a pc-position points to a '\texttt{[}' or a '\texttt{]}', |
422 to which pc-position do we need to jump next? |
419 to which pc-position do we need to jump next? |
423 |
420 |
458 For the latter consider that it is difficult for compilers to |
455 For the latter consider that it is difficult for compilers to |
459 comprehend what is intended with whole programs, but they are very good |
456 comprehend what is intended with whole programs, but they are very good |
460 at finding out what small snippets of code do, and then try to |
457 at finding out what small snippets of code do, and then try to |
461 generate faster code for such snippets. |
458 generate faster code for such snippets. |
462 |
459 |
463 In our case, dead code is everything that is not a bf++-command. |
460 In our case, dead code is everything that is not a bf-command. |
464 Therefore write a function \texttt{optimise} which deletes such |
461 Therefore write a function \texttt{optimise} which deletes such |
465 dead code from a bf++-program. Moreover this function should replace every substring |
462 dead code from a bf-program. Moreover this function should replace every substring |
466 of the form \pcode{[-]} by a new command \texttt{0}. |
463 of the form \pcode{[-]} by a new command \texttt{0}. |
467 The idea is that the loop \pcode{[-]} just resets the |
464 The idea is that the loop \pcode{[-]} just resets the |
468 memory at the current location to 0. It is more efficient |
465 memory at the current location to 0. It is more efficient |
469 to do this in a single step, rather than stepwise in a loop as in |
466 to do this in a single step, rather than stepwise in a loop as in |
470 the original bf++-programs. |
467 the original bf-programs. |
471 |
468 |
472 In the extended \texttt{compute3} and \texttt{run3} functions you should |
469 In the extended \texttt{compute3} and \texttt{run3} functions you should |
473 implement this command by writing 0 to \pcode{mem(mp)}, that is use |
470 implement this command by writing 0 to \pcode{mem(mp)}, that is use |
474 \pcode{write(mem, mp, 0)} as the rule for the command \texttt{0}. |
471 \pcode{write(mem, mp, 0)} as the rule for the command \texttt{0}. |
475 The easiest way to modify a string in this way is to use the regular |
472 The easiest way to modify a string in this way is to use the regular |
476 expression \pcode{"""[^<>+-.\\[\\]@\#*]"""}, which recognises everything that is |
473 expression \pcode{"""[^<>+-.\\[\\]]"""}, which recognises everything that is |
477 not a bf++-command. Similarly, the |
474 not a bf-command. Similarly, the |
478 regular expression \pcode{"""\\[-\\]"""} finds all occurrences of \pcode{[-]}. By using the Scala method \pcode{.replaceAll} you can replace substrings |
475 regular expression \pcode{"""\\[-\\]"""} finds all occurrences of \pcode{[-]}. By using the Scala method \pcode{.replaceAll} you can replace substrings |
479 with new strings.\\ |
476 with new strings.\\ |
480 \mbox{}\hfill{[1 Mark]} |
477 \mbox{}\hfill{[1 Mark]} |
481 |
478 |
482 \item[(7)] Finally, real compilers try to take advantage of modern |
479 \item[(7)] Finally, real compilers try to take advantage of modern |
507 |
504 |
508 |
505 |
509 If there are more |
506 If there are more |
510 than 26 \pcode{+}'s in a row, then more than one ``two-character'' |
507 than 26 \pcode{+}'s in a row, then more than one ``two-character'' |
511 bf-commands need to be generated (the idea is that more than |
508 bf-commands need to be generated (the idea is that more than |
512 26 copies of a single bf++-command in a row is a rare occurrence in |
509 26 copies of a single bf-command in a row is a rare occurrence in |
513 actual bf++-programs). Similar replacements apply |
510 actual bf-programs). Similar replacements apply |
514 for \pcode{-}, \pcode{<} and \pcode{>}, but |
511 for \pcode{-}, \pcode{<} and \pcode{>}, but |
515 all other bf++-commands should be unaffected by this |
512 all other bf-commands should be unaffected by this |
516 change. |
513 change. |
517 |
514 |
518 For this write a function \texttt{combine} which replaces sequences |
515 For this write a function \texttt{combine} which replaces sequences |
519 of repeated increment and decrement commands by appropriate |
516 of repeated increment and decrement commands by appropriate |
520 two-character commands. In the functions \pcode{compute4} and |
517 two-character commands. In the functions \pcode{compute4} and |
521 \pcode{run4}, the ``combine'' and the optimisation from (6) should |
518 \pcode{run4}, the ``combine'' and the optimisation from (6) should |
522 be performed. Make sure that when a two-character bf++-command is |
519 be performed. Make sure that when a two-character bf-command is |
523 encountered you need to increase the \pcode{pc}-counter by two in |
520 encountered you need to increase the \pcode{pc}-counter by two in |
524 order to progress to the next command. For example |
521 order to progress to the next command. For example |
525 |
522 |
526 \begin{center} |
523 \begin{center} |
527 \pcode{combine(optimise(load_bff("benchmark.bf")))} |
524 \pcode{combine(optimise(load_bff("benchmark.bf")))} |