LLVMでForthを動かしてみた - 初めての言語処理系実装

ここ最近趣味として、LLVMを使ってForth処理系を実装するというのをやっていました。ようやく一区切り(ここまではやりたい)と思っていたものができたので、コードを公開しつつブログを書いてます。

本編は英語でどうぞ

本質的に書きたい内容は英語でMediumおよびWikiに書いてしまったので、そちらをご覧下さい。

落ち穂拾い

Low-Level Programmingマジオススメ

この本がなければLLForthはできなかった。x86_64を理解したい人だけでなく、そもそもコンピュータってどうやって動いてるの?というのを理解するのに激しくオススメ(といいつつまだ読了してない) Amazon.com のリンクをどうぞ。

Forth面白い

すごくシンプルな仕組みなのに、Colon wordsのおかげでいくらでも自然に拡張できる。でも仕組みがシンプルなので実装はそこまで難しくない(もちろんどこまで本気でやるかに依存するが)。超単純なstack machineとして計算機程度を実装するだけだと、1日もかからずにできてしまって面白くないけど、辞書をやろうとするとそこそこいいボリュームになると思うのでオススメ。僕は2ヶ月くらいでここまでできました。

そんなことより、スペースシャトルでも使われてたとか、そういうのにワクワクしませんか?!

C++17いいけどC++はやっぱり辛い

今回生まれて初めてC++11を使ってみて、autolambda最高だなと感じました。ついでにC++17に途中で変えて、std::variantstd::optionalも使ってみて、他の言語で普通にやってることが自然にできるようになってきたなぁとは感じました。

とはいえ、pattern matchingが無いのはやっぱり書きづらいなと感じるし、print debugのためにoperatorめっちゃ定義するのとかだるいし、積極的に使いたいとはまだ感じられなかった。今回のようにLLVM APIがC++で提供されるみたいな理由が無い限り。(もちろん他の言語bindingはあるのは知ってるけど、一番資料が豊富なC++を使っていなかったら、そもそもAPIも知らない状態では完成できなかった。)

Rustはとても興味深い

たまたまRustにも手をだしたけど、とても良い。何がいいって、まずrustupcargoのおかげで環境構築〜プロジェクト開始に全くつまづかないし選ぶ必要もない。それから、言語的にはメモリ管理を本当に大切にしていて、僕の浅はかなCS知識ではコンパイルが全く通らない。でも、コンパイルを通すまでの過程で、なるほどここは確かにまずいな、というのを修正できるのはとても気持ちが良い。システムよりな何かを書くなら、次は間違いなくRustを選択しますね。

FFI楽しいけど辛い

FFIを通してRustで作ったライブラリをLLVMやC++から呼び出す実装もしました。確かにCのインタフェースを実装すれば自由に呼び出せるのはいいと思うけど、C的な型を取り扱うのが激しく面倒だった。

一方で、なんで今まで触ったことのあるFFIがああいう面倒なインタフェースになってるのかがよーく理解できたのはとても良かった。例えば、create/destroyがなぜ必要なのかとか。最初はRust上でlazy_static使って保持しようとしてたんだけど、どう考えてもRustと相性が悪すぎだった。以下のブログが最高でした。

まとめ

LLVMからRustまで学べて、俺得でした。みなさんもForth処理系の実装おもしろいのでぜひ。

次は、データベースの実装でもやってみようかなぁ。

riywo

Software Engineer, DevOps, DBA, Solutions Architect, NFL, working for AWS. All posts are my own, not endorsed by any org.