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

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

простір мавка {
  дія перетворити_п64_в_кд(
    М: *Машина,
    значення: п64,
    вихід_текстового_значення: *кд
  ) -> логічне {
    змінна значення_кд: кд;

    якщо пристрій_мавки_перетворити_п64_в_кд(значення, значення_кд.розмір::адреса, значення_кд.дані::адреса) {
      вихід_текстового_значення.розмір = значення_кд.розмір;
      вихід_текстового_значення.дані = значення_кд.дані;

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

    вернути ні;
  }

  дія перетворити_ц64_в_кд(
    М: *Машина,
    значення: ц64,
    вихід_текстового_значення: *кд
  ) -> логічне {
    змінна значення_кд: кд;

    якщо пристрій_мавки_перетворити_ц64_в_кд(значення, значення_кд.розмір::адреса, значення_кд.дані::адреса) {
      вихід_текстового_значення.розмір = значення_кд.розмір;
      вихід_текстового_значення.дані = значення_кд.дані;

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

    вернути ні;
  }

  дія перетворити_р64_в_кд(
    М: *Машина,
    значення: р64,
    вихід_текстового_значення: *кд
  ) -> логічне {
    змінна значення_кд: кд;
    змінна розмір_експоненти: ціле = 0;

    якщо пристрій_мавки_перетворити_р64_в_кд(значення, значення_кд.розмір::адреса, значення_кд.дані::адреса, розмір_експоненти::адреса) {
      якщо розмір_експоненти == 0 {
        вихід_текстового_значення.розмір = значення_кд.розмір;
        вихід_текстового_значення.дані = значення_кд.дані;

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

      змінна накопичувач_тексту = зробити_накопичувач_тексту(М, значення_кд.розмір + 10);
      покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, значення_кд);

      змінна значення_експоненти_кд: кд;

      якщо пристрій_мавки_перетворити_ц64_в_кд(розмір_експоненти, значення_експоненти_кд.розмір::адреса, значення_експоненти_кд.дані::адреса) {
        покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, "е");

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

        покласти_в_накопичувач_тексту(М, накопичувач_тексту::адреса, значення_експоненти_кд);

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

        вихід_текстового_значення.розмір = накопичувач_тексту.розмір;
        вихід_текстового_значення.дані = накопичувач_тексту.дані;

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

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

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

    вернути ні;
  }

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

  дія піднести_до_степеня_р64(
    М: *Машина,
    значення: р64,
    степінь: р64
  ) -> р64 {
    вернути пристрій_мавки_піднести_до_степеня_р64(значення, степінь);
  }

  простір пристрій {
    внутрішня дія машина_виділити_сиру_памʼять(
      М: *Машина,
      розмір: природне
    ) -> адреса {
      вернути пристрій_мавки_виділити(розмір);
    }

    внутрішня дія машина_перевиділити_сиру_памʼять(
      М: *Машина,
      значення: адреса,
      новий_розмір: природне
    ) -> адреса {
      вернути пристрій_мавки_перевиділити(значення, новий_розмір);
    }

    внутрішня дія машина_звільнити_сиру_памʼять(
      М: *Машина,
      значення: адреса
    ) {
      пристрій_мавки_звільнити(значення);
    }

    внутрішня дія машина_запанікувати(
      М: *Машина,
      повідомлення: кд
    ) {
      надрукувати_кд(М, повідомлення);

      пристрій_мавки_вийти(1);
    }

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

    внутрішня дія машина_вивести_шлях(
      М: *Машина,
      колір: природне,
      розмір: природне,
      дані: *п8
    ) {
      пристрій_мавки_вивести_шлях(колір, дані, розмір);
    }

    дія машина_отримати_теку_файлу(
      М: *Машина,
      шлях_до_файлу: *ПредметДаних,
      глибина: природне
    ) -> *ПредметДаних {
      змінна розмір: природне;
      змінна дані: *п8;

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

      вернути створити_дані(
        М,
        розмір,
        дані
      );
    }

    дія машина_прочитати_файл(
      М: *Машина,
      шлях_до_файлу: *ПредметДаних
    ) -> *ПредметДаних {
      змінна розмір: природне;
      змінна дані: *п8;

      якщо не пристрій_мавки_прочитати_файл(шлях_до_файлу.дані, шлях_до_файлу.розмір, дані::адреса, розмір::адреса) {
        вернути пусто;
      }

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

    внутрішня дія машина_перевірити_чи_шлях_починається_на(
      М: *Машина,
      шлях: *ПредметДаних,
      початок: *ПредметДаних
    ) -> логічне {
      вернути пристрій_мавки_перевірити_чи_шлях_починається_на(
        шлях.дані,
        шлях.розмір,
        початок.дані,
        початок.розмір
      );
    }

    внутрішня дія машина_отримати_шлях_до_паку_з_шляху_теки_модулів(
      М: *Машина,
      шлях_до_теки_модулів: *ПредметДаних,
      шлях_до_теки_паків: *ПредметДаних,
      вихід: **ПредметДаних
    ) -> логічне {
      змінна розмір: природне;
      змінна дані: *п8;

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

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

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

    внутрішня дія машина_збити_шлях_до_модуля(
      М: *Машина,
      розмір: природне,
      елементи: **ПредметДаних,
      вихід: **ПредметДаних
    ) -> логічне {
      змінна елементи_пристрою = виділити<ЕлементШляхуПристроюМавки>(М, розмір);
      змінна розмір_виходу: природне;
      змінна дані_виходу: *п8;

      змінна п: природне = 0;
      поки п < розмір {
        елементи_пристрою[п] = ЕлементШляхуПристроюМавки { елементи[п].дані, елементи[п].розмір };
        п += 1;
      }

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

      вихід::вміст = створити_дані_без_копіювання(
        М,
        розмір_виходу,
        дані_виходу
      );

      звільнити(М, елементи_пристрою);
      вернути так;
    }

    дія створити_машину() -> *Машина {
      змінна М = пристрій_мавки_виділити(Машина.розмір) як *Машина;

      налаштувати_машину(М, Налаштування {
        виділити_сиру_памʼять = машина_виділити_сиру_памʼять,
        перевиділити_сиру_памʼять = машина_перевиділити_сиру_памʼять,
        звільнити_сиру_памʼять = машина_звільнити_сиру_памʼять,
        запанікувати = машина_запанікувати,
        вивести_кд = машина_вивести_кд,
        вивести_шлях = машина_вивести_шлях,
        отримати_теку_файлу = машина_отримати_теку_файлу,
        прочитати_файл = машина_прочитати_файл,
        перевірити_чи_шлях_починається_на = машина_перевірити_чи_шлях_починається_на,
        отримати_шлях_до_паку_з_шляху_теки_модулів = машина_отримати_шлях_до_паку_з_шляху_теки_модулів,
        збити_шлях_до_модуля = машина_збити_шлях_до_модуля,
        взяти_біб = пусто,
      });

      вернути М;
    }

    дія розібрати_шлях_початкового_модуля(
      М: *Машина,
      шлях: *ПредметДаних,
      вихід_абсолютного_шляху: **ПредметДаних,
      вихід_теки_модулів: **ПредметДаних,
      вихід_теки_паків: **ПредметДаних,
      вихід_назви_модуля: **ПредметТексту
    ) -> логічне {
      змінна розмір_абсолютого_шляху: природне;
      змінна дані_абсолютного_шляху: *п8;
      змінна розмір_теки_модулів: природне;
      змінна дані_теки_модулів: *п8;
      змінна розмір_теки_паків: природне;
      змінна дані_теки_паків: *п8;
      змінна розмір_назви_модуля: природне;
      змінна дані_назви_модуля: *п8;

      якщо не пристрій_мавки_перевірити_чи_шлях_існує_і_є_файлом(
        шлях.дані,
        шлях.розмір
      ) {
        вернути ні;
      }

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

      якщо не пристрій_мавки_отримати_теку_шляху(
        дані_абсолютного_шляху,
        розмір_абсолютого_шляху,
        дані_теки_модулів::адреса,
        розмір_теки_модулів::адреса,
        1
      ) {
        пристрій_мавки_звільнити(дані_абсолютного_шляху);
        вернути ні;
      }

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

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

      вихід_абсолютного_шляху::вміст = створити_дані(
        М,
        розмір_абсолютого_шляху,
        дані_абсолютного_шляху
      );

      вихід_теки_модулів::вміст = створити_дані(
        М,
        розмір_теки_модулів,
        дані_теки_модулів
      );

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

      вихід_назви_модуля::вміст = створити_текст(
        М,
        кд { дані_назви_модуля, розмір_назви_модуля }
      );

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