Skip to content

Instantly share code, notes, and snippets.

@SonOfLilit
Created June 26, 2017 22:56
Show Gist options
  • Save SonOfLilit/67f1b35973be90b6d721d3e08fe6556b to your computer and use it in GitHub Desktop.
Save SonOfLilit/67f1b35973be90b6d721d3e08fe6556b to your computer and use it in GitHub Desktop.
Live coded during my "Virtual Machines and Brainfuck" talk at PyConIL 2017
import sys
def parse_parens(code):
result = {}
stack = []
for i, c in enumerate(code):
if c == '[':
stack.append(i)
elif c == ']':
match = stack.pop()
result[i] = match
result[match] = i
return result
assert parse_parens('') == {}
assert parse_parens('[]') == {0: 1, 1: 0}
assert parse_parens('[+]') == {0: 2, 2: 0}
assert parse_parens('[+[]]') == {0: 4, 4: 0, 2: 3, 3: 2}
def bf(code, input=''):
def get():
if get.i >= len(input):
return ''
char = input[get.i]
get.i += 1
return char
get.i = 0
output = []
def put(char):
output.append(char)
brainfuck(code, getchar=get, putchar=put)
return ''.join(output)
def brainfuck(code, getchar=lambda: sys.stdin.read(1), putchar=sys.stdout.write):
matched_parens = parse_parens(code)
memory = [0] * 40000
cursor = 0
instruction_pointer = 0
while instruction_pointer < len(code):
instruction = code[instruction_pointer]
if instruction == '+':
memory[cursor] = (memory[cursor] + 1) % 255
elif instruction == '-':
memory[cursor] = (memory[cursor] - 1) % 255
elif instruction == '<':
cursor = (cursor - 1) % len(memory)
elif instruction == '>':
cursor = (cursor + 1) % len(memory)
elif instruction == '[':
if memory[cursor] == 0:
instruction_pointer = matched_parens[instruction_pointer]
elif instruction == ']':
instruction_pointer = matched_parens[instruction_pointer]
continue
elif instruction == ',':
char = getchar()
if char == '':
break
memory[cursor] = ord(char)
elif instruction == '.':
putchar(chr(memory[cursor]))
else:
# everything else is a comment
pass
instruction_pointer += 1
#print instruction_pointer, memory[:10]
assert bf('') == ''
assert bf('++++++++++.') == '\n'
assert bf('+++++++++++++.---.') == '\r\n'
assert bf('++++++++[>++++++++<-]>+.') == 'A'
assert bf('+++[>,.<-]', 'abcde') == 'abc'
assert bf('+[>,.<]', 'abcde') == 'abcde'
assert bf(bf('+++++++++[<+++++>-],[[-<--.++<+>>]<+.-<[->.<]>>,]', 'hello, world!')) == 'hello, world!'
def main():
assert len(sys.argv) == 2, 'usage: bf.py <code>'
_, code = sys.argv
brainfuck(code)
return 0
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment