Linear bounded brainfuck

From Esolang
Jump to navigation Jump to search

Linear bounded brainfuck is brainfuck as a linear bounded automaton, created by User:PythonshellDebugwindow.

The input-size function

The function of the input-size used is , where is the length of the input (1 if no input) and is the length of the program.

Commands

The same as in brainfuck, but minus input (which is preloaded onto the tape). The tape without input on it is initialized to all zeros, and all cells are bytes.

Command Description
> Move the pointer to the right
< Move the pointer to the left
+ Increment the memory cell under the pointer
- Decrement the memory cell under the pointer
. Output the character signified by the cell at the pointer
[ Jump past the matching ] if the cell under the pointer is 0
] Jump back to the matching [ if the cell under the pointer is nonzero

Going out of the tape bounds causes the program to error and exit.

Examples

Cat program

This version doesn't actually error at the end because for an input of length p, it has a tape of length p + 4.

[.>]

This version does error at the end because it keeps going along the tape.

[.>]+[>+]

Truth-machine

[>+>+<<-]>------------------------------------------------[>.<].

Implementation

def run_lbf(code: str, textfile=False, starting_input='') -> None:
    pointer = 0  # for instructions
    location = 0  # for tape
    counter = 0

    if textfile:
        code = ''.join(open(f'{code}', 'r').readlines())
    corresponding_bracket = {}  # dictionary where the values are the corresponding bracket positions of the keys
    bracket_stack = []  # acts as a stack for the last bracket

    for num, char in enumerate(code):
        if char == '[':
            bracket_stack.append(num)
        elif char == ']':
            assert len(bracket_stack) > 0, 'unmatched ]'
            corresponding_bracket[num] = bracket_stack[-1]
            corresponding_bracket[bracket_stack[-1]] = num
            bracket_stack.pop()
    assert len(bracket_stack) == 0, 'unmatched ['

    tape = [ord(x) for x in starting_input] + ([0] * len(code))

    while pointer < len(code):
        if code[pointer] == '>':
            location += 1
            assert location < len(tape), f'Cannot move right from position {len(tape)}'
        elif code[pointer] == '<':
            assert location > 0, 'Cannot move left from position 0'
            location -= 1
        elif code[pointer] == '+':
            tape[location] = (tape[location] + 1) % 256
        elif code[pointer] == '-':
            tape[location] = (tape[location] - 1) % 256
        elif code[pointer] == '.':
            print(chr(tape[location]), end='')
        elif code[pointer] == '[':
            if tape[location] == 0:
                pointer = corresponding_bracket[pointer]
        elif code[pointer] == ']':
            if tape[location] != 0:
                pointer = corresponding_bracket[pointer]
        pointer += 1