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

взяти визначення мавка/машина;
взяти визначення мавка/розбирач;
взяти визначення мавка/перекладач;

простір мавка {
  дія взяти_файл(
    М: *Машина,
    шлях_до_файлу: *ПредметДаних,
    назва_модуля: *ПредметТексту,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    змінна успіх: логічне = ні;
    змінна значення = НЕДІЙСНЕ;
    змінна файл: *ПредметДаних = пусто;
    змінна сирий_текст: кд = кд { 0, пусто };
    змінна знаки: розбирач::Знаки;
    змінна помилка_розбору_на_знаки: розбирач::ПомилкаРозборуНаЗнаки;
    змінна сполуки: розбирач::Сполуки;
    змінна помилка_розбору_на_сполуки: розбирач::ПомилкаРозборуНаСполуки;
    змінна перекладений_код: *ПредметКоду = пусто;
    змінна помилка_перекладу: перекладач::ПомилкаПерекладу;
    змінна шлях_до_теки_модулів: *ПредметДаних = пусто;

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

    шлях_до_теки_модулів = отримати_теку_файлу(
      М,
      шлях_до_файлу,
      1
    );
    якщо шлях_до_теки_модулів == пусто {
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося отримати теку шляху."), місцезнаходження);
    }

    файл = прочитати_файл(
      М,
      шлях_до_файлу
    );
    якщо файл == пусто {
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося прочитати файл."), місцезнаходження);
    }

    успіх = перекодувати_ю8_в_кд(
      М,
      ю8 { файл.розмір, файл.дані },
      сирий_текст::адреса,
      пусто
    );
    якщо не успіх {
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося перекодувати файл в код мавки."), Місцезнаходження { шлях_до_файлу, 0 });
    }

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

      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалось розібрати на знаки."), Місцезнаходження { шлях_до_файлу, рядок });
    }

    успіх = розбирач::розібрати_знаки_на_сполуки(
      М,
      сирий_текст,
      знаки,
      сполуки::адреса,
      помилка_розбору_на_сполуки::адреса
    );
    якщо не успіх {
      змінна рядок = розбирач::отримати_рядок_помилки_розбору_на_сполуки(
        М,
        помилка_розбору_на_сполуки
      );
      увімкнути_стан_падіння(
        М,
        ПРЕДМЕТ(створити_текст(М, "Не вдалось розібрати на сполуки.")),
        Місцезнаходження { шлях_до_файлу, рядок }
      );
      вернути НЕДІЙСНЕ;
    }

    успіх = перекласти_в_код(
      М,
      створити_дані(М, шлях_до_файлу.розмір, шлях_до_файлу.дані),
      сирий_текст,
      знаки,
      сполуки,
      перекладений_код::адреса,
      помилка_перекладу::адреса
    );
    якщо не успіх {
      вернути МІСЦЕПАДІННЯ(М, створити_текст_без_копіювання(М, помилка_перекладу.повідомлення.розмір, помилка_перекладу.повідомлення.дані), Місцезнаходження { шлях_до_файлу, помилка_перекладу.рядок });
    }

    змінна предмет_модуля = створити_модуль(
      М,
      назва_модуля
    );

    записати_взяте_значення(
      М,
      шлях_до_файлу,
      ПРЕДМЕТ(предмет_модуля)
    );

    змінна предмет_дії_модуля = створити_дію(
      М,
      М.глобальна_дійсність,
      назва_модуля,
      М.пуста_послідовність,
      пусто,
      перекладений_код як *ПредметКоду,
      шлях_до_теки_модулів
    );

    змінна результат = предмет_дії_здійснити(
      М,
      ПРЕДМЕТ(предмет_модуля),
      предмет_дії_модуля,
      Задіяні { ВидЗадіяних2, 0, пусто, 0 },
      місцезнаходження
    );

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

    вернути ПРЕДМЕТ(предмет_модуля);
  }

  дія взяти_модуль(
    М: *Машина,
    шлях_до_теки_модулів: *ПредметДаних,
    відносно: логічне,
    довжина_шляху: природне,
    шлях: **ПредметТексту,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    змінна успіх: логічне = ні;
    змінна шлях_до_кореневої_теки_модулів = М.шлях_до_теки_модулів;
    змінна шлях_до_теки_паків = М.шлях_до_теки_паків;
    змінна предмет_шляху: *ПредметДаних = пусто;
    змінна розмір_елементів_збиття: природне = довжина_шляху + 1;
    змінна елементи_збиття = виділити<*ПредметДаних>(М, розмір_елементів_збиття);
    змінна позиція_елементів_збиття: природне = 0;
    змінна п: природне = 0;
    змінна значення_ю8: ю8 = ю8 { 0, пусто };
    змінна позиція_помилки: природне = 0;

    якщо відносно {
      елементи_збиття[позиція_елементів_збиття] = шлях_до_теки_модулів;

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

      якщо успіх {
        успіх = отримати_шлях_до_паку_з_шляху_теки_модулів(
          М,
          шлях_до_теки_модулів,
          шлях_до_теки_паків,
          елементи_збиття[позиція_елементів_збиття]::адреса,
        );
        якщо не успіх {
          звільнити(М, елементи_збиття);
          вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося отримати шлях до паку з шляху модуля."), місцезнаходження);
        }
      } інакше {
        елементи_збиття[позиція_елементів_збиття] = шлях_до_кореневої_теки_модулів;
      }

      позиція_елементів_збиття += 1;
    }

    поки п < довжина_шляху {
      успіх = перекодувати_кд_в_ю8(
        М,
        шлях[п].значення,
        значення_ю8::адреса,
        позиція_помилки::адреса
      );
      якщо не успіх {
        звільнити(М, елементи_збиття);
        вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося перекодувати елемент шляху модуля в ю8."), місцезнаходження);
      }

      елементи_збиття[позиція_елементів_збиття] = створити_дані(
        М,
        значення_ю8.розмір,
        значення_ю8.дані
      );

      позиція_елементів_збиття += 1;

      п += 1;
    }

    успіх = збити_шлях_до_модуля(
      М,
      розмір_елементів_збиття,
      елементи_збиття,
      предмет_шляху::адреса,
    );
    якщо не успіх {
      звільнити(М, елементи_збиття);
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося збити шлях до модуля."), місцезнаходження);
    }

    звільнити(М, елементи_збиття);

    вернути взяти_файл(
      М,
      предмет_шляху,
      шлях[довжина_шляху - 1],
      місцезнаходження
    );
  }

  дія взяти_пак(
    М: *Машина,
    довжина_шляху: природне,
    шлях: **ПредметТексту,
    місцезнаходження: Місцезнаходження
  ) -> ЗначенняАбоСтанПадіння {
    змінна успіх: логічне = ні;
    змінна шлях_до_теки_паків = М.шлях_до_теки_паків;
    змінна предмет_шляху: *ПредметДаних = пусто;
    змінна розмір_елементів_збиття: природне = довжина_шляху + 1;
    якщо довжина_шляху == 1 {
      розмір_елементів_збиття += 1;
    }
    змінна елементи_збиття = виділити<*ПредметДаних>(М, розмір_елементів_збиття);
    змінна позиція_елементів_збиття: природне = 0;
    змінна п: природне = 0;
    змінна значення_ю8: ю8 = ю8 { 0, пусто };
    змінна позиція_помилки: природне = 0;

    елементи_збиття[позиція_елементів_збиття] = шлях_до_теки_паків;

    позиція_елементів_збиття += 1;

    якщо довжина_шляху == 1 {
      успіх = перекодувати_кд_в_ю8(
        М,
        шлях[п].значення,
        значення_ю8::адреса,
        позиція_помилки::адреса
      );
      якщо не успіх {
        звільнити(М, елементи_збиття);
        вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося перекодувати елемент шляху модуля в ю8."), місцезнаходження);
      }

      елементи_збиття[позиція_елементів_збиття] = створити_дані_без_копіювання(
        М,
        значення_ю8.розмір,
        значення_ю8.дані
      );

      позиція_елементів_збиття += 1;
    }

    поки п < довжина_шляху {
      успіх = перекодувати_кд_в_ю8(
        М,
        шлях[п].значення,
        значення_ю8::адреса,
        позиція_помилки::адреса
      );
      якщо не успіх {
        звільнити(М, елементи_збиття);
        вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося перекодувати елемент шляху модуля в ю8."), місцезнаходження);
      }

      елементи_збиття[позиція_елементів_збиття] = створити_дані_без_копіювання(
        М,
        значення_ю8.розмір,
        значення_ю8.дані
      );

      позиція_елементів_збиття += 1;

      п += 1;
    }

    успіх = збити_шлях_до_модуля(
      М,
      розмір_елементів_збиття,
      елементи_збиття,
      предмет_шляху::адреса
    );
    якщо не успіх {
      звільнити(М, елементи_збиття);
      вернути МІСЦЕПАДІННЯ(М, створити_текст(М, "Не вдалося збити шлях до модуля."), місцезнаходження);
    }

    звільнити(М, елементи_збиття);

    вернути взяти_файл(
      М,
      предмет_шляху,
      шлях[довжина_шляху - 1],
      місцезнаходження
    );
  }
}