B言語といえば、C言語を知っている人なら「名前だけは知っている」言語だと思います。Cの元となった(つまりCのひとつ前の)言語です。つまりめちゃくちゃ古い言語です。1969年ごろ(?)に最初のバージョンが作られたようです。
今回私はBの処理系を作ったわけですが、「なんで今頃そんな古いものを?」と思う人が多いと思います。当たり前です。
まあプログラムを作る理由なんて「楽しいから」で十分ですし、私は今回これを作ってみて実に楽しかったのでそれでよいのですが、BはCの先祖なので、歴史を追うことで見えてくるものもあるとは思います。
たとえば、C言語で定期的に話題になるネタとして、「a[5]は5[a]と書くこともできる」というものがあります。たとえば、ちょっと前のことですが、こちらでも話題になりました。
『これを知らなければ、C++プログラマを名乗れない。ITエンジニアも驚いた「C言語」の配列の仕組み→「初めて知った」「配列へのアクセスの書き方が糖衣構文」』
https://posfie.com/@taimport/p/rwnGv98
これはもともとCで配列の要素を参照する
a[5]
のような式は、実のところ
*(a + 5)
のシンタックスシュガー(人間にとってわかりやすくするためだけに入れられた簡便記法)にすぎないからで、そして足し算の+は前後が逆でも成り立つので(交換法則が成り立つので)、
*(5 + a)
とひっくりかえして書くこともできて、よって
5[a]
と書くこともできる――という理屈です。
が、実のところ、ここまでだけでは、なぜCがこうなっているのかという説明にはなっていないと思うのです。a[5]が*(a + 5)のシンタックスシュガーであるのはまあいい、足し算には交換法則が成り立つべきだろうから*(5 + a)を許すのもわかる、でも、添字演算子[]は、ポインタと整数をオペランドにとり、かつ、それを明確に違うところに書く構文になっている(ポインタは[]の前、整数は[]の中)。そして、Cではポインタと整数は違う型なのだから、5[a]をコンパイルエラーにすることは十分可能だったはずです※1。
にも関わらずCで5[a]を許しているのは、おそらくですが、B言語との互換性を気にした、という面もいくらかあったと思うのです。なにしろBでは、ポインタと整数型という区別がなく、データ型はただ1種類の整数型しかありませんでした(ポインタも整数で表していました)。そして、Cと同様、a[5]は*(a + 5)のシンタックスシュガーだったので、a[5]を5[a]と書くこともできたわけです。いや実のところ、初期のCでも、Bのプログラムをそのまま持ってきて動く、ということはまずないので、Bとの互換性がそれほど大きな理由だったとは思えませんが。
――とかとか、そういう話をガッツリしたければ、Bを知らなければいけませんし、何かを深く知りたければ作ってみるのが一番です。というわけで、Bの処理系を作ってみることにしました。
ここで作るBの処理系は「Mae-B」と命名します(前橋版のB、です)。このWebページ内で「ここで作るBの処理系」と何度も書くのはわずらわしい、という理由の命名で、実行形式の名前はblangですし、ソースのどこを見てもMae-Bという言葉は出てきません。
ソースはGitHubに上げてあります。
https://github.com/kmaebashi/blang
愚者は経験に学び、ヒマ人は歴史に学ぶ、と言いますが(言わなかったっけ?)、Bを追っかけると歴史が知れて面白いです。いや私は決してヒマ人ではないのですが。
今回、英語のドキュメントをたくさん参照していて、本ページでも引用とその訳が登場しますが、その訳はほぼDeepLの翻訳そのままです(場合により多少はいじってますが)。便利になったものです。
上に書いた「a[5]は5[a]と書くこともできる」みたいな話も、今回作ったBVM(B Virtual Machine)のメモリ構造につながるような話も書いてある本です。宣伝しておきます。
プログラミング言語の作り方については、「プログラミング言語を作る」という本で書いたのですが、現在新品は入手不可です。
Web版がありますのでよろしければそちらをどうぞ。
公開日: 2026/01/18
間違い等ありましたら、掲示板にご連絡願います。