Generic 2D Brainfuck

From Esolang
Jump to navigation Jump to search
Generic 2D Brainfuck
Paradigm(s) imperative, multi-dimensional
Designed by User:Hppavilion1
Appeared in 2015
Memory system tape-based (2d)
Dimensions two-dimensional
Computational class Turing complete
Major implementations None Yet
Influenced by Brainfuck
File extension(s) .2b

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)