h/plugins/bf.py

85 lines
2.2 KiB
Python
Raw Normal View History

2009-03-15 06:51:39 +00:00
'''brainfuck interpreter adapted from (public domain) code at
http://brainfuck.sourceforge.net/brain.py'''
import re
import random
from util import hook
2009-03-15 06:51:39 +00:00
BUFFER_SIZE = 5000
2009-03-15 07:14:45 +00:00
MAX_STEPS = 1000000
2009-03-15 06:51:39 +00:00
@hook.command
def bf(input):
2009-03-15 07:14:45 +00:00
"""Runs a Brainfuck program."""
program = re.sub('[^][<>+-.,]', '', input)
2009-03-15 06:51:39 +00:00
# create a dict of brackets pairs, for speed later on
2009-03-15 07:14:45 +00:00
brackets={}
open_brackets=[]
2009-03-15 06:51:39 +00:00
for pos in range(len(program)):
if program[pos] == '[':
2009-03-15 07:14:45 +00:00
open_brackets.append(pos)
2009-03-15 06:51:39 +00:00
elif program[pos] == ']':
2009-03-15 07:14:45 +00:00
if len(open_brackets) > 0:
brackets[pos] = open_brackets[-1]
brackets[open_brackets[-1]] = pos
open_brackets.pop()
2009-03-15 06:51:39 +00:00
else:
return 'unbalanced brackets'
2009-03-15 07:14:45 +00:00
if len(open_brackets) != 0:
return 'unbalanced brackets'
2009-03-15 06:51:39 +00:00
# now we can start interpreting
2009-03-15 07:14:45 +00:00
ip = 0 # instruction pointer
2009-03-15 06:51:39 +00:00
mp = 0 # memory pointer
steps = 0
2009-03-15 06:51:39 +00:00
memory = [0] * BUFFER_SIZE #initial memory area
rightmost = 0
output = "" #we'll save the output here
2009-03-15 06:51:39 +00:00
# the main program loop:
2009-03-15 07:14:45 +00:00
while ip < len(program):
c = program[ip]
2009-03-15 06:51:39 +00:00
if c == '+':
memory[mp] = memory[mp] + 1 % 256
elif c == '-':
memory[mp] = memory[mp] - 1 % 256
elif c == '>':
2009-03-15 07:14:45 +00:00
mp += 1
2009-03-15 06:51:39 +00:00
if mp > rightmost:
rightmost = mp
if mp >= len(memory):
# no restriction on memory growth!
memory.extend([0]*BUFFER_SIZE)
2009-03-15 06:51:39 +00:00
elif c == '<':
mp = mp - 1 % len(memory)
elif c == '.':
output += chr(memory[mp])
if len(output) > 500:
break
2009-03-15 07:14:45 +00:00
elif c == ',':
memory[mp] = random.randint(1, 255)
2009-03-15 07:14:45 +00:00
elif c == '[':
2009-03-15 06:51:39 +00:00
if memory[mp] == 0:
2009-03-15 07:14:45 +00:00
ip = brackets[ip]
elif c == ']':
2009-03-15 06:51:39 +00:00
if memory[mp] != 0:
2009-03-15 07:14:45 +00:00
ip = brackets[ip]
2009-03-15 07:14:45 +00:00
ip += 1
2009-03-15 06:51:39 +00:00
steps += 1
2009-03-15 07:14:45 +00:00
if steps > MAX_STEPS:
2009-03-15 06:51:39 +00:00
output += "Maximum number of steps exceeded"
break
2009-05-15 03:07:31 +00:00
output = '/'.join(output.splitlines())
2009-07-08 17:28:15 +00:00
2009-05-15 03:07:31 +00:00
if output == '':
return 'no output'
2009-07-08 17:28:15 +00:00
2009-05-15 03:07:31 +00:00
return unicode(output, 'iso-8859-1')[:430]