コンパイラ作成(57) char*型の変数

今回の目標

簡単にできそうなところからこつこつと。

// char*型の変数
int main()
{
    char *p = "Hello, World!";
    puts(p);
}

char*型の変数だよ。引数と大して違わないから簡単だと思う。

statement

変数の宣言部をちょこちょこっと修正。

    elsif kind == TK::TYPE then
      # 変数宣言の処理
      basetype = str
      loop do
        type = basetype
        kind, str = @lex.gettoken
        if kind == TK::SYMBOL && str == "*" then
          type += str
          kind, str = @lex.gettoken
        end
        if kind != TK::ID then perror end
        print "var "+str+"\n" if $opt_d
        @lvarsize += sizeof(type)
        if @lvars[str] then perror "redefinition variable \"" + str +"\"" end
        @lvars[str] = [type,@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
        perror "expected ';' after variables"
      end

引数の処理と同じようにsizeofを呼んでる。

動作テスト

どうかな。

~/myc$ myc -d o13.myc
var p
[p, =, Hello, World!]
[[p, =, Hello, World!]]
[[puts, (), [p]]]
[[puts, (), [p]]]
{"p"=>["char*", 8]}
{"main"=>["int", []]}
~/myc$ ./o13
Hello, World!
~/myc$

よしよし。今回はサクッとできたよ。調子に乗ってint*型の変数を宣言してみたけど、コンパイルエラーになっちゃったよ。sizeofが超適当コーディングになってて、int型とchar*型にしか対応してなかった。それにint*型の変数が宣言できたとしてもちゃんと扱えないから意味ないしね。とりあえずここまえだけど、今日はもう少し頑張るよ。