コンパイラ作成(104) ポインタを配列として扱う
今回の目標
ポインタに[]演算子を適用できるようにするよ。
// ポインタと配列演算子 int main() { char *p = "myc"; for(int i = 0; i < 3; i = i + 1) putchar(p[i]); putchar('\n'); }
配列演算子っていう呼び方で合ってるんだろうか。
codegen_els
型チェックの処理を修正。
# 型チェック if type_l == "double" && type_r == "int" then if str != "r10d" then codegen " mov r10d, #{str}" end codegen " cvtsi2sd xmm9, r10d" str = "xmm9" type_r = type_l elsif type_l == "int" && type_r == "double" then codegen " cvtsi2sd xmm8, eax" type_l = type_r end if type_l != type_r then if is_pointer_type?(type_l) && type_r == "int" then if op.str != "+" && op.str != "-" && op.str != "[]" then perror "mismatched types to binary operation" end elsif type_l == "int" && is_pointer_type?(type_r) then if op.str != "+" && op.str != "-" && op.str != "[]" then perror "mismatched types to binary operation" end elsif is_array_type?(type_l) && type_r == "int" then if op.str != "[]" then perror "mismatched types to binary operation" end elsif type_l == "int" && is_array_type?(type_r) then if op.str != "[]" then perror "mismatched types to binary operation" end else perror "mismatched types to binary operation" end elsif is_pointer_type? type_l then perror "mismatched types to binary operation" elsif type_l == "double" && op.str == "%" then perror "mismatched types to binary operation" end
ポインタ型のときも[]演算子を弾かないように修正。
if is_pointer_type?(type_l) && type_r == "int" then # ポインタ型+int型の処理 codegen_pointer_int type_l, op, ostr, str if op.str == "[]" then codegen_lval_to_rval type_l end elsif type_l == "int" && is_pointer_type?(type_r) then # int型+ポインタ型の処理 codegen_int_pointer type_r, op, ostr, str type_l = type_r if op.str == "[]" then codegen_lval_to_rval type_l end elsif is_array_type?(type_l) && type_r == "int" then # 配列+int型の処理 type_l = array_to_pointer type_l codegen_pointer_int type_l, op, ostr, str type_l = type_l[0,type_l.length-1] codegen_lval_to_rval type_l elsif type_l == "int" && is_array_type?(type_r) then # int型+配列の処理 type_r = array_to_pointer type_r codegen_int_pointer type_r, op, ostr, str type_l = type_r[0,type_r.length-1] codegen_lval_to_rval type_l else codegen " " + ostr + " #{reg}, " + str end
codegen_lval_to_rvalをコールするよう修正。