hccの変数実装周辺のメモ
以下を実装する
ローカル変数の宣言
ローカル変数のassign
ローカル変数の呼び出し
LVarが来たらとりあえず「左辺値」だとみなす
その変数のアドレスを計算して、それをスタックにpushする
つまり、その変数の値が何なのか、は気にしなくていいのか
右辺値だった場合どうするか
まず左辺値として評価する
その後、スタックのてっぺんにはアドレスを表す値が乗っている
ので、そのアドレスが指す値をロードする
ちょっとややこしいな?mrsekut.icon
ちゃんと理解しよう
一文字のローカル変数の実装のときに何をやってたか ref 26文字のアルファベットの変数が全て存在するものとしてアセンブリを吐いていた
つまり、x=3; a;みたいに、自分では定義していない変数aを呼び出すCコードをアセンブリに変換して実行しても、ちゃんと実行できていた。
結果は「1776768808」とかになるが
Assignするとき
これを実現するために、関数呼び出しのプロローグのタイミングで26*8byte分、スタックポインタを押し下げていた
code:memory
// スタックには上から下向きに積んでいっている
| .... |
|-------------------|
| 関数fのリターンアドレス |
|-------------------|
| f呼び出し時点でのRBP | <- RBP(ベースポインタ)
|-------------------|
| fのローカル変数a | ┐
|-------------------| |
| fのローカル変数b | |
|-------------------| | ← 26個分のローカル変数の領域を自動で確保
.... |
|-------------------| |
| fのローカル変数z | ┘
|-------------------|
なのでAssignするときは普通にAssign "x" (Nat 3)のようなASTを作るだけでいい
呼び出す時
今回は一文字の変数名に絞っているのと、すでに全部宣言されているのが前提なので、その変数が使われるより前にちゃんと宣言されているかどうかを調べなくていい
LVar "x"のようなASTを生成した
コード生成する時
Assign
LVar
ローカル変数を扱う
まず複数文字の変数をパースできるようにするのか
codeGenはなしで
monkey-nimでは、変数が既出かどうかなどはevalの方でやっていた気がするが、今回はparserがそれをするのか(?) LVar構造体がEnvみたいな役割を持っている
LVarの中にLVarがいる感じ
Assignするとき
呼び出す時
そもそもなんでOffsetが知りたいのか
offsetがわかったら何がわかるのか
valueは知りたいのか
本の方では入れ子のLVarを作ってそれをたどっていくが、これMapでも良いんじゃないか
変数の名前だけで判断する
てか、この仕事ってparserがするのか?
この仕事というのは、それが既存の変数なのか、新出の変数なのかや、
offsetの計算をすることが
一旦、parserには手を加えずにcodeGen側に頑張ってもらうことにしよう