419 \begin{itemize} |
419 \begin{itemize} |
420 \item[(2a)] Brainf*** memory is represented by a \texttt{Map} from |
420 \item[(2a)] Brainf*** memory is represented by a \texttt{Map} from |
421 integers to integers. The empty memory is represented by |
421 integers to integers. The empty memory is represented by |
422 \texttt{Map()}, that is nothing is stored in the |
422 \texttt{Map()}, that is nothing is stored in the |
423 memory. \texttt{Map(0 -> 1, 2 -> 3)} clearly has stored \texttt{1} |
423 memory. \texttt{Map(0 -> 1, 2 -> 3)} clearly has stored \texttt{1} |
424 at memory location \texttt{0}, at \texttt{2} it stores |
424 at memory location \texttt{0}; at \texttt{2} it stores |
425 \texttt{3}. The convention is that if we query the memory at a |
425 \texttt{3}. The convention is that if we query the memory at a |
426 location that is not defined in the \texttt{Map} we return |
426 location that is not defined in the \texttt{Map}, we return |
427 \texttt{0}. Write a function, \texttt{sread}, that takes a memory (a |
427 \texttt{0}. Write a function, \texttt{sread}, that takes a memory (a |
428 \texttt{Map}) and a memory pointer (an \texttt{Int}) as argument, |
428 \texttt{Map}) and a memory pointer (an \texttt{Int}) as argument, |
429 and safely reads the corresponding memory location. If the map is not |
429 and safely reads the corresponding memory location. If the map is not |
430 defined at the memory pointer it returns \texttt{0}. |
430 defined at the memory pointer, \texttt{sread} returns \texttt{0}. |
431 |
431 |
432 Write another function \texttt{write}, which takes a memory, a |
432 Write another function \texttt{write}, which takes a memory, a |
433 memory pointer and a integer value as argument and updates the map |
433 memory pointer and an integer value as argument and updates the map |
434 with the value at the given memory location. As usual the map is not |
434 with the value at the given memory location. As usual the map is not |
435 updated `in-place' but a new map is created with the same data, |
435 updated `in-place' but a new map is created with the same data, |
436 except the value is stored at the given memory pointer.\hfill[1 Mark] |
436 except the value is stored at the given memory pointer.\hfill[1 Mark] |
437 |
437 |
438 \item[(2b)] Write two functions, \texttt{jumpRight} and |
438 \item[(2b)] Write two functions, \texttt{jumpRight} and |
452 |
452 |
453 \begin{center} |
453 \begin{center} |
454 \texttt{--[..+>--]\barbelow{,}>,++} |
454 \texttt{--[..+>--]\barbelow{,}>,++} |
455 \end{center} |
455 \end{center} |
456 |
456 |
457 meaning it jumps after the loop. Similarly, if you in 8th position |
457 meaning it jumps to after the loop. Similarly, if you in 8th position |
458 then \texttt{jumpLeft} is supposed to jump to just after the opening |
458 then \texttt{jumpLeft} is supposed to jump to just after the opening |
459 bracket (that is jumping to the beginning of the loop): |
459 bracket (that is jumping to the beginning of the loop): |
460 |
460 |
461 \begin{center} |
461 \begin{center} |
462 \texttt{--[..+>-\barbelow{-}],>,++} |
462 \texttt{--[..+>-\barbelow{-}],>,++} |
463 \qquad$\stackrel{\texttt{jumpLeft}}{\longrightarrow}$\qquad |
463 \qquad$\stackrel{\texttt{jumpLeft}}{\longrightarrow}$\qquad |
464 \texttt{--[\barbelow{.}.+>--],>,++} |
464 \texttt{--[\barbelow{.}.+>--],>,++} |
465 \end{center} |
465 \end{center} |
466 |
466 |
467 Unfortunately we have to take into account that there might be |
467 Unfortunately we have to take into account that there might be |
468 another opening and closing bracket on the `way' to find the |
468 other opening and closing brackets on the `way' to find the |
469 matching bracket. For example in the brainf*** program |
469 matching bracket. For example in the brainf*** program |
470 |
470 |
471 \begin{center} |
471 \begin{center} |
472 \texttt{--[\barbelow{.}.[+>]--],>,++} |
472 \texttt{--[\barbelow{.}.[+>]--],>,++} |
473 \end{center} |
473 \end{center} |
474 |
474 |
475 we do not want to return the index for the \texttt{'-'} in the 9th |
475 we do not want to return the index for the \texttt{'-'} in the 9th |
476 position, but the program counter for \texttt{','} in 12th |
476 position, but the program counter for \texttt{','} in 12th |
477 position. The easiest to find out whether a bracket is matched is to |
477 position. The easiest to find out whether a bracket is matched is by |
478 use levels (which are the third argument in \texttt{jumpLeft} and |
478 using levels (which are the third argument in \texttt{jumpLeft} and |
479 \texttt{jumpLeft}). In case of \texttt{jumpRight} you increase the |
479 \texttt{jumpLeft}). In case of \texttt{jumpRight} you increase the |
480 level by one whenever you find an opening bracket and decrease by |
480 level by one whenever you find an opening bracket and decrease by |
481 one for a closing bracket. Then in \texttt{jumpRight} you are looking |
481 one for a closing bracket. Then in \texttt{jumpRight} you are looking |
482 for the closing bracket on level \texttt{0}. For \texttt{jumpLeft} you |
482 for the closing bracket on level \texttt{0}. For \texttt{jumpLeft} you |
483 do the opposite. In this way you can find \textbf{matching} brackets |
483 do the opposite. In this way you can find \textbf{matching} brackets |
505 \hfill[1 Mark] |
505 \hfill[1 Mark] |
506 |
506 |
507 |
507 |
508 \item[(2c)] Write a recursive function \texttt{run} that executes a |
508 \item[(2c)] Write a recursive function \texttt{run} that executes a |
509 brainf*** program. It takes a program, a program counter, a memory |
509 brainf*** program. It takes a program, a program counter, a memory |
510 counter and a memory as arguments. If the program counter is outside |
510 pointer and a memory as arguments. If the program counter is outside |
511 the program string, the execution stops and \texttt{run} returns the |
511 the program string, the execution stops and \texttt{run} returns the |
512 memory. If the program counter is inside the string, it reads the |
512 memory. If the program counter is inside the string, it reads the |
513 corresponding character and updates the program counter \texttt{pc}, memory |
513 corresponding character and updates the program counter \texttt{pc}, |
514 pointer \texttt{mp} and memory \texttt{mem} according to the rules shown |
514 memory pointer \texttt{mp} and memory \texttt{mem} according to the |
515 in Figure~\ref{comms}. It the calls recursively \texttt{run} with the updated |
515 rules shown in Figure~\ref{comms}. It then calls recursively |
516 data. |
516 \texttt{run} with the updated data. |
517 |
517 |
518 Write another function \texttt{start} that calls \texttt{run} with a |
518 Write another function \texttt{start} that calls \texttt{run} with a |
519 given brainfu** program and memory, and the program counter and memory counter |
519 given brainfu** program and memory, and the program counter and memory pointer |
520 set to~$0$. Like \texttt{run} it returns the memory after the execution |
520 set to~$0$. Like \texttt{run} it returns the memory after the execution |
521 of the program finishes. You can test your brainf**k interpreter with the |
521 of the program finishes. You can test your brainf**k interpreter with the |
522 Sierpinski triangle or the Hello world programs or have a look at |
522 Sierpinski triangle or the Hello world programs or have a look at |
523 |
523 |
524 \begin{center} |
524 \begin{center} |