パイパイでFu*kしてみる

PyPy 1.4がリリースされたそうなので、brainfu*kインタープリタを書いて見ました.

brainfu*kについてはスタート ガイド: Python - Google App Engine — Google Developersなどを参照.

#bf.py
import re
from collections import defaultdict
import sys

def brace_pairs(commands):
    stack = []
    table = []
    for i, c in enumerate(commands):
        if c == "]":
            table.append((stack.pop(-1), i))
        elif c == "[":
            stack.append(i)
    return table

def bf(src):
    commands = [c for c in src if c in "><+-.,[]"]

    t = brace_pairs(commands)
    jump_table = dict()
    jump_table.update(t)
    jump_table.update((end, begin) for begin, end in t)
    
    ptr = 0
    i = 0
    buf = defaultdict(int)
    
    while i < len(commands):
        c = commands[i]
        if c == ">":
            ptr += 1
        elif c == "<":
            ptr -= 1
        elif c == "+":
            buf[ptr] += 1
        elif c == "-":
            buf[ptr] -= 1
        elif c == ".":
            sys.stdout.write(chr(buf[ptr]))
        elif c == ",":
            buf[ptr] = ord(sys.stdin.read(1))
        elif c == "[":
            if buf[ptr] == 0:
                i = jump_table[i]
        elif c == "]":
            if buf[ptr] != 0:
                i = jump_table[i]
        else:
            assert False
        i += 1

def main():
    bf(open(sys.argv[1]).read())
    
if __name__ == "__main__":
    main()


まず、普通のpythonで実行.

> python bf.py hello.bf
hello world!


次にpypyで実行.PyPy :: Download and installから, 自分のOS用のバイナリをダウンロードして解凍.
win32版では, MSVCR100.dllを要求されました. 適当にMSVCR100.dllをダウンロードして, pypy\pypy.exeと同じ場所に置きます.

pypy\pypy.exe bf.py hello.bf
hello world!


こんな短いコードじゃしょうがないですが, 動くことは確認できました.