Sat, 01 Jul 2006

brainf*ckのインタプリタ

Pythonで簡易インタプリタを書いてみた。本当に"hello world!"って出力 されるのか試してみたかったので。("[]"のネストには対応してません。)

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

(参考) ASCII文字コード : IT用語辞典 e-Words

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

def do_bf(data):
    """
    $ echo "++++[>++++++++++<-]>++++++++." | python brainfuck.p
    0
    $ echo "++++[>++++++++++<-]>+++++++++." | python brainfuck.p
    1

    ++++[>++++++++++<-]>++++++++     # asciiで数字を表示するためにincrement
    >+<++>[-<+>]<.                   # 1+2
    """
    bf_ptr = 0
    bf_array = [0]*255
    bf_stack = []
    bf_stdin = []

    count = 0
    data_len = len(data)

    while(count < data_len):
        d = data[count]
        if d == '+':
            bf_array[bf_ptr] += 1
        elif d == '-':
            bf_array[bf_ptr] -= 1
        elif d == '>':
            bf_ptr += 1
        elif d == '<':
            bf_ptr -= 1
        elif d == '.':
            sys.stdout.write(chr(bf_array[bf_ptr]))
        elif d == ',':
            if bf_stdin:
                bf_array[bf_ptr] = bf_stdin.pop(0)
            else:
                bf_stdin = map(ord,list(raw_input('\nbf > ')))
                if not bf_stdin:
                    sys.stdout.write('\n')
                    continue
                else:
                    bf_array[bf_ptr] = bf_stdin.pop(0)
        elif d == '[':
            if bf_array[bf_ptr] != 0:
                bf_stack.append(count)
            else:
                count += 1
                while(count < data_len):
                    d = data[count]
                    if d == ']':
                        break
                    count += 1
        elif d == ']':
            count = bf_stack.pop()
            continue
        count += 1

    sys.stdout.write('\n')

if __name__ == '__main__':
    if len(sys.argv) < 2:
        data = sys.stdin
    else:
        data = file(sys.argv[1],'rU')
    do_bf(data.read())

Thu, 29 Jun 2006