『低レイヤを知りたい人のための Cコンパイラ作成入門』感想
インターネット上で公開されている範囲については実装が終わりました。
内容について
非常によかったです。わかりやすかったです。僕は技術書の場合、だいたい冒頭だけ読んで、実装してみて、本の内容と比較するという読み方をしています。この本については、ある機能を実装するにあたって、「このへんは今はやらなくていいや」と割り切るのが上手いと感じました。実装していると「これもやらなきゃじゃん」「こうなってるほうがいいよなー」みたいな気持ちがどんどん生まれますが、実際にを読んでみると「これは後ででいいです」とバッサリ。これはCコンパイラを複数回作った経験とコンピューターサイエンスに関する体系的な知識があるがゆえにできているのかなーと思っています。
このコンテンツを読む前に期待している点としては、「言語実装に関する理解が深まること」と「アセンブリ、機械語を生成するフェイズの知識が得られること」の2点でした。やってみた感じとしては、前者は特に深まったなーと思っています。tokenize, parse というフェイズごとに何をしているのかという点や実際のバイナリをつくるまでの過程というのが理解できました。
一方で後者は、いまだによくわかりません。吐くアセンブリの意味を正しく理解できているかというとあやしいし……。これはどちらかというと文章としての問題ではなく、読み手としてアセンブリと仲良くなる努力がまだ足りてないのかなーと思っています。どうにかしないとなー。いい教材みたいなのがあると助かります。fizzbuzzみたいなのを自分で書いてみるか。
これから
上記のアセンブリと仲良くなるっていうのと、あとはCで書くのがダルいので他言語で実装しなおすかもしれません。あるいはもうちょい自力ですすめるか。あと解析フェイズの理解が進んだせいで TaPL の言語実装が適当すぎることに気づいたのでそっちを直したくもなっています。どうしよう。
動いているようす
こんな感じになります。ちゃんと動いてますね。中間生成物のアセンブリもチラ見せ。
$ make test bin/hkdcc -test OK ./test.sh 0; => 0 42; => 42 1+2; => 3 1+10+2; => 13 3-1; => 2 23-12; => 11 3 - 1; => 2 70+2*5*5; => 120 4/2; => 2 5+6*7; => 47 5*(9-6); => 15 (3+5)/2; => 4 1; 2; => 2 a = 1; => 1 a = 1; a; => 1 a = 1; a + 1; => 2 a = b = 1; a + b; => 2 1 == 1; => 1 a = 1; 1 == a; => 1 a = 2; 1 == a; => 0 a = 2; a == 1; => 0 a = 2; a == a; => 1 a = 1 == 1; a; => 1 a = 0 == 1; a; => 0 1 != 1; => 0 2 != 1; => 1 OK $ cat tmp.s .intel_syntax noprefix .global _main _main: push rbp mov rbp, rsp sub rsp, 208 push 2 push 1 pop rax pop rdi cmp rdi, rax setne al movzx rax, al push rax pop rax mov rsp, rbp pop rbp ret