взяти визначення КД;
взяти визначення пристрій_мавки;
взяти визначення РМв1;

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

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

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

    вернути ні;
  }

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

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

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

    вернути ні;
  }

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

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

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

    вернути ні;
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

структура ДаніЧитанняВводу {
  М: *мавка::Машина;
  перед: *мавка::ПредметТексту;
  обробник: мавка::ОбробникПрочитанняВводу;
  аргумент: адреса;
}

внутрішня дія обробник_прочитання(
  дані: *п8,
  розмір: природне,
  кінець_файлу: логічне,
  аргумент: адреса,
) {
  змінна успіх: логічне;
  змінна дчв = аргумент як *ДаніЧитанняВводу;
  змінна М = дчв.М;

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

  мавка::звільнити(М, дчв);
}

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

  змінна дчв = мавка::виділити<ДаніЧитанняВводу>(М, 1);
  дчв.М = М;
  дчв.перед = перед;
  дчв.обробник = обробник;
  дчв.аргумент = аргумент;

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

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

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

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

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

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

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

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

внутрішня дія машина_обробник_падінь(
  М: *мавка::Машина,
  інформація_падіння: мавка::ІнформаціяПадіння
) {
  мавка::надрукувати_інформацію_падіння(
    М,
    інформація_падіння
  );
  пристрій_мавки_вийти(1);
}

синонім ТипДіїЗавантажитиРМв1 = (Р: *РМв1::Розширення, вихрез: *РМв1::Значення) -> логічне;

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

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

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

  успіх = (сдб як ТипДіїЗавантажитиРМв1)(Р, рез::адреса);
  якщо не успіх {
    // ...
  }

  вернути мавка::НЕДІЙСНЕ;
}

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

  змінна ос: п8;
  змінна розділювач_шляху: п8;
  змінна версія: кд;

  ос = пристрій_мавки_отримати_ос();
  якщо ос == 18 { // віндовс
    розділювач_шляху = КД::символи::Обернена_похила;
  } інакше {
    розділювач_шляху = КД::символи::Похила;
  }

  пристрій_мавки_отримати_версію(версія.дані::адреса, версія.розмір::адреса);

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

  мавка::звільнити(М, версія.дані);

  вернути М;
}

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

  пристрій_мавки_звільнити(М);
}