rui312/9ccを写経する-その5

https://github.com/rui314/9cc/commit/e89595ac2097981b55e4e287d07f8a3e62a6b02c

map_existsの実装。次への布石か。

https://github.com/rui314/9cc/commit/42e403e3de0c6457bc11ab14c55a9dad27ed82be

変数の追加。よし、これも自分でやってみよう。

...(1ヶ月後)

うん、完全に詰んだ。tokenやparseまでは=+-みたいに扱えばいけそうな気がしたけど、 register周りの理解が甘くて変数をregisterに入れたらいいのかmapに入れたらいいのか、入れるとしてどうやって取り出すのか、わからなくなってしまった。

ここから進まなくなってだいぶ間が空いたのでギブアップ。答えを見てみよう。

token.c

struct Tokenにnameを追加している。そうそう、変数名で参照するから、どうしても文字列を保持しておかないといけなかった。 だいたい想像通り。

parse.c

変数割当になる=を処理する段階の追加と、これまで数字リテラルだけをnode化していた部分を変数も対応するようにしている。 Nodeにnameメンバーを追加して、変数の場合は変数名をnode->nameに渡している。 これもまあ想像通り。さあここから。

ir.c

処理順に下から見る

gen_ir

regnoはグローバルにするのは他の関数でも使いたくなったんだろう。 baseregとは? varsはmapになっている。このレベルでmapを使って変数を解決するのか。どうやるんだろ。 bpoffとは? IR_ALLOCAとは?わからん。

gen_stmt

使わない値を-1にしているだけっぽい。

gen_expr

タイプが変数だったらgen_lvalを読んでいる。変数としての処理なんだろうか?そしてIR_LOAD命令を追加している。変数だったらとりあえず中身を見るようにしている? タイプが=だったら右辺を処理して命令を生成しておく。それから左辺を変数として処理する。IR_STOREはおそらく変数の代入に相当する命令だろう。gen_lvalが気になるところ。

gen_lval

(...さらに1ヶ月後)

うーんこのへんで挫折。続かなかった。変数処理を理解するまでには至らず。 いずれは理解したいけどこのままだといつまでたっても新しいエントリーが書けないので一旦ここで閉める。。。