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