Open2

フルスクラッチでコンパイラを作っていく

long_long_floatlong_long_float

https://github.com/long-long-float/lisp-rs

パーサライブラリやLLVMなどのコンパイラ基盤を使用せずに、フルスクラッチでRISC-V向けのコードを生成するコンパイラを作成していく。
進捗としてはLispインタプリタはある程度形になっており、今はコンパイラ作成に着手している。
入力の言語としてLispを採用したが、いずれは自作言語に置き換えたい。

機能としては以下の通り

  • Lispとしての基本的な関数(define, if, +など)
  • マクロ
  • 静的型
  • REPL
    • ちょっとこだわって作ったが自分では使っていない 😇
  • いくつかの最適化
    • 末尾再帰最適化、定数畳み込みなど

コンパイラの実装は、パースや型検査などのフロントエンド処理をしてから、中間言語にコンパイル、最適化、レジスタ割り当てをして最後にRISC-Vのコードを生成している。
まだ簡単な演算や制御式、関数定義を含むコードしかコンパイルできない。


実行に関しては、実機とエミュレータで行っている。
実機はRISC-Vの開発ボードを使用している。

https://www.switch-science.com/products/7001

書き込みモードと実行モードの切り替えがしやすいので、普段はこっちを使っている。ただ、書き込みモードにするとブルースクリーンになってしまうことがある。

https://www.switch-science.com/products/5946

書き込みモードへの切り替えが面倒なので、開発には使っていない。IPSディスプレイが付いているので、いつかコンパイルしたプログラムで表示させてみたい。

(RISC-Vのマイコンボード、少なすぎなのでもっと増えて欲しい)

コンパイラ作成に当たっての最初の目標は、LEDを点滅させること、つまりLチカである。点滅はループないしタイマ割り込みが必要なので、まずは点灯させることを目指した。
Arduinoだと pinModedigitalWrite で済んでしまうが、そういったライブラリに頼ることはできないのでMemory-Mapped Registerでピンの設定と書き込みをする必要がある。
チップの仕様書が公開されているので、それを見ながら実装したら点灯まではできた。
点滅は今動くように修正中。

エミュレータは手元でのデバッグと自動テスト用に使っている。

https://github.com/sysprog21/rv32emu

テストをしやすくするために、レジスタの値をJSONで出力するようにしたものを使っている。
てか、みんなどうやってコンパイラのテストをしているんだろう 🤔 最適化のテストとか特に。


コンパイラとしてはまだまだなので、実装で詰まったところなどを書いていきたい。
ある程度たまってきたら本にしたいなーと少し考えている。

long_long_floatlong_long_float

メモ: WSL2 Ubuntu 20.04.6におけるコアダンプの出力先

$ sysctl kernel.core_pattern
kernel.core_pattern = /mnt/wslg/dumps/core.%e