Created
January 10, 2011 01:59
-
-
Save maxcountryman/772244 to your computer and use it in GitHub Desktop.
Brainfuck converter and interpreter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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