Skip to content

Instantly share code, notes, and snippets.

@ivoscc
Last active August 22, 2016 13:33
Show Gist options
  • Save ivoscc/05ce118c2be505e0f3b2525e63cfae4e to your computer and use it in GitHub Desktop.
Save ivoscc/05ce118c2be505e0f3b2525e63cfae4e to your computer and use it in GitHub Desktop.
Brainfuck Interpreter
# -*- coding: utf-8 -*-
import os
import sys
import time
IP = 0 # Instruction pointer
DP = 0 # Data pointer
DATA = [0] * 20
OUTPUT = []
def search_matching_bracket(text, direction):
brackets = ("[", "]")
if direction == "backwards":
brackets = brackets[::-1] # use ("]", "[") instead
text = text[::-1] # revert text
same_bracket, matching_bracket = brackets
matching_found = 0
for index, char in enumerate(text):
if char == same_bracket:
matching_found -= 1
elif char == matching_bracket:
matching_found += 1
if matching_found == 1:
return index
raise Exception("Unbalanced brackets in program")
def jump_to_matching_bracket(program, current_position, direction):
if direction == 1: # search forward
index = search_matching_bracket(program[current_position:],
"forwards")
return current_position + index
else:
index = search_matching_bracket(program[:current_position],
"backwards")
return current_position - (index + 1)
def show_state(program):
os.system("clear")
state = (
"OUT: {output}\n"
"{program}\n{instruction_pointer}\n"
"{data}\n{data_pointer}^"
).format(
output="".join(OUTPUT),
program=program,
instruction_pointer=(" " * IP) + "^",
data="|" + "|".join(map(lambda x: str(x).rjust(3), DATA)) + "|",
data_pointer=(" " * DP) + " "
)
print state
if __name__ == "__main__":
# This BF program prints "Hello World!"
program = ("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++"
"++..+++.>>.<-.<.+++.------.--------.>>+.>++.")
DEBUG = '--debug' in sys.argv
while 1:
try:
next_instruction = program[IP]
except IndexError:
# we've reached the end of the program
show_state(program)
break
if DEBUG:
show_state(program)
time.sleep(0.01)
if next_instruction == ">":
DP += 1
elif next_instruction == "<":
DP -= 1
elif next_instruction == "+":
DATA[DP] += 1
if DATA[DP] > 255: # rollover to 0 when overflowing
DATA[DP] = 0
elif next_instruction == "-":
DATA[DP] -= 1
if DATA[DP] < 0: # rollover to 255 when underflowing
DATA[DP] = 255
elif next_instruction == ".":
OUTPUT.append(chr(DATA[DP]))
elif next_instruction == ",":
done = False
while not done:
try:
val = input("Enter a value (0-255):")
if 0 <= val <= 255:
done = True
DATA[DP] = val
except NameError:
pass
elif next_instruction == "[":
if DATA[DP] == 0:
IP = jump_to_matching_bracket(program, IP, 1)
elif next_instruction == "]":
if DATA[DP] != 0:
IP = jump_to_matching_bracket(program, IP, -1)
IP += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment