Loose Circular Brainfuck (LCBF)
(Redirected from Loose Circular Brainfuck)
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)