1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonAdvent Calendar 2024

Day 16

brainf*ck を python にトランスパイル、そして実行も

Last updated at Posted at 2024-12-15

@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!
1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?