KDOC 27: Cコンパイラを書く
この文書のステータス
- 作成
- レビュー
CLOSE プロジェクトステータス
プロジェクトは終了である。
未完成で放置した。
導入
背景。
Tasks
TODO 8ccを読む
まず全体像を把握する。
TODO 終端のチェックをやる
セミコロンをチェックする。
TODO 変数宣言まわりで式の評価順が間違っているのを直す
なぜか違う値になる。
echo 'int a = 1;a+2' | go run ./main.go > gogo.s
.text .global mymain mymain: mov $1, %eax mov %eax, -4(%rbp) mov $2, %eax push %rax mov %eax, -4(%rbp) pop %rbx add %ebx, %eax ret
TODO identの許容文字を明示する
小文字、大文字、アンダースコアのみにする。
Archives
DONE 関数呼び出しを実装する
関数定義は後でやる。
DONE charを実装する
文字列と同じ感じでいけそう。
DONE 文字列のテスト落ちを直す
テスト用のCの関数がintを返すようになっているから、文字列は返せないんだな。8ccではASTで文字列を返すようになっているので、同じ感じにする。
DONE identを直す
envが初期状態のままになっているようだ。分岐の箇所を間違っていた。
DONE stringを直す
データラベルが必要。
DONE 文字列テストを書き直す
printf関数を使って文字列テストをやる。
DONE lexerまわりのリファクタ
細かいやつ。
CLOSE DeclStatementは中置演算子で書けないか
いや、今のコミット時点の8ccと同じように合わせておくのが安全そう。いきなり大変になるし。
宣言文は int a = 1
みたいな文。
別枠にしているが、中置演算子で共用するときれいにかけるのではないか。型名がなければ代入文で完全に中置にできる。
int a “=” 2
今はidentが特定の名前だったらトークン認識するが、これは最初の判定にイコールを使ったほうがよさそうだ。代入しなおすときに型名はないから。イコールを使えば中置演算子とできそう。
- 宣言文と代入文は使う関数を変えたほうがいいのだろうか
- 各ast構造体に型を追加する
- プリミティブ型だけで必要。それぞれintのときは…とかで分岐するから、共通でなくていい
DONE astのidentをvarにする
astの時点でidentの中の、varと確定できるので。lexerの時点ではidentのまま。
DONE ctypeを追加する
- それぞれのASTにctypeを追加する
- 不定なものと、確定しているものがある
- identをCTYPEに変換する関数を追加する
- 型演算の結果を出す関数を追加する
DONE ast読み込みの時点で変数を確定する
今は変数の確認をasmでやっていて確定するが、それをparserでやる。うーん、変数の確認をするにはobjectを持ってくる必要があるが、面倒だな。
monkeyではevaluatorでやってる。インタプリタではそうするのが自然に思える。とにかく、コンパイルするので事前にそれぞれの型を確定して、チェックする必要がある。
とりあえずparserにobjectsを保存するようにして、取り出して確定できるようにする。
- 関数呼び出しを、変数と解釈してしまっている。
f(1)
で、f
が見つからないエラー。f()
がidentになっているのが問題- token.identは共用のもので、ast.callとast.varに分岐させたい