Rokiのチラ裏

学生による学習のログ

brainf**k LLVM IR トランスパイラ(コンパイラ)ジェネレータ

以前 brainf**k インタプリタジェネレータのようなものを書いたが、LLVM IR を使ってオブジェクトファイル吐けたら良いかなと思ったので、取り敢えず作った。レキシカルアナライザ*1は、インタプリタで書いたものを呼び出して再利用している。

github.com

こんな感じに使う。

以下のようにビルドする(Makefile が雑なのは悪しからず)。

実行すると、IR コードがダンプされると同時にオブジェクトファイルが生成される。 尚、キーワードはbrainf**k インタプリタジェネレータと同じく好き勝手に設定できるので、brainf**k の亜種であるインタプリタ/コンパイラは、これらを用いてキーワードをただ単に変えるだけで完結する*2

#include <srook/brainfk/llvm/brainfk_compiler.hpp>

int main()
{
    using namespace std::string_literals;
    namespace br_keywords = srook::brainfk::label;

    const auto ponkotsu_keywords = srook::brainfk::make_keywords((
        br_keywords::_INCREMENT_THE_POINTER = L"ブラック企業かよ"s,
        br_keywords::_DECREMENT_THE_POINTER = L"アイスうめー"s,
        br_keywords::_INCREMENT_THE_BYTE_AT_THE_POINTER = L"ヒョウド! "s,
        br_keywords::_DECREMENT_THE_BYTE_AT_THE_POINTER = L"ドルファヘキセンダー  "s,
        br_keywords::_OUTPUT = L"おもらひ"s,
        br_keywords::_INPUT = L"おねひ"s,
        br_keywords::_JUMP_FORWARD = L"労災はおりない"s,
        br_keywords::_JUMP_BACKWARD = L"ハンマー"s));

    srook::brainfk::brainfk_syntax_llvm_compiler<std::wstring> bk_syn(ponkotsu_keywords);
    if(!bk_syn.file_open("../sample_bf/fizzbuzz.ponque")){
        return EXIT_FAILURE;
    }
    if(!bk_syn.analyze()){
        return EXIT_FAILURE;
    }
    bk_syn.exec();
    bk_syn.output_object("output.o");
}

上記のように設定した fizzbuzz のコードは以下のようになる。

*1:ご存知の通り brainf**k はそれほど大それた構文ではないので通常1バイトずつ進んで行けば勝手にトークンに分割されるが、今回はキーワードを任意に変更できるようにしてある分、ほんの少し面倒ではある。

*2:キーワードを変えただけで新しい言語であるとは到底思えない。