Loose Circular Brainfuck (LCBF)
Jump to navigation
Jump to search
Loose Circular Brainfuck (LCBF) is created by Maurice Ling and is a derivative of Brainfuck. It is originally meant as a generic mechanism to test out different varieties of assembly or op-code typed languages.
LCBF uses all 8 operations of Brainfuck with major differences in the tape and the loop operations.
Differences from Brainfuck
- The tape or array is circular (a ring list) instead of linear. When the pointer is at the "end" of the tape, an increment (">") will move the tape to the start. Similarly, when the pointer is decremented at the "beginning" of the tape, the pointer goes to the end.
- Operations after a start loop operator ("[") will only be executed provided the loop(s) are properly closed. If the loops are open, the program will terminate.
- However, it is possible to have an end loop operator ("]") without a preceding start loop operator ("["). In this case, the end loop operator ("]") will be ignored and execution continues.
- Unclosed or unopened loops may result in non-deterministic behaviour.
- All inputs are pre-defined at the start of the program.
Python Implementation
def increment(array, apointer, inputdata, output, source, spointer):
array[apointer] = array[apointer] + 1
return (array, apointer, inputdata, output, source, spointer)
def decrement(array, apointer, inputdata, output, source, spointer):
array[apointer] = array[apointer] - 1
return (array, apointer, inputdata, output, source, spointer)
def forward(array, apointer, inputdata, output, source, spointer):
return (array, apointer + 1, inputdata, output, source, spointer)
def backward(array, apointer, inputdata, output, source, spointer):
return (array, apointer - 1, inputdata, output, source, spointer)
def call_out(array, apointer, inputdata, output, source, spointer):
output.append(array[apointer])
return (array, apointer, inputdata, output, source, spointer)
def accept_predefined(array, apointer, inputdata, output, source, spointer):
if len(inputdata) > 0: array[apointer] = inputdata.pop(0)
else: array[apointer] = 0
return (array, apointer, inputdata, output, source, spointer)
def cbf_start_loop(array, apointer, inputdata, output, source, spointer):
if array[apointer] > 0:
return (array, apointer, inputdata, output, source, spointer)
else:
count = 1
try:
while count > 0:
spointer = spointer + 1
if source[spointer] == ']':
count = count - 1
if source[spointer] == '[':
count = count + 1
except IndexError:
spointer = len(source) - 1
return (array, apointer, inputdata, output, source, spointer)
def cbf_end_loop(array, apointer, inputdata, output, source, spointer):
temp = spointer
if array[apointer] < 1:
return (array, apointer, inputdata, output, source, spointer + 1)
else:
count = 1
try:
while count > 0:
spointer = spointer - 1
if source[spointer] == ']':
count = count + 1
if source[spointer] == '[':
count = count - 1
except IndexError:
spointer = temp
return (array, apointer, inputdata, output, source, spointer)
LCBF = {'+': increment,
'-': decrement,
'>': forward,
'<': backward,
'.': call_out,
',': accept_predefined,
'[': cbf_start_loop,
']': cbf_end_loop,
}
def interpret(source, functions,
function_size=1, inputdata=[],
array=None, size=30):
spointer = 0
apointer = 0
output = list()
if array == None:
array = [0] * size
if len(array) > size:
array = array[0:size]
if len(source) % function_size != 0:
source = source + '!'*(function_size - \
len(source) % function_size)
tokens = functions.keys()
source = "".join([x for x in source if x in tokens])
while spointer < len(source):
try:
token = source[spointer:spointer+function_size]
(array, apointer, inputdata, output,
source, spointer) = functions[token](array, apointer,
inputdata, output,
source, spointer)
except KeyError:
print ' '.join(['Unknown function: ',
source[i:i+function_size],
'at source position',
str(i)])
if apointer > size:
apointer = apointer - size
if apointer < 0:
apointer = size + apointer
spointer = spointer + function_size
return (array, apointer, inputdata, output, source, spointer)
if __name__ == '__main__':
print interpret('++++++++++[>+++++<.-]', LCBF)
print interpret('++[>+++++<.-]>>>+++.', LCBF)
print interpret('++>+++++<.-]>>>+++.', LCBF)
print interpret('++>[+++++<.->>>+++.', LCBF)
print interpret('+++++[>++++[>+++.<-].<-]', LCBF)