Generic 2D Brainfuck

Generic 2D Brainfuck is a language created in 2015 by User:Hppavilion1. It is, as the name suggests, a generic 2-Dimensional brainfuck-based language. It operates on both a 2-Dimensional variant of Brainfuck's tape as well as using a 2-Dimensional program.
==Language Overview==
Generic 2D Brainfuck is basically just brainfuck, but the program and tape are 2D. The way it is designed makes it entirely backwards-compatible with vanilla brainfuck (except for comment conflicts). The commands are as such:
Command	Description
> 	Move the pointer to the right
< 	Move the pointer to the left
^ 	Move the pointer upwards
v 	Move the pointer downwards
u 	Set the program counter direction to up
d 	Set the program counter direction to down
l 	Set the program counter direction to left
r 	Set the program counter direction to right
+ 	Increment the memory cell under the pointer
- 	Decrement the memory cell under the pointer
. 	Output the character signified by the cell at the pointer
, 	Input a character and store it in the cell at the pointer
[ 	Jump past the matching ] (following the program counter direction) if the cell under the pointer is 0
] 	Jump back to the matching [ (following the program counter direction) if the cell under the pointer is nonzero
==History==
Generic 2D Brainfuck was created by Hppavilion1 in 2015. There hasn't been much time for history to be made.
==Examples==
As Generic 2D Brainfuck is almost backwards-compatible with Brainfuck, many examples can be found on the normal brainfuck page (but only one-line examples will work (but multiline examples can be condensed)).
One thing which will only work in this language is the following "Hello, World!" implementation, which takes advantage of the 2-dimensional space in both the program and the tape.
d r^---.+++++++..+++.^^.v-.v.+++.------.--------.^^+.
 u l
r++++++++[^++++[^++^+++^+++^+vvvv-]^+^+^-^^+[v]v-]^^.u
==Implementations==
This is an implementation in Python.
def run_generic_2d_brain(code_string: str, textfile = False) -> None:
 pointer = (0, 0) # for instructions
 row = 0 # for up and down tape
 column = 0 # for left and right tape
 direction = 'r' # for direction
 tape = [[0]]
 input_string = chr(10) # allows multiple inputs easily
 nest_counter = 0 # allows code with nested parentheses to work
 # this checks if the code is in a loop and what caused the loop
 # it can be [ or ], or _ if not in a loop
 loop_maker = '_'
 code = []
 if textfile:
 for line in open(code_string, 'r'):
 code.append(line.strip('\n'))
 else:
 code = code_string.split('\n')
 code_width = max([len(line) for line in code])
 while 0 <= pointer[0] < len(code) and 0 <= pointer[1] < code_width:
 # variable names look cleaner and indicate actual direction when incremented
 down = pointer[0]
 right = pointer[1]
 if right >= len(code[down]) or code[down][right] not in '><^vudlr+-.,[]':
 pass
 else:
 char = code[down][right]
 if loop_maker in '[]':
 if char in '[]':
 nest_counter = nest_counter + 1 if loop_maker == char else nest_counter - 1
 if nest_counter == 0:
 loop_maker = '_'
 else:
 if char in 'udlr':
 direction = char
 elif char == '>':
 column += 1
 if column == len(tape[row]):
 for row_number in range(len(tape)):
 tape[row_number].append(0)
 elif char == '<':
 column -= 1
 if column < 0:
 for row_number in range(len(tape)):
 tape[row_number] = [0] + tape[row_number]
 column += 1
 elif char == 'v':
 row += 1
 if row == len(tape):
 tape.append([0]*(column+1))
 elif char == '^':
 row -= 1
 if row < 0:
 tape = [[0]*(column+1)] + tape
 row += 1
 elif char == '+':
 tape[row][column] = (tape[row][column] + 1) % 256
 elif char == '-':
 tape[row][column] = (tape[row][column] - 1) % 256
 elif char == '.':
 print(chr(tape[row][column]),end=)
 elif char == ',':
 if input_string == chr(10):
 input_string = input(">>") + chr(10)
 # the following thing has to make sure
 # the input isn't an empty string
 if len(input_string) > 0 and ord(input_string[0]) != chr(10):
 tape[row][column] = ord(input_string[0])
 input_string = input_string[1:]
 elif char in '[':
 if tape[row][column] == 0:
 loop_maker = '['
 nest_counter = 1
 elif char == ']':
 if tape[row][column] != 0:
 loop_maker = ']'
 nest_counter = 1
 # sets direction
 if (loop_maker == ']' and direction == 'd') or (loop_maker != ']' and direction == 'u'): # normally up
 pointer = (pointer[0] - 1, pointer[1])
 elif (loop_maker == ']' and direction == 'u') or (loop_maker != ']' and direction == 'd'): # normally down
 pointer = (pointer[0] + 1, pointer[1])
 elif (loop_maker == ']' and direction == 'r') or (loop_maker != ']' and direction == 'l'): # normally left
 pointer = (pointer[0], pointer[1] - 1)
 else: # normally right
 pointer = (pointer[0], pointer[1] + 1)
Category:Brainfuck derivatives
Category:2015
Category:Two-dimensional languages
Category:Languages
Category:Turing complete
Category:Turing tarpits
Category:Implemented
Category:Cell-based
Category:Low-level