低レイヤを知りたい人のための Cコンパイラ作成入門、こちら、日々更新されている書籍(?)なのですが、現在書かれている部分まで完了した。
コードは以下。Docker上で開発していて、Travis CIでのテストもしている。 github.com
よくわからなかったところ
全部のコードが載っているわけではないので、 "動くには動いているが本当にこれでいいんだろうか?" という部分がいくつかあった。
mulやexpr内で自分の読めない文字の判定
以下のように、mulの最初でひたすらmulの扱わない文字を弾いていっているのだけど、(更に言うとexprの最初でも同様のことをやっているんだけど)、もっとエレガントな方法はないのだろうか、このままでは記号は増えるごとにこの条件が増えていくぞ…?と考えている。 https://github.com/dekokun/9cc/blob/955ec5aa6c44e1c9cd1721ace7e8140cd357419a/parse.c#L79
しかし、mulが呼び出されたらmulは自分の読める範囲内で最大のところまで読まないといけないし、そうすると自分の読めない文字も知っていないといけないよなぁ、だからこれでいいんだろうなぁ、と思ったりもしている。
(追記) と、このエントリを書いてちょっと考えていたら以下のように修正すればいいんじゃね?と思って修正した。パッと考えて実装してテストも通ったからコミットしたけどエラーに弱くなったりするのかな。ちょっと考えないとわからないし今日はもう寝る。
読めるところまで読んで読めなかったら返す · dekokun/9cc@ec14865 · GitHub
(更に追記)
布団の中で考えていたが、やっぱ例えば 1 1
みたいな入力を与えられた時に、これまではmulで止められていたのがassignまで上ってきてエラーの分類能力が弱くなっているな…ダメか〜。まぁ寝る。
util_testでのgccからの警告
コンパイル時にhttps://github.com/dekokun/9cc/blob/40fe86304cf08139611615971303fb57284e01f1/util_test.c#L28 のあたりで util_test.c:28:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
という感じで、integerと void *
のサイズが違うよって言われていて、64bit環境だと違うよね、とは思うんですがこのエラーを解消させるうまい方法はあるのだろうか… void *
をやめるとかしかない…??
と思った。
感想
以下でもruiさんを参考にプログラミング言語を作って楽しかったので今回も楽しいだろうなと思いつつ始めたらめちゃくちゃ楽しくてドハマリしている。
再帰は難しいなと改めて思うし、再帰から再帰を繰り返して魔法のようにプログラムが解読されていくのは本当にワケワカラン感じですごいなと思う。
とにかくturingcompletefmを聞きつつこれをやりつつ、ruiさんみたいな感じになりたいな("みたいに" とは何か)と最近思う日々なのであった。