ふるつき

私は素直に思ったことを書いてるけど、上から目線だって言われる

プログラミング言語を作りました

元記事

のばなしうさぎ

このように、お友達のいらいざくんが「cottonなる言語を作ったよ〜見て〜」と言って自慢してきて、「すげーーっ!!」となったので、これは負けていられないと思い、 silk というプログラミング言語を作りました。

GitHub - theoldmoon0602/silk

僕も勉強がてら Haskell + LLVM で処理系書いてみるか、と思っていたですが、 cotton のソースを見たところ、レキサもパーサもまるで読めなかったので心折られて、OCaml + LLVM で書くことにしました。 silk 自体の目標としては、 cotton の追従です。 残念ながら全く同じというわけではないのですが。

ところで silk の何よりイケイケなポイントはその小ささで、試しに cat *ml* | wc -l としたら 284 と出ました。いろんなものを省いた結果ですね。

ざっくりした処理の流れ

  • Tokenize
  • Parse
  • α変換
  • 型検査
  • K正規化
  • Closure変換
  • LLVM IR 生成

以上です、 cotton はLLVM builderを使わずに手でIRを吐いていたようですが、ちゃんと cotton のソースコードを読まなかったので、 silk では LLVMOCaml バインドを利用しています。なので多分速度には問題がないです。

データ型はInt32しかない上に関数はオブジェクトとして認めていないので型の概念が今は必要ないので型検査がありません。α変換とか Closure変換とかは必要になったら入れようと思っていたのですが気がついたら cotton と同じところまでは動いたのでまだありません。*1

LLVMは初めて触りましたが関数のインターフェースが勉強になります。どの関数がどんな役割の値を返すのか、といったことはコード生成を自分で書こうとしたらいくらでも悩めるところだったと思うので。一方で、 llbuilder 型の扱いはちょっと気に食わない感じがします。多分これ引数が変更されてますよね?*2 違いますかね。違ったらまるでわからん。

LLVMに任せるとメモリレジスタの管理が不要になるのは本当に偉大ですね。

使ったライブラリとか

いらいざが Lexer とか Parser Generatorを使っていたのでこちらも定番の ocamllex menhir 体制で望みました。レキサパーサを書かなくて良くなるだけでものすごく開発が楽になりますね。

ビルドは OMake を使っていましたが、作業環境その2でいくら menhir を入れてもないと怒られる事案が発生して、回避のために build.sh というファイルに ocamlbuild を用いたビルドスクリプトも書きました。

みていたものとか

どんな構文にするかは cotton ベースで決めていました。LLVM まわりは

https://llvm.moe/ocaml/Llvm.html

Blox/codegen.ml at master · sgtb3/Blox · GitHub

cminus/codegen.ml at master · douggard/cminus · GitHub

を引っ張ってきたりです。なんでこいつら関数の引数に func なんてものがあるんだろうと思っていたのですが、 append_block の引数に必要だったんですよね、なんでこんなことになってるんだろうというのはよくわからないまま、 silk でも eval_exp の引数には func がいます。

おわりに

cotton が更新されたら silk も更新していきたいと思っています。OCaml way も LLVM way もまるで知らないのでもう少し綺麗に書きたいとも思っています。

モチベーションを与えてくれたいらいざと cotton に感謝を込めて。

*1:このあたりってLLVMがやってくれているということなんですか、それともこの程度のプログラムならひつようないということですか

*2:OCamlってそういうことできましたっけ?