
米国版メルカリの開発をしています。趣味でGoコンパイラを2つ自作して、アメリカGoherConで発表しました。いまはアセンブラ自作中 / Software engineer working for @mercari_app. I made Go compilers from scratch twice.

GolanによるGo Compiler 作り始めてみました。150行くらい書いたら足し算が動くようになった。github.com/DQNEO/mgc/blob… 設計は8ccをほぼ踏襲しつつ、9ccの知見を一部取り込んでいます。
2018-10-07 12:19:33
GolangはCと比べて言語仕様にまつわる歴史的紆余曲折が圧倒的に少ない分、その分パーサー実装は楽な気がする。メモリのアロケーション(stack/heapをコンパイラが判定)とかGCは難易度高そうだけど。あと型推論、interfaceあたりもむずそう。
2018-10-07 12:35:04
* 簡易tokenizerが完成 * 足し算と引き算と掛け算が動いた 自分でもびっくりするくらい進捗したw github.com/DQNEO/mgc/comm…
2018-10-07 16:10:25
早くも関数呼び出しができるようになった! そして hello worldが動いた!! たった1日でここまでいけるとは、自分でもびっくりw pic.twitter.com/o45cBydtHn
2018-10-08 01:10:58

hello worldがファイルまるごとコンパイルできるようになったー Tour of Goに2回挫折した私ですが、Goコンパイラの開発はできているという不思議。 pic.twitter.com/whWcFVPLYO
2018-10-08 23:03:25

設計の参考にするためにGo本家のコンパイラのソースを読んでみたんだけど、意外と読めた。特に ASTの構造体の設計がめちゃきれいだった。 github.com/golang/go/blob…
2018-10-13 22:11:01
Go本体を読んでて気づいたんだけど、Goって代入文は式じゃないのね。 a = b = 3 はコンパイルエラーになった。 そして、宣言文( var i =1 ) も式じゃないっぽい。 処理系本体を読んで言語仕様を知るの、普通の学び方とは逆な気がするけど、こういう学び方もアリだな。
2018-10-13 22:19:52
ローカル変数とグローバル変数の宣言、代入、参照を実装した。(型はintのみ) あと大胆に内部設計をリファクタリングして、8cc/9cc風の巨大構造体を使うのをやめて、小さい構造体をたくさん定義してみた。この方がIDE補完効くのと、Go本家の設計に寄せたかったという理由。 github.com/DQNEO/minigo/c…
2018-10-14 22:38:52
* インラインコメント、ブロックコメント機能を実装した。 * 変数スコープを多段入れ子になるようにちゃんと実装した。 * 内部的に使ってたスペーストークンを廃止。Goの文法はセミコロンと改行、コメントとスペースの関係が少しややこしいので、いったんシンプルにした github.com/DQNEO/minigo/c…
2018-10-15 20:42:38
コンパイラ作り始めて1週間で、こんなコードがコンパイルできるようになった。それなりにプログラミング言語っぽく見えるw github.com/DQNEO/minigo/b…
2018-10-15 20:52:06
自作コンパイラ開発は、初期段階はイテレーティブ(字句解析・構文解析・コード生成をそれぞれ少しずついじって育てていくアプローチ)にやる方がいいのは間違いないけど、ある段階まできたらウォーターフォルに切り替えた方が効率がいいと思う。字句解析器だけ先に完成させてしまうみたいな。
2018-10-18 20:38:18
あと、似た機能は同時にまとめて開発した方がよい。比較演算==を実装するなら!=も一緒にやる。大小比較(<=, <)も一緒にやる。フロー制御をやるならfor,while,if,elseは一緒にやる。
2018-10-18 20:45:18
構文解析で宣言のパーズをやるときは、変数・定数・型のパーズを一気にやる。そのときはパーズだけ書いてemitterはやらない、みたいな。 そうすれば脳のモード切替をしなくてすむので圧倒的にスピードが速い。
2018-10-18 20:46:58
とにかくコンパイラというのは複雑なソフトウェアなので、いかに脳みその負担を減らすかが重要。コンパイラ内部の動きを可視化するのも重要。 ロガーを仕込むとかエラーメッセージをわかりやすくするとか、パーサの入れ子になったスタックトレースをログ表示のインデントで可視化するとか。
2018-10-18 20:52:16
そう考えて可視化をやってみたら、めちゃくちゃ生産性があがった。ログ出力のために多少コードのきれいさを犠牲にしてもよいことにした。可視化の方が圧倒的に重要。 pic.twitter.com/jLxo2EL8nP
2018-10-18 20:57:57

上の画像のfor文のパースに失敗してエラーになった例。for文を式(Expr)として解析しようとしているが、for文は文(Statement)なので、for文のパースを開始する際の前提が間違っていることがわかる。
2018-10-18 21:04:02