@fygar256 さんの 「Brainfuck compiler to X86_64 on linux by C and python」に触発されて、Brainf*ckからPythonへのトランスパイラを作ってみました。
命令変換は単純なので、辞書を使って変換するようにしました。
ループの戻り先はインデントで決まるので、インデントの深さを管理するだけで済みました。
トランスパイルしたコードを実行する -e
オプションも付けました。
bf2py.py
#!/usr/bin/env python3
import sys
import argparse
TRANS = {
# op: (nest, python_code)
'>': (0, 'index += 1'),
'<': (0, 'index -= 1'),
'+': (0, 'memory[index] = (memory[index] + 1) & 0xff'),
'-': (0, 'memory[index] = (memory[index] - 1) & 0xff'),
'.': (0, 'sys.stdout.write(chr(memory[index]))'),
',': (0, 'memory[index] = ord(sys.stdin.read(1))'),
'[': (1, 'while memory[index]:'),
']': (-1, ''),
}
def transpile(bf, memory_kib=8):
"""brainf*ckコードbfをpythonに変換(メモリサイズはmemory_kibキビバイト)"""
yield 'import sys'
yield f'memory = [0] * {memory_kib} * 1024'
yield 'index = 0'
indent = 0
for op in bf:
nest, py = TRANS.get(op, (0, ''))
if py:
yield ' ' * indent + py
indent += nest
def main():
parser = argparse.ArgumentParser()
parser.add_argument('filename', help='input file name of brainf*ck source code')
parser.add_argument('-e', '--execute', help='execute code', action='store_true')
parser.add_argument('-m', '--memory', type=int, default=8, help='memory size in KiB')
args = parser.parse_args()
with open(args.filename) as f:
(exec if args.execute else print)('\n'.join(transpile(f.read(), args.memory)))
if __name__ == '__main__':
main()
ヘルプ
$ python3 bf2py.py -h
usage: bf2py.py [-h] [-e] [-m MEMORY] filename
positional arguments:
filename input file name of brainf*ck source code
options:
-h, --help show this help message and exit
-e, --execute execute code
-m MEMORY, --memory MEMORY
memory size in KiB
hello.bf
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
トランスパイル
$ python3 bf2py.py hello.bf
import sys
memory = [0] * 8 * 1024
index = 0
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
while memory[index]:
index += 1
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
while memory[index]:
index += 1
memory[index] = (memory[index] + 1) & 0xff
memory[index] = (memory[index] + 1) & 0xff
(以下省略)
実行
$ python3 bf2py.py hello.bf -e
Hello World!