Brainf*ck in Python

箱根駅伝を見ながら、Python で brainf*ck インタプリタを実装してみました。
すでに偉大なる Pythonista 達の手により行われていること*1ではあるのですが、あえて車輪の再実装です。


インタプリタのコード (bf.py)

# -*- coding:utf-8 -*-
import sys
from array import array
from optparse import OptionParser

def bf_eval(expr, debug):
    loop_begin_ptr = []
    loop_end_ptr = []
    # 最初に "[", "]" の位置を走査
    for i, token in enumerate(expr):
        if token == '[':
            loop_begin_ptr.append(i)
        elif token == ']':
            loop_end_ptr.append(i)
    
    # 構文解析
    #   仕様 - http://ja.wikipedia.org/wiki/Brainfuck
    memory = array('b', [0]*256)
    ptr = 0;
    i = 0
    while i < len(expr):
        token = expr[i]
        if token == '>':
            ptr += 1
        elif token == '<':
            ptr -= 1
        elif token == '+':
            memory[ptr] += 1
        elif token == '-':
            memory[ptr] -= 1
        elif token == '.':
            sys.stdout.write(chr(memory[ptr]))
        elif token == ',':
            memory[ptr] = sys.stdin.read(1)
        elif token == '[':
            if memory[ptr] == 0:
                i = loop_end_ptr[loop_begin_ptr.index(i)] + 1
        elif token == ']':
            if memory[ptr] != 0:
                i = loop_begin_ptr[loop_end_ptr.index(i)]
        else:
            raise SyntaxError, i
        if debug:
            print "  ptr=%s" % ptr, memory[:16] # dump
        i += 1

if __name__ == '__main__':
    usage = 'bf.py [source-file]'
    version = '%prog 0.0.1'
    parser = OptionParser(usage=usage, version=version)
    parser.add_option(
            '-d', '--debug',
            action='store_true',
            help=u'1ステップごとにバイト配列をダンプします。とりあえず先頭16バイトのみ。',
            )
    options, args = parser.parse_args()

    if len(args) == 0:
        print u'ファイルが指定されていません。'
        sys.exit()
    
    buf = open(args[0]).read()
    if options.debug:
        bf_eval(buf, True)
    else:
        bf_eval(buf, False)


実行するソースコード (bf_hny.txt)

+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>--.+++++++++++++++..+++++++++.>-------------.<-----------.<+++++++++++++++++++++++++++++.>+++++++++.>.<++.<.----.+++++++++++++++++.>>+.


実行結果

C:\Documents and Settings\takanori\junks>python bf.py bf_hny.txt
Happy new year!

でた!