Brain F***
Introduction
Brain F*** language was created in 1990s by Urban Müller. Its notable feature is its extreme minimalism. Each Brain F*** program consists of just eight instructions! Primary purpose of the language was to amaze other programmers rather than write any useful programs in it. Surprisingly it found its usage to demonstrate expresiveness of other programming languages. This article presents Brain F*** interpreter implemented in Never programming language. Compiler and interpreter implementation is based on C implementation by Robert de Bath found on RosettaCode site.
The following table lists Brain F*** instructions:
Command | Description |
---|---|
> | Move the memory pointer to the right |
< | Move the memory pointer to the left |
+ | Increment the memory cell under the memory pointer |
- | Decrement the memory cell under the memory pointer |
. | Print the character signified by the memory cell at the memory pointer |
, | Read a character and store it in the memory cell at the memory pointer |
[ | Jump past the matchin ] if the memory cell under the memory pointer is 0 |
] | Jump back to the mating [ if the memory cell under the memory pointer is not 0 |
Implementation
Data Structures
record BFI
{
cmd : char;
next : BFI;
jmp : BFI;
}
record MEM
{
val : int;
next : MEM;
prev : MEM;
}
Brain F**** compiler and interpreter uses BFI
record to store
list of instuctions linked with next
attribute. jmp
attribute
is used to point where a jump should be executed when [ or ] instruction
is executed. MEM
record is a double linked list through next
and
prev
attributes which stores memory values.
Algorithms
func compile(prog : string) -> BFI
{
var i = 0;
var n = BFI;
var p = BFI;
var j = BFI;
var pgm = BFI;
/*
* Only valid programs are accepted by the following function.
* Add each valid BF command onto the end of the program.
* The 'j' variable points at the list of currently open '[' commands,
* one is matched off by each ']'.
*/
for (i = 0; i < length(prog); i = i + 1) {
printc(prog[i]);
/* create program instruction */
n = BFI('0', nil, nil);
/* add it at the end program which begins at pgm */
if (p != nil) {
p.next = n
} else {
pgm = n
};
/* instruction name */
n.cmd = prog[i];
p = n;
/* if opening \[ was found push instruction pointer to stack */
if (prog[i] == '[') {
n.jmp = j;
j = n;
0
/* if closing \] was found pop instruction pointer from stack */
} else if (prog[i] == ']') {
n.jmp = j;
j = j.jmp;
n.jmp.jmp = n;
0
} else {
0
}
};
pgm
}
func exec(pgm : BFI) -> int
{
var m = MEM(0, nil, nil);
var n = BFI;
for (n = pgm; n != nil; n = n.next) {
/* increase memory cell */
if (n.cmd == '+') {
m.val = m.val + 1
/* decrease memory cell */
} else if (n.cmd == '-') {
m.val = m.val - 1
/* print character */
} else if (n.cmd == '.') {
printc(chr(m.val));
0
/* read character */
} else if (n.cmd == ',') {
m.val = read()
/* jump if value in memory is 0 */
} else if (n.cmd == '[') {
if (m.val == 0) {
n = n.jmp;
0
} else {
0
}
/* jump is value in memory is not 0 */
} else if (n.cmd == ']') {
if (m.val != 0) {
n = n.jmp;
0
} else {
0
}
/* move to previous memory cell */
} else if (n.cmd == '<') {
m = m.prev;
0
/* move to next memory cell. if not available extend memory */
} else if (n.cmd == '>') {
if (m.next == nil) {
m.next = MEM(0, nil, nil);
m.next.prev = m;
0
} else {
0
};
m = m.next;
0
} else {
0
}
};
0
}
func run(prog : string) -> int
{
var pgm = BFI;
pgm = compile(prog);
prints("\n");
exec(pgm);
0
}
func main() -> int
{
/* Hello World! */
run("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.");
#run("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.");
#prints("Adds two digits\n"); run(",>,[<+>-]<.");
#run(",>,.<.");
0
}
Brain F**** compiler and interpreter is implemeneted using two major
functions - compile
and exec
. Former function creates a list of instructions
and marks jumps which should be executed when [ or ] instruction is executed.
Later function executes instructions according to their specifiction.
Summary
I hope you liked this entry!