コンパイラ作成(32) ローカル変数の初期化

今回の目標

前回積み残したのをちょっとずつやってくよ。

// 変数
int main()
{
    int a = 6, b = 7;
    int answer = a * b;
    printf("Answer is %d\n",answer);
}

今回は変数の初期化処理に対応するよ。

statement

ここを修正。

    elsif kind == TK::RESERVE && str == "int" then
      # 変数宣言の処理
      loop do
        kind, str = @lex.gettoken
        if kind != TK::ID then perror end
        print "var "+str+"\n" if $opt_d
        @lvarsize += 4
        if @lvars[str] then perror "redefinition variable \"" + str +"\"" end
        @lvars[str] = ["int",@lvarsize]
        skind, sstr = @lex.gettoken
        if skind == TK::SYMBOL && sstr == "=" then
          kind, str = expr2 kind, str, skind, sstr;
        else
          kind, str = skind, sstr;
        end
        if kind != TK::SYMBOL || str != "," then break end
      end
      if kind == TK::SYMBOL && str == ";" then return true end
      perror "expected ';' after variables"
      return true;

前回作った変数宣言の処理をちょっと修正してexpr2をかませるようにしただけ。修正量は僅かだよ。これでできるなら前回ここまでやればよかった。

動作テスト

どうかな。

:~/myc$ myc -d m14.myc
var a
[a, =, 6]
[a, =, 6]
var b
[b, =, 7]
[b, =, 7]
var answer
[answer, =, a, *, b]
[answer, =, [a, *, b]]
[answer]
[answer]
{"a"=>["int", 4], "b"=>["int", 8], "answer"=>["int", 12]}
{"main"=>["int", []]}
~/myc$ ./m14
Answer is 42
~/myc$

上手くいった。今回は-dでデバッグ出力をonしてみたよ。作った俺には有用な情報なんだけど、他人が見ても良く分からないかなあ。もうちょっと分かり易くする必要があるのかな。
次回は多重代入の対応かな。右結合への対応を組み込むよ。