\brainfuck is a programming language supposed to resemble a working Turing machine and it consists of only eight commands.
A program written in \brainfuck makes use of sequences of these commands and
said sequence might actually have other characters in between that are promptly ignored and treated as comments instead.
The way \brainfuck works includes a program and an instruction pointer, an array of
byte cells initialized to 0 as well as a movable data pointer, starting from the leftmost
position, to address such cells with the given instructions.
What's more \brainfuck makes use of the ASCII encoding for inputs and outputs.
The eight commands \brainfuck is based on are the following:
\begin{itemize}
\item[]\texttt{\textbf{\Large >}} : increments the data pointer to point the cell to the right;
\item[]\texttt{\textbf{\Large <}} : decrements the data pointer to point the cell to the left;
\item[]\texttt{\textbf{\Large +}} : increases by one the byte at the data pointer;
\item[]\texttt{\textbf{\Large -}} : decreases by one the byte at the data pointer;
\item[]\texttt{\textbf{\Large .}} : prints as output the byte at the data pointer;
\item[]\texttt{\textbf{\Large ,}} : asks for an input to store in the byte at the data pointer;
\item[]\texttt{\textbf{\Large [}} : if the byte at the data pointer is zero, jumps forward to the command after the matching \texttt{\textbf{]}} command instead of advancing the instruction pointer to the next instruction;
\item[]\texttt{\textbf{\Large ]}} : if the byte at the data pointer is non-zero, jumps backward to the command before the matching \texttt{\textbf{[}} command instead of advancing the instruction pointer to the next instruction;
You have two different options to run the program: a GUI and a CLI.
For the GUI open the ``\texttt{gui.rkt}'' file from either the `DrRacket' environment or the
Racket CLI tool.
As for the CLI version of the program you should use the ``\texttt{./cli.rkt}'' command followed by your ``\texttt{filename.bf}'' \brainfuck file that you want to execute.
The entire program revolves around the main struct defined as:\\
\texttt{
; A ProgState is a (prog-state tape dp output program ip) where: \\
; - tape: Tape\\
; - dp: DataPointer\\
; - tape-len: Nat\\
; - output: String\\
; - program: Program\\
; - ip: InstructionPointer\\
; - error: Option<ErrorCode>\\
; Interpretation: the current state of execution of a brainf*ck program.\\\\
\textbf{\large (struct prog-state (tape dp tape-len output program ip error)}}
And, likewise, each term in the struct has its own type definition: \\
\texttt{
; A Byte is an Int between 0 and 255 \\
; Interpretation: a byte in decimal notation.\\\\
; A Tape is a NEList<Byte>\\
; Interpretation: a tape in brainf*ck's Turing machine.\\\\
; A DataPointer (DP) is a NonNegInt\\
; Interpretation: a data pointer in the \brainfuck language in a tape.\\\\
; A Program is a String of:\\
; - ">" (tape-right)\\
; - "<" (tape-left)\\
; - "+" (add1)\\
; - "-" (sub1)\\
; - "." (out)\\
; - ","\\
; - "[" (loop-start)\\
; - "]" (loop-end)\\
; Interpretation: the brainf*ck program.\\\\
; A InstructionPointer (IP) is a NonNegInt\\
; Interpretation: a pointer to the instruction to execute.\\\\
; An ErrorCode is one of:\\
; - 'error1\\
; Interpretation: an error code for the bf interpreter.}
\subsubsection{Execute Function}
The main aspects of the \texttt{execute} function, other than executing the program, include:
\begin{itemize}
\item[-] The world state previously defined as a program state
\item[-] An asynchronous function call to get the user input when required by the program
\item[-] A callback function call defined as ``\texttt{done}'' which is called when an instruction is executed and that returns \texttt{\#false} when the program is at its last instruction.
\end{itemize}
\subsubsection{Interpreter Execution}
In order to parse the \brainfuck instructions correctly and ignore all other characters
in a \brainfuck file, the execute function requires a \texttt{cond} to give a condition to
each valid \brainfuck character and call the right function.
List of helper functions for execute:
\begin{itemize}
\item[]\textbf{\large\texttt{exec-tape-right}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the $>$ instruction executed.
\item[]\textbf{\large\texttt{exec-tape-left}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the $<$ instruction executed.
\item[]\textbf{\large\texttt{exec-add1}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the $+$ instruction executed.
\item[]\textbf{\large\texttt{exec-sub1}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the $-$ instruction executed.
\item[]\textbf{\large\texttt{exec-out}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the . instruction executed.
\item[]\textbf{\large\texttt{exec-loop-start}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the $[$ instruction executed.
\item[]\textbf{\large\texttt{exec-loop-end}}:\\ ProgState -$>$ ProgState\\ Given a ProgState, returns a new ProgState with the $]$ instruction executed.
\item[]\textbf{\large\texttt{exec-in}}:\\ ProgState ((Byte -$>$\_) -$>$\_) (ProgState -$>$\_) -$>$\_\\ Given a ProgState, a function that takes a callback function requiring a Byte and a function which takes the new ProgState, calls done with the input provided by get-input (provided by the call to the callback given in get-input).