// 2025-2026 Богданович Давид Когут Прихожденко (кдб.дійсність.укр)

взяти визначення мавка/пристрій;

простір мавка {
  простір пристрій {
    дія надрукувати_інформацію_падіння(
      М: адреса<Машина>,
      інформація_падіння: ІнформаціяПадіння
    ) {
      пристрій_мавки_вивести_формат(ФКолірТекстуЧервоний);
      вивести_кд(М, "Помилка");
      пристрій_мавки_вивести_формат(ФОчистити);

      якщо інформація_падіння.місцезнаходження.шлях != пусто {
        вивести_кд(М, " в ");

        пристрій_мавки_вивести_шлях(інформація_падіння.місцезнаходження.шлях.розмір, інформація_падіння.місцезнаходження.шлях.дані);

        якщо інформація_падіння.місцезнаходження.рядок > 0 {
          вивести_кд(М, ":");
          вивести_п64(М, п64(інформація_падіння.місцезнаходження.рядок));
        }

        вивести_кд(М, "");
      }

      надрукувати_значення(М, інформація_падіння.значення, 2, 0);

      змінна п: природне = 0;

      якщо інформація_падіння.розмір_історії > 0 {
        надрукувати_кд(М, "Історія здійснення:");
      }

      поки п < інформація_падіння.розмір_історії {
        змінна елемент_історії = інформація_падіння.історія[п];

        якщо елемент_історії.назва != пусто {
          вивести_кд(М, "  ");
          пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
          вивести_кд(М, елемент_історії.назва.значення);
          пристрій_мавки_вивести_формат(ФОчистити);

          якщо елемент_історії.місцезнаходження.шлях == пусто {
            вивести_кд(М, "");
          } інакше {
            вивести_кд(М, " в ");
            пристрій_мавки_вивести_шлях(елемент_історії.місцезнаходження.шлях.розмір, елемент_історії.місцезнаходження.шлях.дані);

            якщо елемент_історії.місцезнаходження.рядок > 0 {
              вивести_кд(М, ":");
              вивести_п64(М, п64(елемент_історії.місцезнаходження.рядок));
            }

            вивести_кд(М, "");
          }
        }

        п += 1;
      }
    }

    внутрішня дія вивести_пропуски(М: адреса<Машина>, кількість: природне) {
      змінна п: природне = 0;

      поки п < кількість {
        вивести_кд(М, " ");

        п += 1;
      }
    }

    внутрішня дія вивести_вбудований_предмет(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      предмет: адреса<Предмет>,
      розмір_відступу: природне,
      глибина: природне
    );
    внутрішня дія вивести_предмет(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      предмет: адреса<Предмет>,
      розмір_відступу: природне,
      глибина: природне
    );
    внутрішня дія вивести_значення_1(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      значення: Значення,
      розмір_відступу: природне,
      глибина: природне
    );

    внутрішня дія зберегти_стан_виведених_предметів(
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>
    ) -> природне {
      вернути виведені_предмети.розмір;
    }

    внутрішня дія відновити_стан_виведених_предметів(
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      стан: природне
    ) {
      виведені_предмети.розмір = стан;
    }

    внутрішня дія покласти_виведений_предмет(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      предмет: адреса<Предмет>
    ) {
      покласти_в_накопичувач<адреса<Предмет>>(
        М,
        виведені_предмети,
        предмет
      );
    }

    внутрішня дія предмет_вже_виведено(
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      предмет: адреса<Предмет>
    ) -> логічне {
      змінна п: природне = 0;

      поки п < виведені_предмети.розмір {
        якщо виведені_предмети.дані[п] == предмет {
          вернути так;
        }

        п += 1;
      }

      вернути ні;
    }

    внутрішня дія вивести_вбудований_предмет(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      предмет: адреса<Предмет>,
      розмір_відступу: природне,
      глибина: природне
    ) {
      якщо предмет.клас == М.клас_Клас {
        змінна властивості = предмет як адреса<ПредметКласу>;

        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);

        якщо властивості.назва == пусто {
          вивести_кд(М, "<клас>");
        } інакше {
          вивести_кд(М, "<клас ");

          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(властивості.назва), 0, 0);

          вивести_кд(М, ">");
        }

        пристрій_мавки_вивести_формат(ФОчистити);

        вернути;
      }

      якщо предмет.клас == М.клас_Модуль {
        змінна властивості_модуля = предмет як адреса<ПредметМодуля>;

        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);

        якщо властивості_модуля.назва == пусто {
          вивести_кд(М, "<модуль");
        } інакше {
          вивести_кд(М, "<модуль ");

          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(властивості_модуля.назва), 0, 0);
        }

        якщо властивості_модуля.властивості.вмісткість > 0 {
          вивести_кд(М, "[");
          змінна п: природне = 0;
          змінна виведено_першу = ні;

          поки п < властивості_модуля.властивості.вмісткість {
            змінна призначене = властивості_модуля.властивості.дані[п];

            поки призначене != пусто {
              якщо виведено_першу {
                вивести_кд(М, ", ");
              }

              виведено_першу = так;

              вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(призначене.назва), 0, 0);

              призначене = призначене.наступний;
            }

            п += 1;
          }
          вивести_кд(М, "]");
        }

        вивести_кд(М, ">");

        пристрій_мавки_вивести_формат(ФОчистити);

        вернути;
      }

      якщо предмет.клас == М.клас_Текст {
        змінна властивості = предмет як адреса<ПредметТексту>;

        якщо глибина != 0 {
          пристрій_мавки_вивести_формат(ФКолірТекстуЗелений);
          вивести_кд(М, "\"");
        }

        якщо глибина == 0 {
          вивести_кд(М, властивості.значення);
        } інакше {
          змінна п: природне = 0;
          поки п < властивості.значення.розмір {
            змінна символ = властивості.значення.дані[п];

            якщо символ == КД::символи::Міжряд {
              вивести_кд(М, "\\р");
            } інакше якщо символ == КД::символи::Дволапка {
              вивести_кд(М, "\\\"");
            } інакше якщо символ == КД::символи::Обернена_похила {
              вивести_кд(М, "\\\\");
            } інакше якщо символ == КД::символи::Дія {
              вивести_кд(М, "\\д");
            } інакше {
              вивести_кд(М, кд { 1, символ::адреса як адреса<п8> });
            }

            п += 1;
          }
        }

        якщо глибина != 0 {
          вивести_кд(М, "\"");
          пристрій_мавки_вивести_формат(ФОчистити);
        }

        вернути;
      }

      якщо предмет.клас == М.клас_Дія {
        змінна властивості = предмет як адреса<ПредметДії>;

        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);

        якщо властивості.назва == пусто {
          вивести_кд(М, "<дія>");
        } інакше {
          вивести_кд(М, "<дія ");

          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(властивості.назва), 0, 0);

          вивести_кд(М, ">");
        }

        пристрій_мавки_вивести_формат(ФОчистити);

        вернути;
      }

      якщо предмет.клас == М.клас_Параметр {
        змінна предмет_параметра = предмет як адреса<ПредметПараметра>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "Параметр");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "назва=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_параметра.назва), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "тип=");
        якщо предмет_параметра.тип == пусто {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        } інакше {
          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_параметра.тип), розмір_відступу, глибина + 1);
        }
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "дія_значення=");
        якщо предмет_параметра.дія_значення == пусто {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        } інакше {
          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_параметра.дія_значення), розмір_відступу, глибина + 1);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_Код {
        змінна предмет_коду = предмет як адреса<ПредметКоду>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "Код");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "константи=");
        якщо предмет_коду.константи == пусто {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        } інакше {
          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_коду.константи), розмір_відступу, глибина + 1);
        }
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "вказівки=");
        якщо предмет_коду.вказівки == пусто {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        } інакше {
          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_коду.вказівки), розмір_відступу, глибина + 1);
        }
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "шлях=");
        якщо предмет_коду.шлях == пусто {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        } інакше {
          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_коду.шлях), розмір_відступу, глибина + 1);
        }
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "місцезнаходження_вказівок=");
        пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
        вивести_кд(М, "недійсне");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_Список {
        змінна властивості_списку = предмет як адреса<ПредметСписку>;

        якщо предмет_вже_виведено(виведені_предмети, предмет) {
          вивести_кд(М, "[...]");
          вернути;
        }

        змінна свп = зберегти_стан_виведених_предметів(виведені_предмети);
        покласти_виведений_предмет(М, виведені_предмети, предмет);

        вивести_кд(М, "[");

        якщо властивості_списку.розмір > 0 {
          якщо розмір_відступу > 0 {
            вивести_кд(М, "");
          }

          змінна п: природне = 0;
          поки п < властивості_списку.розмір {
            змінна елемент = властивості_списку.елементи[п];
            вивести_пропуски(М, розмір_відступу * (глибина + 1));
            вивести_значення_1(М, виведені_предмети, елемент, розмір_відступу, глибина + 1);
            вивести_кд(М, ",");
            якщо розмір_відступу > 0 {
              вивести_кд(М, "");
            } інакше {
              вивести_кд(М, " ");
            }

            п += 1;
          }

          вивести_пропуски(М, розмір_відступу * глибина);
        }

        вивести_кд(М, "]");

        відновити_стан_виведених_предметів(виведені_предмети, свп);

        вернути;
      }

      якщо предмет.клас == М.клас_Словник {
        змінна властивості_словника = предмет як адреса<ПредметСловника>;

        якщо предмет_вже_виведено(виведені_предмети, предмет) {
          вивести_кд(М, "{...}");
          вернути;
        }

        змінна свп = зберегти_стан_виведених_предметів(виведені_предмети);
        покласти_виведений_предмет(М, виведені_предмети, предмет);

        вивести_кд(М, "{");

        якщо властивості_словника.розмір > 0 {
          якщо розмір_відступу > 0 {
            вивести_кд(М, "");
          }

          змінна п: природне = 0;
          поки п < властивості_словника.розмір {
            змінна пара = властивості_словника.елементи[п];
            вивести_пропуски(М, розмір_відступу * (глибина + 1));
            вивести_значення_1(М, виведені_предмети, пара.ключ, розмір_відступу, глибина + 1);
            вивести_кд(М, " => ");
            вивести_значення_1(М, виведені_предмети, пара.значення, розмір_відступу, глибина + 1);
            вивести_кд(М, ",");
            якщо розмір_відступу > 0 {
              вивести_кд(М, "");
            } інакше {
              вивести_кд(М, " ");
            }

            п += 1;
          }

          вивести_пропуски(М, розмір_відступу * глибина);
        }

        вивести_кд(М, "}");

        відновити_стан_виведених_предметів(виведені_предмети, свп);

        вернути;
      }

      якщо предмет.клас == М.клас_Дані {
        змінна предмет_даних = предмет як адреса<ПредметДаних>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "Дані");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "розмір=");
        вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_даних.розмір)), розмір_відступу, глибина + 1);
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ДіапазонЧисел {
        змінна предмет_діапазону_чисел = предмет як адреса<ПредметДіапазонуЧисел>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ДіапазонЧисел");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "від=");
        вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_діапазону_чисел.від)), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "до=");
        вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_діапазону_чисел.до)), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "включно=");
        пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
        якщо предмет_діапазону_чисел.включно {
          вивести_кд(М, "дійсне");
        } інакше {
          вивести_кд(М, "недійсне");
        }
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ПеребірДіапазонуЧисел {
        змінна предмет_перебору_діапазону_чисел = предмет як адреса<ПредметПереборуДіапазонуЧисел>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ПеребірДіапазонуЧисел");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "діапазон=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_перебору_діапазону_чисел.предмет_діапазону), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "значення=");
        якщо предмет_перебору_діапазону_чисел.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(предмет_перебору_діапазону_чисел.поточне_значення), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ПеребірДаних {
        змінна предмет_перебору_даних = предмет як адреса<ПредметПереборуДаних>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ПеребірДаних");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "дані=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_перебору_даних.предмет_даних), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "значення=");
        якщо предмет_перебору_даних.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(предмет_перебору_даних.поточне_значення), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "позиція=");
        якщо предмет_перебору_даних.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_перебору_даних.позиція)), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ПеребірПослідовності {
        змінна предмет_перебору_послідовності = предмет як адреса<ПредметПереборуПослідовності>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ПеребірПослідовності");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "послідовність=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_перебору_послідовності.предмет_послідовності), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "значення=");
        якщо предмет_перебору_послідовності.почато {
          вивести_значення_1(М, виведені_предмети, предмет_перебору_послідовності.поточне_значення, розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "позиція=");
        якщо предмет_перебору_послідовності.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_перебору_послідовності.позиція)), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ПеребірСловника {
        змінна предмет_перебору_словника = предмет як адреса<ПредметПереборуСловника>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ПеребірСловника");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "словник=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_перебору_словника.предмет_словника), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "значення=");
        якщо предмет_перебору_словника.почато {
          вивести_значення_1(М, виведені_предмети, предмет_перебору_словника.поточне_значення, розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ПеребірСписку {
        змінна предмет_перебору_списку = предмет як адреса<ПредметПереборуСписку>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ПеребірСписку");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "список=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_перебору_списку.предмет_списку), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "значення=");
        якщо предмет_перебору_списку.почато {
          вивести_значення_1(М, виведені_предмети, предмет_перебору_списку.поточне_значення, розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "позиція=");
        якщо предмет_перебору_списку.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_перебору_списку.позиція)), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_ПеребірТексту {
        змінна предмет_перебору_тексту = предмет як адреса<ПредметПереборуТексту>;
        пристрій_мавки_вивести_формат(ФКолірТекстуСиній);
        вивести_кд(М, "ПеребірТексту");
        пристрій_мавки_вивести_формат(ФОчистити);
        вивести_кд(М, "(");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "текст=");
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_перебору_тексту.предмет_тексту), розмір_відступу, глибина + 1);
        вивести_кд(М, ",");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "значення=");
        якщо предмет_перебору_тексту.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(предмет_перебору_тексту.поточне_значення), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * (глибина + 1));
        вивести_кд(М, "позиція=");
        якщо предмет_перебору_тексту.почато {
          вивести_значення_1(М, виведені_предмети, ЧИСЛО(р64(предмет_перебору_тексту.позиція)), розмір_відступу, глибина + 1);
        } інакше {
          пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);
          вивести_кд(М, "недійсне");
          пристрій_мавки_вивести_формат(ФОчистити);
        }
        вивести_кд(М, "");

        вивести_пропуски(М, розмір_відступу * глибина);
        вивести_кд(М, ")");
        вернути;
      }

      якщо предмет.клас == М.клас_Послідовність {
        змінна властивості_списку = предмет як адреса<ПредметСписку>;

        якщо предмет_вже_виведено(виведені_предмети, предмет) {
          вивести_кд(М, "Послідовність(...)");
          вернути;
        }

        змінна свп = зберегти_стан_виведених_предметів(виведені_предмети);
        покласти_виведений_предмет(М, виведені_предмети, предмет);

        вивести_кд(М, "Послідовність(");

        якщо властивості_списку.розмір > 0 {
          якщо розмір_відступу > 0 {
            вивести_кд(М, "");
          }

          змінна п: природне = 0;
          поки п < властивості_списку.розмір {
            змінна елемент = властивості_списку.елементи[п];
            вивести_пропуски(М, розмір_відступу * (глибина + 1));
            вивести_значення_1(М, виведені_предмети, елемент, розмір_відступу, глибина + 1);
            якщо п + 1 < властивості_списку.розмір {
              вивести_кд(М, ",");
              якщо розмір_відступу > 0 {
                вивести_кд(М, "");
              } інакше {
                вивести_кд(М, " ");
              }
            }

            п += 1;
          }

          якщо розмір_відступу > 0 {
            вивести_кд(М, "");
          }
          вивести_пропуски(М, розмір_відступу * глибина);
        }

        вивести_кд(М, ")");

        відновити_стан_виведених_предметів(виведені_предмети, свп);

        вернути;
      }

      вивести_кд(М, "<невідомо>");
    }

    структура ДаніДіїПереборуВиводуВластивостейПредмета {
      предмет: адреса<Предмет>;
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>;
      виведені_властивості: адреса<Накопичувач<адреса<ПредметТексту>>>;
      розмір_відступу: природне;
      глибина: природне;
      щось_виведено: адреса<логічне>;
    }

    внутрішня дія дія_перебору_виводу_властивостей_предмета(
      М: адреса<Машина>,
      призначення: Призначення,
      назва: адреса<ПредметТексту>,
      значення: Значення,
      аргумент: невідома_адреса
    ) -> логічне {
      змінна дані = аргумент як адреса<ДаніДіїПереборуВиводуВластивостейПредмета>;
      змінна предмет = дані.предмет;
      змінна виведені_предмети = дані.виведені_предмети;
      змінна виведені_властивості = дані.виведені_властивості;
      змінна розмір_відступу = дані.розмір_відступу;
      змінна глибина = дані.глибина;

      змінна п: природне = 0;

      поки п < виведені_властивості.розмір {
        якщо перевірити_чи_предмети_тексту_рівні(М, назва, виведені_властивості.дані[п]) {
          вернути так;
        }

        п += 1;
      }

      якщо не дані.щось_виведено::вміст {
        якщо розмір_відступу > 0 {
          вивести_кд(М, "");
        }
      }

      дані.щось_виведено::вміст = так;

      вивести_пропуски(М, розмір_відступу * (глибина + 1));
      вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(назва), 0, 0);
      вивести_кд(М, "=");
      вивести_значення_1(М, виведені_предмети, значення, розмір_відступу, глибина + 1);
      вивести_кд(М, ",");
      якщо розмір_відступу > 0 {
        вивести_кд(М, "");
      } інакше {
        вивести_кд(М, " ");
      }

      вернути так;
    }


    внутрішня дія вивести_предмет(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      предмет: адреса<Предмет>,
      розмір_відступу: природне,
      глибина: природне
    ) {
      якщо предмет.клас.вбудований {
        вивести_вбудований_предмет(
          М,
          виведені_предмети,
          предмет,
          розмір_відступу,
          глибина
        );
        вернути;
      }

      пристрій_мавки_вивести_формат(ФКолірТекстуСиній);

      якщо предмет.клас.назва == пусто {
        вивести_кд(М, "<без_назви>");
      } інакше {
        вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет.клас.назва), 0, 0);
      }

      пристрій_мавки_вивести_формат(ФОчистити);

      якщо предмет_вже_виведено(виведені_предмети, предмет) {
        вивести_кд(М, "(...)");
        вернути;
      }

      змінна свп = зберегти_стан_виведених_предметів(виведені_предмети);
      покласти_виведений_предмет(М, виведені_предмети, предмет);

      вивести_кд(М, "(");

      змінна щось_виведено = ні;
      змінна виведені_властивості = зробити_накопичувач<адреса<ПредметТексту>>(М, предмет.клас.параметри.розмір);

      якщо предмет.клас.параметри.розмір > 0 {
        якщо розмір_відступу > 0 {
          вивести_кд(М, "");
        }

        змінна п: природне = 0;
        поки п < предмет.клас.параметри.розмір {
          змінна параметр = предмет.клас.параметри.елементи[п];
          змінна предмет_параметра = параметр.дані як адреса<Предмет> як адреса<ПредметПараметра>;

          покласти_в_накопичувач<адреса<ПредметТексту>>(М, виведені_властивості::адреса, предмет_параметра.назва);

          змінна значення_властивості = отримати_властивість(М, ПРЕДМЕТ(предмет), предмет_параметра.назва, Місцезнаходження { пусто, 0});
          вивести_пропуски(М, розмір_відступу * (глибина + 1));
          вивести_значення_1(М, виведені_предмети, ПРЕДМЕТ(предмет_параметра.назва), 0, 0);
          вивести_кд(М, "=");
          вивести_значення_1(М, виведені_предмети, значення_властивості, розмір_відступу, глибина + 1);
          вивести_кд(М, ",");
          якщо розмір_відступу > 0 {
            вивести_кд(М, "");
          } інакше {
            вивести_кд(М, " ");
          }

          щось_виведено = так;

          п += 1;
        }
      }

      змінна дані_дпввп = ДаніДіїПереборуВиводуВластивостейПредмета {
        предмет,
        виведені_предмети,
        виведені_властивості::адреса,
        розмір_відступу,
        глибина,
        щось_виведено::адреса
      };

      перебрати_призначення(
        М,
        (предмет як адреса<СкладенийПредмет>).властивості,
        дія_перебору_виводу_властивостей_предмета,
        дані_дпввп::адреса
      );

      звільнити(М, виведені_властивості.дані);

      якщо щось_виведено {
        вивести_пропуски(М, розмір_відступу * глибина);
      }

      вивести_кд(М, ")");

      відновити_стан_виведених_предметів(виведені_предмети, свп);
    }

    // позначка: прохід по типах предметів
    внутрішня дія вивести_значення_1(
      М: адреса<Машина>,
      виведені_предмети: адреса<Накопичувач<адреса<Предмет>>>,
      значення: Значення,
      розмір_відступу: природне,
      глибина: природне
    ) {
      якщо значення.вид == ЗНедійсне {
        пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);

        вивести_кд(М, "недійсне");

        пристрій_мавки_вивести_формат(ФОчистити);

        вернути;
      }

      якщо значення.вид == ЗДійсне {
        пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);

        вивести_кд(М, "дійсне");

        пристрій_мавки_вивести_формат(ФОчистити);

        вернути;
      }

      якщо значення.вид == ЗЧисло {
        пристрій_мавки_вивести_формат(ФКолірТекстуЖовтий);

        змінна значення_кд: кд;

        якщо перетворити_р64_в_кд(М, значення.дані як р64, значення_кд::адреса) {
          вивести_кд(М, значення_кд);
        }

        звільнити(М, значення_кд.дані);

        пристрій_мавки_вивести_формат(ФОчистити);

        вернути;
      }

      вивести_предмет(
        М,
        виведені_предмети,
        значення.дані як адреса<Предмет>,
        розмір_відступу,
        глибина
      );
    }

    // позначка: прохід по типах предметів
    дія вивести_значення(
      М: адреса<Машина>,
      значення: Значення,
      розмір_відступу: природне,
      глибина: природне
    ) {
      змінна виведені_предмети = зробити_накопичувач<адреса<Предмет>>(М, 32);

      вивести_значення_1(
        М,
        виведені_предмети::адреса,
        значення,
        розмір_відступу,
        глибина
      );

      звільнити(М, виведені_предмети.дані);
    }

    дія надрукувати_значення(М: адреса<Машина>, значення: Значення, розмір_відступу: природне, глибина: природне) {
      вивести_значення(
        М,
        значення,
        розмір_відступу,
        глибина
      );

      вивести_кд(М, "");
    }
  }
}