BFFB
BFFB (Brainfuck fucks brains) is a joke language (devised by User:Feuermonster, 2012) whose acronym incidentally is a palindrome. BFFB programs are essentially brainfuck programs with just one little restriction. Due to popular request BFB is an abbreviation for BFFB, incidentally both are palindromic. BFB is the official file extension for BFFB programs.
Restriction
Any given program P consisting of a list of instructions L is a valid program:
iff P ∈ BF where BF is the set of all valid brainfuck programs. and iff L = mirror(L)
Where mirror is a function "mirroring" characters
[ → ] ] → [ > → < < → > + → + - → - . → . , → ,
Example:
[><] | [><]
An easy way to turn brainfuck programs into valid BFFB programs would be to put
[-]+[]
at the end of the brainfuck program and then mirror it.
Examples
[-]
is a perfectly valid BFFB program.
[>]
is not a valid BFFB program.
Cat Program
,[.,][,.],
The second part of the program never runs because the first loop never ends.
Implementations
This is an implementation in Python. It assumes all non-BF characters in the original code are comments and only analyzes the BF characters for symmetry purposes.
# runs language from https://esolangs.org/wiki/BFFB
# textfile indicates whether the string is a textfile
# starting_input indicates what the starting input should be, in case it shouldn't be taken from the text
def run_bffb(rawcode: str, textfile=False, starting_input='') -> None:
pointer = 0 # for instructions
location = 0 # for tape
tape = [0]
input_string = starting_input # allows multiple inputs to happen easily
if textfile:
with open(rawcode, 'r') as s:
code = [char for char in ''.join(s.readlines()) if char in set('+-><,.[]')]
else:
code = [char for char in rawcode if char in set('+-><,.[]')]
mirror = {'+': '+',
'-': '-',
'>': '<',
'<': '>',
',': ',',
'.': '.',
'[': ']',
']': '['}
for x in range(len(code)):
first, last = code[x], code[len(code) - 1 - x]
if mirror[first] != last:
raise SyntaxError(f'{first} is not the mirror image of {last}')
corresponding_bracket = {} # dictionary where the values are the corresponding bracket positions of the keys
bracket_stack = [] # acts as a stack for the last bracket
for num, char in enumerate(code):
if char == '[':
bracket_stack.append(num)
elif char == ']':
if len(bracket_stack) <= 0:
raise ValueError('unmatched ]')
corresponding_bracket[num] = bracket_stack[-1]
corresponding_bracket[bracket_stack[-1]] = num
bracket_stack.pop()
if len(bracket_stack) != 0:
raise ValueError('unmatched [')
while pointer < len(code):
if code[pointer] == '>':
location += 1
if location == len(tape):
tape.append(0)
elif code[pointer] == '<':
if location <= 0:
raise ValueError('Cannot move left from position 0')
location -= 1
elif code[pointer] == '+':
tape[location] = (tape[location] + 1) % 256
elif code[pointer] == '-':
tape[location] = (tape[location] - 1) % 256
elif code[pointer] == '.':
print(chr(tape[location]), end='')
elif code[pointer] == ',':
if input_string == '':
input_string = input(">>")
if len(input_string) > 0:
tape[location] = ord(input_string[0])
input_string = input_string[1:]
elif code[pointer] == '[':
if tape[location] == 0:
pointer = corresponding_bracket[pointer]
elif code[pointer] == ']':
if tape[location] != 0:
pointer = corresponding_bracket[pointer]
pointer += 1