PythonによるBrainf*ckインタプリタ 1.01
PythonによるBrainf*ckインタプリタ @ NISHIO HIROKAZU # Archived COREBlogの改良版です。 便利な機能としては「入出力を数字にするモード(7を入力したいときに文字コード7のものを入れるとか、7の文字コードから0の文字コードを引くコードにしておく等の面倒なことが不要)」「ステップ実行」「メモリの内容表示」「#以降行末まではコメントになる」「コメント以外でもコードに使われる種類以外の文字は無視される」などです。
## 掛け算
,>,< # 2つ値を読み込む
[- # [0]の回数だけブロック内を繰り返し
>
[->+>+<<] # [1]の内容を[2], [3]に加算、[1]は0になる
>>[-<<+>>] # [3]の内容を[1]に加算(移動)、[3]は0になる
<<<
]
# -*- coding: cp932 -*-
#
# Brainf*ck Interpreter
#
import sys
IO_ORD = True
class BFInterpreter:
pointer = 0
caret = 0
code = ""
def __init__(self):
self.command = {
">": self.incPtr,
"<": self.decPtr,
"+": self.incValue,
"-": self.decValue,
".": self.putValue,
",": self.getValue,
"[": self.jumpIfZero,
"]": self.backJump
}
self.memSpace = {}
def incPtr(self):
self.pointer += 1
self.caret += 1
def decPtr(self):
self.pointer -= 1
self.caret += 1
def incValue(self):
ptr = self.pointer
v = self.memSpace.get(ptr, 0)
self.memSpace[ptr] = (v + 1) % 256
self.caret += 1
def decValue(self):
ptr = self.pointer
v = self.memSpace.get(ptr, 0)
self.memSpace[ptr] = (v + 255) % 256
self.caret += 1
def putValue(self):
value = self.memSpace.get(self.pointer, 0)
if IO_ORD:
print value,
else:
sys.stdout.write(chr(value))
self.caret += 1
def getValue(self):
data = raw_input("bf>")
if IO_ORD:
self.memSpace[self.pointer] = int(data) % 256
else:
self.memSpace[self.pointer] = ord(data[0]) % 256
self.caret += 1
def jumpIfZero(self):
if self.memSpace.get(self.pointer, 0) == 0:
c = self.caret + 1
depth = 1
while c < len(self.code):
cod = self.code[c]
if cod == "]":
depth -= 1
elif cod == "[":
depth += 1
if depth == 0:
break
c += 1
else:
raise RuntimeError
self.caret = c + 1
else:
self.caret += 1
def backJump(self):
if self.memSpace.get(self.pointer, 0) != 0:
c = self.caret - 1
depth = 1
while c != 0:
cod = self.code[c]
if cod == "]":
depth += 1
elif cod == "[":
depth -= 1
if depth == 0:
break
c -= 1
self.caret = c + 1
else:
self.caret += 1
def stepCode(self):
c = self.code[self.caret]
self.command[c]()
def runCode(self):
while self.caret < len(self.code):
self.stepCode()
# util
def showMem(self):
ks = self.memSpace.keys()
ks.sort()
for k in ks:
print k, self.memSpace[k]
def simplify(self, source):
code = ""
for line in source.split("\n"):
for c in line:
if c == "#":
break
elif c in "><+-,.[]":
code += c
self.code = code
def removeOpposite(self, source):
code = ""
code = self.simplify(source)
while True:
prev = code
for p in ">< <> +- -+".split():
code = code.replace(p, "")
if prev == code:
break
self.code = code
bf = BFInterpreter()
bf.simplify("""
++++++++++
[ # The initial loop to set up useful values in the array
>+++++++>++++++++++>+++>+<<<<-
]
>++. #print 'H'
>+. #print 'e'
+++++++. # 'l'
. # 'l'
+++. # 'o'
>++. # space
<<+++++++++++++++. # 'W'
>. # 'o'
+++. # 'r'
------. # 'l'
--------. # 'd'
>+. # '!'
>. # newline
""")
bf.runCode()