User:1hals/brainfuck
Jump to navigation
Jump to search
This is my brainfuck interpreter implementation in Python 3
#!/usr/bin/env python3 import sys EOF = 0 NUM_DEBUG_CELLS = 10 MEMORY_STEP = 1024 if len(sys.argv) != 2: print('Usage:') print(sys.argv[0], '[filename or -]') sys.exit() filename = sys.argv[1] if filename == '-': # Take program from standard input # With program input starting with '!' program_file = 'stdin' stdin = input() parts = stdin.split('!') if len(parts) == 2: program, input_text = parts else: program = parts[0] input_text = '' else: # Take program from given file # With program input from standard input program_file = open(filename, 'r') program = program_file.read() input_text = input() input_x = list(ord(x) for x in reversed(input_text)) program_len = len(program) memory = bytearray([0 for x in range(MEMORY_STEP)]) memory_len = len(memory) pointer = 0 program_counter = 0 cycles = 0 while program_counter < program_len: char = program[program_counter] if char == '>': # Move the pointer to the right pointer += 1 if pointer >= memory_len: # Get more memory self.memory += bytearray([0 for x in range(MEMORY_STEP)]) self.memory_len = len(memory) elif char == '<': # Move the pointer to the left pointer -= 1 elif char == '+': # Increment the memory cell at the pointer memory[pointer] += 1 if memory[pointer] > 255: memory[pointer] = 0 elif char == '-': # Decrement the memory cell at the pointer memory[pointer] -= 1 if memory[pointer] < 0: memory[pointer] = 255 program_counter += 1 elif char == '.': # Output the character signified by the cell at the pointer print(end=chr(memory[pointer])) elif char == ',': # Input a character and store it in the cell at the pointer try: memory[pointer] = input_x.pop() except IndexError: memory[pointer] = EOF elif char == '[': # Jump past the matching ] if the cell at the pointer is 0 if memory[pointer] == 0: index = None depth = 1 for i in range(program_counter + 1, program_len): char = program[i] if '[' == char: depth += 1 elif ']' == char: depth -= 1 if depth == 0: index = i break program_counter = index elif char == ']': # Jump back to the matching [ if the cell at the pointer is nonzero if memory[pointer] != 0: index = None depth = 1 for i in range(program_counter - 1, 0, -1): char = program[i] if ']' == char: depth += 1 elif '[' == char: depth -= 1 if depth == 0: index = i break program_counter = index elif '#' == char: # Debug: print first 10 cells print('#[%s...]' % ', '.join(str(x) for x in memory[:NUM_DEBUG_CELLS])) elif '$' == char: # Debug: print program counter print('$%d' % program_counter) elif '^' == char: # Debug: print pointer print('^%d' % pointer) elif '@' == char: # Debug: print cycle number print('@%d' % cycles) program_counter += 1 cycles += 1