Skip to content

Instantly share code, notes, and snippets.

@maxcountryman
Created January 10, 2011 01:59
Show Gist options
  • Save maxcountryman/772244 to your computer and use it in GitHub Desktop.
Save maxcountryman/772244 to your computer and use it in GitHub Desktop.
Brainfuck converter and interpreter
class Converter(object):
'''Converts a string to Brainfuck.'''
def __init__(self, string):
self.output = self._parse(string)
def _parse(self, string):
'''Takes a string, redefines it as a list containing its ASCII values,
rounds the values down, creates loop cells using those values, minus
the first decimal, i.e. 72 becomes 70 and then 7, this is because the
loop will mutiply these values by 10. Finally the value that was
rounded out, e.g. 2 in 72 will be used in the body cells.
'''
prefix = '++++++++++'
string = map(ord, string)
rounded = map(lambda x : x - (x % 10), string)
fst_two = map(lambda x : x / 10, rounded)
loop_cells = map(lambda x : '+' * x, fst_two) #we increment by tens
loop_body = ''.join(map(lambda x: '>' + x, loop_cells)) #prefix '>' move to next cell
loop_suffix = '<' * len(string) + '-' #decrement once per iteration
fst_dec = map(lambda x: x[0] - x[1], zip(string, rounded))
body_cells = map(lambda x : '+' * x, fst_dec)
body = ''.join(['>' + i + '.' for i in body_cells])
output = '{0}[{1}{2}]{3}'.format(prefix, loop_body, loop_suffix, body)
return output
class Loop(object):
'''Used by `loopstack` to hold the position of the cell prefixing the loop.'''
def __init__(self, prefix):
self.prefix = prefix
class Interpreter(object):
'''Takes raw Brainfuck input, returns the parsed result as `output`.'''
def __init__(self, raw):
self.output = self._parse(raw)
def _parse(self, raw):
tape = [0] * 30000 #thirty-thousand cells
cell = 0
loopstack = []
output = ''
pointer = 0
while pointer < len(raw):
instr = raw[pointer]
if instr == '>':
cell += 1
elif instr == '<':
cell -= 1
elif instr == '+':
tape[cell] += 1
elif instr == '-':
tape[cell] -= 1
elif instr == '.':
output += chr(tape[cell])
elif instr == '[':
loopstack.insert(0, Loop(pointer))
elif instr == ']':
loop = loopstack.pop(0)
if tape[cell] != 0:
pointer = loop.prefix
loopstack.insert(0, loop)
pointer += 1
return output
if __name__ == '__main__':
b = Converter('Problem?')
print('Brainfuck: {0}'.format(b.output))
a = Interpreter(b.output)
print('Interpreted: {0}'.format(a.output))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment