Skip to content

Instantly share code, notes, and snippets.

@DavideCanton
Last active December 19, 2015 05:19
Show Gist options
  • Select an option

  • Save DavideCanton/5903223 to your computer and use it in GitHub Desktop.

Select an option

Save DavideCanton/5903223 to your computer and use it in GitHub Desktop.
Simple Brainfuck interpreter
__author__ = 'davide'
import numpy as np
LEFT, RIGHT, INCR, DECR, INPUT, OUTPUT, WHILE, WEND = range(8)
opcodes = {'<': LEFT,
'>': RIGHT,
'+': INCR,
'-': DECR,
',': INPUT,
'.': OUTPUT,
'[': WHILE,
']': WEND}
def assemble(code):
assembled = []
last_opened = []
ip = 0
for symbol in code:
opcode = opcodes.get(symbol)
if opcode is None:
ip -= 1
elif opcode == WHILE:
last_opened.append(ip)
assembled.append([WHILE, -1])
elif opcode == WEND:
last = last_opened.pop()
assembled[last] = [WHILE, ip + 1]
assembled.append([WEND, last + 1])
else:
assembled.append(opcode)
ip += 1
if last_opened:
raise ValueError("Invalid code!")
return assembled
def run(code, mem_size=3E4, debug=False):
mem = np.zeros(mem_size, dtype=np.uint8)
ip = 0
mp = 0
while ip < len(code):
instr = code[ip]
if instr == LEFT:
mp = (mp + mem_size - 1) % mem_size
elif instr == RIGHT:
mp = (mp + 1) % mem_size
elif instr == INCR:
mem[mp] += 1
elif instr == DECR:
mem[mp] -= 1
elif instr == INPUT:
input_str = input() or "\0"
mem[mp] = ord(input_str[0])
elif instr == OUTPUT:
print(chr(mem[mp]), end="")
else:
instr, jmp = instr
if instr == WHILE:
if not mem[mp]:
ip = jmp - 1
elif instr == WEND:
if mem[mp]:
ip = jmp - 1
ip += 1
if debug:
print("IP: {}".format(ip))
print("MP: {}".format(mp))
print("MEM: {}".format(mem))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment