Skip to content

Instantly share code, notes, and snippets.

@knightshrub
Created June 4, 2018 19:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knightshrub/08690bf52d7247e7fd4fbcd62b6d3034 to your computer and use it in GitHub Desktop.
Save knightshrub/08690bf52d7247e7fd4fbcd62b6d3034 to your computer and use it in GitHub Desktop.
A brainfuck interpreter written in python
#!/usr/bin/env python3
import sys
"""
A brainfuck interpreter written in python
Example usage: python3 brainfck.py test.bfck
Contents of test.bfck:
---------------------
,[-.>+<];
"""
# allocate memory
mem = [0]
# initialize data pointer
dp = 0
def last_index(l,what):
n = (len(l) - i - 1 for i,v in enumerate(reversed(l)) if v == what)
return next(n)
def loop(commands,main=False):
global mem
global dp
cp = 0
dp0 = dp
while True:
c = commands[cp]
if c == '>':
dp += 1
try:
mem[dp]
except IndexError:
mem += [0]
elif c == '<':
dp -= 1
elif c == '+':
mem[dp] += 1
elif c == '-':
mem[dp] -= 1
elif c == '.':
print(mem[dp])
elif c == ',':
mem[dp] = int(input())
elif c == '[':
j = last_index(commands,']')
loop(commands[cp+1:j+1])
commands = commands[:cp+1] + commands[j+1:]
# go back to start of the loop
if c == ']':
if not mem[dp0] and not main:
break
else:
cp = 0
elif c == ';' and main:
break
else:
cp += 1
# read the specified program file
with open(sys.argv[1]) as f:
program = list(''.join(f.read().split()))
loop(program,True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment