Main¶
There are many brainfuck implementations (compilers/interpreters) and
therefore no need for yet another implementation.
But here it is.
The goal is to make something configurable, extendable and at the same time extensive in itself from the very beginning.
pybrainfuck will for sure not win any price for memory efficiency, speed or
size. But it can serve to experiment with the configuration options, extension
commands or who knows what.
The introduction has already shown how to use the BrainFck class and the
pybrainfuck script.
For the configuration options, take a look at the class reference or the scrip reference.
Using the BrainFck class¶
See the class reference for the full set configuration options and methods.
The most important methods for a external user are:
- ``runfiles`` which defined as ``def runfiles(self, *args)``
Each arg in args must be the path to a file containing a ``brainfuck``
program
- ``run`` which is defined as ``def run(self, f)``
f is either a file (or file-like) object or a string containing the program.
If a string is passed it will internally converted to a file-like object
before execution.
Those are the ones the end user pass the brainfuck programs too.
Formatting of the programs¶
Usually each brainfuck is contained in a single file. pybrainfuck
supports additional formats which can aid when it comes down to testing and
readability. The configuration options to support additional formats:
- linemode (default: False) Read the input in lines and interpret each line as a program skipping blank lines
- multiline (default: False) In
linemodejoin lines until a blank line is seen- comments (default: False) In
linemodeskip lines starting withcommentchar- commentchar (default: #) Comment charachter for
commentsinlinemode
Doing this configuration:
bfck = BrainFck(linemode=True, multiline=True, comments=True)
and applying it to the following file:
# Yo!
+[--->++<]>+++.[->+++++++<]>.[--->+<]>----.
# Hello World! (and newline)
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
# Prints H (and newline) after checking some pathological cases
[]++++++++++[>>+>+>++++++[<<+<+++>>>-]<<<<-]
"A*$";?@![#>>+<<]>[>>]<<<<[>++<[-]]>.>.
# Cell 30000 (prints # and newline)
++++[>++++++<-]>[>+++++>+++++++<<-]>>++++<[[>[[>>+<<-]<]>>>-]>-[>+>+<<-]>]+++++[>+++++++<<++>-]>.<<.
Results in the execution of 4 brainfuck programs. Lines starting with ‘#’
and blank lines will be skipped.
And the 2 line program (because ‘multiline’ was set to True) will be joined
Extending the command set¶
To aid in addind commands without tapping into the logic and internals of the
classavoid tapping into the internals of BrainFck a decorator is provided to
define commands.
Operation of the existing commands is defined by modifying the status
variables (see the class reference).
In regular brainfuck the commands + and - increment and decrement
the value of the current cell by 1.
To experiment with “shorter” programs which can increment/decrement by 2, let’s
add a couple of commands: " and =:
from pybrainfuck import BrainFck, BfCommand
class BrainFck2(BrainFck):
@BfCommand('"')
def proc_increment2(self):
self.cells[self.ptr] += 2
@BfCommand('=')
def proc_decrement2(self):
self.cells[self.ptr] -= 2
´Rather than directly modifying the status of the interpreter/machine the existing methods can be reused:
from pybrainfuck import BrainFck, BfCommand
class BrainFck2(BrainFck):
@BfCommand('"')
def proc_increment2(self):
self.proc_increment()
self.proc_increment()
@BfCommand('=')
def proc_decrement2(self):
self.proc_decrement()
self.proc_decrement()
This implementation makes use of the existing methods which manage the increment/decrement actions. This can also be done by looking up the command characters:
from pybrainfuck import BrainFck, BfCommand
class BrainFck2(BrainFck):
@BfCommand('"')
def proc_increment2(self):
method = self.cmd_procs['+']
method()
method()
@BfCommand('=')
def proc_decrement2(self):
method = self.cmd_procs['-']
method()
method()
The entire BrainFck class is fully documented, just see the reference to
modify the behaviors or add new ones.