コンパイラ作成(75) char型の比較演算、単項マイナス演算

今回の目標

今回もchar型のサポートだよ。

// char型

int main()
{
    char a = 11, b = 4;
    if( a == b )
        printf("%hhu == %hhu\n", a, b);
    else
        printf("%hhu != %hhu\n", a, b);
}
// char型

int main()
{
    char a = 11, b = -a;
    printf("a = %hhu b = %hhu\n", a, b);
}

これで演算子全部かなあ。

codegen_els

比較演算子のところを修正。

    # 左被演算子と右被演算子とで計算
    if op.str == "==" then
      codegen "  " + ostr + " #{reg}, " + str
      codegen "  sete al"
      codegen "  and  eax, 1"
    elsif op.str == "!=" then
      codegen "  " + ostr + " #{reg}, " + str
      codegen "  setne al"
      codegen "  and  eax, 1"
    elsif op.str == "<" then
      codegen "  " + ostr + " #{reg}, " + str
      codegen "  setl al"
      codegen "  and  eax, 1"
    elsif op.str == ">" then
      codegen "  " + ostr + " #{reg}, " + str
      codegen "  setg al"
      codegen "  and  eax, 1"
    elsif op.str == "<=" then
      codegen "  " + ostr + " #{reg}, " + str
      codegen "  setle al"
      codegen "  and  eax, 1"
    elsif op.str == ">=" then
      codegen "  " + ostr + " #{reg}, " + str
      codegen "  setge al"
      codegen "  and  eax, 1"

eax固定だったのを#{reg}に置き換えたよ。これでchar型の時は8bitのalになるよ。

codegen_unaryop

単項マイナス演算子のところを修正。

    if op.str == "-" then
      # 単行マイナス演算子
      type = codegen_el operand
      if type == "char" then
        codegen "  neg  al"
      elsif type == "int" then
        codegen "  neg  eax"
      else
        perror "unsupported type with unary '-'"
      end

単項プラスのところは修正の必要が無かったよ。

動作テスト

二つ続けてテスト。

~/myc$ myc p5.myc
~/myc$ ./p5
11 != 4
~/myc$ myc p6.myc
~/myc$ ./p6
a = 11 b = 245
~/myc$ 

あれマイナスになってないじゃん。あ、そうだchar型をunsignedにしたんだった。そっかそっか。これで合ってるのか。試しにclang先輩でもコンパイルしてみたけど同じ結果になったよ。これでchar型のサポートは終わったかな。ああ、そうだ。型をミックスしたときの処理が入ってないよ。うーん、でももうchar型は飽きたなあ。次回は何か別の事したいなあ。うーん。
そういや比較演算子のテスト一個しかやってないな。他の演算子も大丈夫だとは思うけどちゃんとテストしないと拙いな。このところ全体的にテストが足りてないし。うーん、うーん。