忙しい人のためのざっくり概要
- 難解プログラミング言語「Brainfuck」をベースに言語仕様作れば、自作言語作るのは意外と簡単
- インタプリタは作っといたから、これ使うと簡単に実行環境を準備出来るよ(Brainfuck派生言語 お手軽インタプリタ)
まえがき
自作プログラミング言語……それは甘美なる響き……
存在するだけでQoLが上がる1、妖艶な輝きを放つ……
…といいつつ、実際に作ろうとすると幾つかの壁を感じるはずです。
「チューリング完全ってどう満たすといいの?」
「字句解析?構文解析?」
「ぜんぜんわからん……」
1から腰を据えてゴリゴリ作ろうと思ったら当然大変な作業ですが、幸いなことに単純に言語を作るだけであればうってつけの方法があります。
既存の言語の命令文字をオリジナルの命令文字に置換してしまえばよいのです!
……そんなのあり?と思われるかもしれませんが、この方式で作られている言語って実は多かったりします。
例えば、今回ベースにしようとしている言語「Brainfuck」はその簡素な言語仕様故に多くの派生言語が存在します。
esolangs.orgのBrainfuck派生タグを確認すると記事作成時点2では706言語ほどあるようです。
また、数年前アニメ「けものフレンズ」が流行っていた際にプログラミング言語「Kemono」が話題になってましたが、あの言語も同じ様にBrainfuck派生で作られていたりします。
1. 言語仕様を作ろう
まえがきにて記載した通り、今回は既存の言語をベースに作成します。
今回は、難解プログラミング言語「Brainfuck」と呼ばれる、実用性ほぼ皆無の言語を使用しようかと思います。
前述の通り実用性はほぼありませんが、命令文が8つしか無いため自作言語のベースにかなり向いています。
なおかつチューリング完全3なので、まさしく「プログラミング言語作った!」と言いやすい!
さて、まずは元の言語仕様を確認してみましょう。
命令文 | 動作 |
---|---|
> | ポインタを右に動かす |
< | ポインタを左に動かす |
+ | ポインタで示す値をインクリメントする |
- | ポインタで示す値をデクリメントする |
. | ポインタで示す値の文字を出力する |
, | 文字を入力し、ポインタに格納する |
[ | ポインタのセルが0の場合、 ] まで飛ばす |
] | ポインタのセルがゼロでない場合は、 [ に戻る |
よく、プログラミングの基本要素として「順次・分岐・反復」みたいに挙げられますが、「順次」はそのままコードの流れで、「分岐・反復」は[
、]
でうまいこと実装できるのです。
つまり、この各命令文を各々で自由に変えてしまえばよいということですね。
ちなみに、この形式で作られた言語を「Brainfuck派生言語」と呼んだりします。
すべてをひっくるめると今回は「Brainfuck派生言語を作ろう!」と言い換えることができます。
例えば、我が地元山形県っぽいプログラミング言語「yamagata」を作ろうとしたとします。4
その場合は以下のようにいい感じに命令文を好きなように変えれば、はい簡単!
わーい!オリジナルの言語(の仕様)完成です!
命令文 | 動作 |
---|---|
さくらんぼ | ポインタを右に動かす |
ラ・フランス | ポインタを左に動かす |
芋煮 | ポインタで示す値をインクリメントする |
いなごの佃煮 | ポインタで示す値をデクリメントする |
米沢牛 | ポインタで示す値の文字を出力する |
雪若丸 | 文字を入力し、ポインタに格納する |
ラーメン | ポインタのセルが0の場合、 ] まで飛ばす |
温泉 | ポインタのセルがゼロでない場合は、 [ に戻る |
2. 実行環境を作ろう
さて、仕様が完成したので一旦プログラミング言語として、必要最低限は完成したと言っていいかもしれません。
が、実行環境がない状態で「俺、自作のプログラミング言語持ってるぜ!」とは言いづらいですよね。
そこで、今回「Brainfuck派生言語」の実行環境を簡単に共有出来るツールを作っておきました。
ということでこちら(Brainfuck派生言語 お手軽インタプリタ)になります。
リンク先の命令文のフォームを書き換えればそれで実行環境完成です。
「共有用URL」で実行環境を展開することも可能です。
例えば、さっき書いたプログラミング言語「yamagata」の実行環境はこんな感じになります。
ここまでくれば、胸を張って「自作プログラミング言語持ってるぜ!」と言えそうですね。
やったー!!
3. (おまけ)難解プログラミング言語のwikiに載せよう
ここはやりたい人だけでいいですが、esolangs.orgに作った言語を掲載することが出来ます。
基本的に「Brainfuck派生言語」はベースの言語(Brainfuck)と同様に難解プログラミング言語5に分類されるため、今回の手順に従った場合はこちらのサイトに追加が可能です。
具体的な手順は過去記事を参考にしてください。
数年前の記事ですが、おそらく当時から大きくは変わっていないはずです。
インタプリタの実装について
ここから先は(Brainfuck派生言語 お手軽インタプリタ)の実装について気になる人向けです。
まず前提として、本アプリはRuby on Railsにて実装しています。
内部的には、2つの機能をガリガリ実装した感じです。
- Brainfuck派生言語→Brainfuck のトランスパイラ
- Brainfuckのインタプリタ
「Brainfuck派生言語→Brainfuck のトランスパイラ」は文字列検索を使って割と簡単に実装できますが、問題は「Brainfuckのインタプリタ」です。
[
、]
の処理はネストする可能性があるため、ちゃんとスタックで管理する必要があります。
ここは気合で実装しました……
(数年前に独自言語でBrainfuckのインタプリタを実装した経験のお陰で、だいぶ助かりました……いやまじで……6)
最後に
ここまで色々書きましたが、この分野に関して詳しい方はかなりの人数いるはずです。
ぜひ、優しくまさかり投げていただければ幸いです。
-
自作プログラミング言語があると、ちょっと嫌なことがあっても「まあ家に帰れば自作プログラミング言語あるしな」ってなるし仕事でむかつく人に会っても「そんな口きいていいのか?私は自宅で自作プログラミング言語とよろしくやってる身だぞ」ってなれる。戦闘力を求められる現代社会においてプログラミング言語を自作することは有効 ↩
-
2024/11/27確認 ↩
-
ざっくり説明すると、基本的に大体のアルゴリズムを実装する事ができる能力を持つよね、みたいな感じ。もっと細かく書くと、アラン・チューリング氏が提唱した「万能チューリングマシン」と同じ計算能力を原理的に持ってるよね、みたいな感じ。ここでは省略、自分で調べて…… ↩
-
本当は他にも有名なものいっぱいあるので、私としては忸怩たる思いなのですが、8つしか命令文がないので仕方ないです…… どんどん焼きやら玉こんやらけん玉やら将棋の駒にだだちゃ、変わり種に即身仏とか、他にも色々…… ↩
-
ちなみにもっと言うと「チューリング完全」かつ「難解な言語仕様」となっているため、「チューリング陥穽」と呼ぶことも出来ます。まぁあまり一般的な語彙では無いですが…… ↩
-
https://github.com/yamaserif/DigFiles/tree/main/example/Brainfuck_interpreter ↩