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
linemode
join lines until a blank line is seen- comments (default: False) In
linemode
skip lines starting withcommentchar
- commentchar (default: #) Comment charachter for
comments
inlinemode
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.