Skip to content

初期化子メモ

tyfkda edited this page Jul 5, 2024 · 1 revision
  expect2("\"array\"", "{\"array\"}", arrayof(&tyChar, 4));

fprintf(stderr, "  ARRAY\n");
      if (*pindex < init->multi->len) {
        Initializer *elem_init = init->multi->data[*pindex];
        if (elem_init->kind == IK_SINGLE && elem_init->single->kind == EX_STR &&
            is_char_type(type->pa.ptrof, elem_init->single->str.kind)) {
fprintf(stderr, "    CharType\n");
          *pindex += 1;
          return elem_init;
        }
      }

fprintf(stderr, "expected=");
dump_init(stderr, expected);
fprintf(stderr, "actual=");
dump_init(stderr, actual);
fprintf(stderr, "\n");



find_desig_indices


旧flatten_initializer_multi内ARRAYあたり

      Type *elem_type = type->pa.ptrof;
      Vector *elems = new_vector();
      ssize_t eidx = 0;
      while (*pindex < init->multi->len) {
        Initializer *elem_init = init->multi->data[*pindex];
fprintf(stderr, "  ARRAY: %d/%d: elem-init=%d\n", *pindex, init->multi->len, elem_init->kind);
        if (elem_init->kind == IK_ARR) {
          elem_init->arr.value = flatten_initializer(elem_type, elem_init->arr.value);
          eidx = elem_init->arr.index;
          assert(type->pa.length < 0 || eidx < type->pa.length);
          *pindex += 1;
        } else {
          if (type->pa.length >= 0 && eidx >= type->pa.length)
            break;
          elem_init = flatten_initializer_multi(flattener, elem_type, init);
        }
        vec_push(elems, elem_init);
        ++eidx;
      }

まず型には複数の要素(multi)を含むものと、そうでないものの2種類がある。 multiは配列型と構造体型だけである。

flatten_initializer: 初期化子をflattenする関数

  • 対象の型がmultiの場合:
    • 初期化子InitializerのkindがIK_MULTIだったら、flatten_initializer_multi0を呼び出す
    • kindがIK_SINGLEだったら、複合リテラル(EX_COMPLIT)や文字列(EX_STRING)に対応する
    • それ以外はエラー
  • 対象の型がmultiじゃない場合:
    • 初期化子がIK_MULTIで、中身が1個の要素だったら、その要素を返す
    • kindがIK_SINGLEだったら、その要素を返す
    • それ以外はエラー

flatten_initializer_multi0: multiな型に対して、IK_MULTIの初期化子全体をマッチさせる関数

  • 対象の型の要素の数に合わせて、展開した初期化子を格納するバッファを確保しておく(各要素はNULLの状態で)
  • 対象の型のどの要素を指すかを示すインデックスを用意する(インデックスはネストするため複数必要になる)
  • flatten_initializer_multi関数を呼び出して、展開した初期化子を得る

flatten_initializer_multi: multiな型に対して、IK_MULTIの初期化子全体をマッチさせる関数

  • 初期化子がIK_MULTIなので、共用体multiの各要素を順番に見ていく:
    • 初期化子の要素のkindがIK_ARRやIK_DOTの場合:
      • 対象の型の中でマッチする要素を探し、その要素を現在のインデックスにする
    • それ以外の場合には、インデックスを一つ進める
    • 初期化子を現在のインデックスの要素に格納する:
      • マッチしない場合にはエラーを出す
  • 初期化子に残りがあったらエラーを出す

インデックスを進める処理:

  • 最初の要素だったら、[0]に初期化する
  • 対応する要素がmultiだったら子要素を見ていき、最初のsingle要素が見つかるまで掘っていく

考慮すべきこと:

  • 構造体・共用体の場合わけ
  • 構造体の最後が可変長配列の場合
  • 配列の長さが指定されてない場合(初期化子の要素数によって決まる)
  • 初期化子が文字列の場合
  • 初期化子が複合リテラルの場合