Loose Circular Brainfuck (LCBF)

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)
Category:Languages
Category:Brainfuck derivatives
Category:Turing complete
Category:Cell-based
Category:Implemented
Category:2012