// 2025-2026 Богданович Давид Когут Прихожденко (кдб.дійсність.укр)
/* Перекладач Мавки */
взяти визначення мавка;
взяти визначення мавка/розбирач;
простір мавка {
простір перекладач {
структура ПомилкаПерекладу {
позиція_в_тексті: природне;
рядок: природне;
стовпець: природне;
повідомлення: кд; // має звільнити той хто оброляє помилку
}
структура Константи {
розмір: п32;
дані: *Значення;
}
структура Вказівки {
розмір: п32;
дані: *п8;
}
структура Повтор {
початок: п32;
позиції_вказівок_виходу: Накопичувач<п32>;
}
структура Код {
константи: Константи;
вказівки: Вказівки;
шлях: *ПредметДаних;
місцезнаходження_вказівок: МісцезнаходженняВказівок;
повтори: Накопичувач<Повтор>;
}
внутрішня дія перевірити_чи_кд_рівні(а: кд, б: кд) -> логічне {
якщо а.розмір != б.розмір {
вернути ні;
}
змінна п: природне = 0;
поки п < а.розмір {
якщо а.дані[п] != б.дані[п] {
вернути ні;
}
п += 1;
}
вернути так;
}
внутрішня дія перевірити_чи_починається_на(значення: кд, починається_на: кд, п: *природне) -> логічне {
змінна пп: природне = 0;
поки пп < починається_на.розмір {
змінна ппп = п::вміст + пп;
якщо ппп >= значення.розмір {
вернути ні;
}
якщо значення.дані[ппп] != починається_на.дані[пп] {
вернути ні;
}
пп += 1;
}
п::вміст = п::вміст + пп - 1;
вернути так;
}
внутрішня дія створити_код(М: *Машина, шлях: *ПредметДаних) -> *Код {
змінна код = виділити<Код>(М, 1);
код.константи = Константи { 0, пусто };
код.вказівки = Вказівки { 0, пусто };
код.шлях = шлях;
код.місцезнаходження_вказівок = МісцезнаходженняВказівок { 0, пусто };
код.повтори = зробити_накопичувач<Повтор>(М, 0);
вернути код;
}
внутрішня дія покласти_константу(М: *Машина, код: *Код, значення: Значення) -> п32 {
код.константи.дані = перевиділити<Значення>(М, код.константи.дані, природне(код.константи.розмір + 1));
код.константи.дані[код.константи.розмір] = значення;
код.константи.розмір += 1;
вернути код.константи.розмір - 1;
}
внутрішня дія покласти_константу_числа(М: *Машина, код: *Код, значення: р64) -> п32 {
змінна п: п32 = 0;
поки п < код.константи.розмір {
змінна константа = код.константи.дані[п];
якщо константа.вид == ЗЧисло {
якщо константа.дані як р64 == значення {
вернути п;
}
}
п += 1;
}
вернути покласти_константу(М, код, ЧИСЛО(значення));
}
внутрішня дія покласти_константу_тексту(М: *Машина, код: *Код, значення: кд) -> п32 {
змінна п: п32 = 0;
поки п < код.константи.розмір {
змінна константа = код.константи.дані[п];
якщо константа.вид == ЗПредмет {
змінна предмет_тексту = константа.дані як *Предмет як *ПредметТексту;
якщо предмет_тексту.клас == М.клас_Текст {
якщо перевірити_чи_кд_рівні(предмет_тексту.значення, значення) {
вернути п;
}
}
}
п += 1;
}
змінна предмет_тексту = створити_текст(М, значення);
вернути покласти_константу(М, код, ПРЕДМЕТ(предмет_тексту));
}
внутрішня дія покласти_константу_коду(М: *Машина, код: *Код, значення: адреса) -> п32 {
змінна значення_як_код = значення як *Код;
змінна константи = створити_послідовність_без_копіювання(М, природне(значення_як_код.константи.розмір), значення_як_код.константи.дані);
змінна вказівки = створити_дані_без_копіювання(М, природне(значення_як_код.вказівки.розмір), значення_як_код.вказівки.дані);
змінна предмет_коду = мавка::створити_код(М, константи, вказівки, значення_як_код.шлях, значення_як_код.місцезнаходження_вказівок);
вернути покласти_константу(М, код, ПРЕДМЕТ(предмет_коду));
}
внутрішня дія покласти_вказівку(М: *Машина, код: *Код, рядок: п32, вид: п8) -> п32 {
код.вказівки.дані = перевиділити<п8>(М, код.вказівки.дані, природне(код.вказівки.розмір + 1));
змінна позиція_вказівки = код.вказівки.розмір;
код.вказівки.дані[код.вказівки.розмір] = вид;
код.вказівки.розмір += 1;
покласти_місцезнаходження_вказівки(М, код.місцезнаходження_вказівок::адреса, рядок, позиція_вказівки);
вернути позиція_вказівки;
}
внутрішня дія покласти_вказівку_з_аргументом(М: *Машина, код: *Код, рядок: п32, вид: п8, аргумент: п32) -> п32 {
код.вказівки.дані = перевиділити<п8>(М, код.вказівки.дані, природне((код.вказівки.розмір + 1) + 4));
змінна позиція_вказівки = код.вказівки.розмір;
код.вказівки.дані[код.вказівки.розмір] = вид;
код.вказівки.розмір += 1;
змінна аргумент_байти = аргумент::адреса як *п8;
код.вказівки.дані[код.вказівки.розмір] = аргумент_байти[0];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_байти[1];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_байти[2];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_байти[3];
код.вказівки.розмір += 1;
покласти_місцезнаходження_вказівки(М, код.місцезнаходження_вказівок::адреса, рядок, позиція_вказівки);
вернути позиція_вказівки;
}
внутрішня дія покласти_вказівку_з_двома_аргументами(М: *Машина, код: *Код, рядок: п32, вид: п8, аргумент1: п32, аргумент2: п32) -> п32 {
код.вказівки.дані = перевиділити<п8>(М, код.вказівки.дані, природне((код.вказівки.розмір + 1) + 8));
змінна позиція_вказівки = код.вказівки.розмір;
код.вказівки.дані[код.вказівки.розмір] = вид;
код.вказівки.розмір += 1;
змінна аргумент_1_байти = аргумент1::адреса як *п8;
код.вказівки.дані[код.вказівки.розмір] = аргумент_1_байти[0];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_1_байти[1];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_1_байти[2];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_1_байти[3];
код.вказівки.розмір += 1;
змінна аргумент_2_байти = аргумент2::адреса як *п8;
код.вказівки.дані[код.вказівки.розмір] = аргумент_2_байти[0];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_2_байти[1];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_2_байти[2];
код.вказівки.розмір += 1;
код.вказівки.дані[код.вказівки.розмір] = аргумент_2_байти[3];
код.вказівки.розмір += 1;
покласти_місцезнаходження_вказівки(М, код.місцезнаходження_вказівок::адреса, рядок, позиція_вказівки);
вернути позиція_вказівки;
}
внутрішня дія змінити_аргумент_вказівки(М: *Машина, код: *Код, позиція_виду_вказівки: п32, позиція_аргумента_вказівки: п32, новий_аргумент: п32) {
змінна позиція_аргумента_як_байти = позиція_виду_вказівки + 1 + (позиція_аргумента_вказівки * 4);
змінна новий_аргумент_як_байти = новий_аргумент::адреса як *п8;
код.вказівки.дані[позиція_аргумента_як_байти + 0] = новий_аргумент_як_байти[0];
код.вказівки.дані[позиція_аргумента_як_байти + 1] = новий_аргумент_як_байти[1];
код.вказівки.дані[позиція_аргумента_як_байти + 2] = новий_аргумент_як_байти[2];
код.вказівки.дані[позиція_аргумента_як_байти + 3] = новий_аргумент_як_байти[3];
}
внутрішня дія отримати_розмір_вказівок(М: *Машина, код: *Код) -> п32 {
вернути код.вказівки.розмір;
}
внутрішня дія отримати_шлях_коду(М: *Машина, код: *Код) -> *ПредметДаних {
вернути код.шлях;
}
внутрішня дія покласти_повтор(М: *Машина, код: *Код, позиція_початку: п32) -> *Повтор {
покласти_в_накопичувач<Повтор>(М, код.повтори::адреса, Повтор { позиція_початку, зробити_накопичувач<п32>(М, 0) });
вернути код.повтори.дані[код.повтори.розмір - 1]::адреса;
}
внутрішня дія обробити_позиції_вказівок_виходу_з_повтору(М: *Машина, код: *Код, повтор: *Повтор, позиція_виходу: п32) {
змінна п: п32 = 0;
поки п < п32(повтор.позиції_вказівок_виходу.розмір) {
змінити_аргумент_вказівки(М, код, повтор.позиції_вказівок_виходу.дані[п], 0, позиція_виходу);
п += 1;
}
}
внутрішня дія видалити_останній_повтор(М: *Машина, код: *Код) {
змінна повтор = код.повтори.дані[код.повтори.розмір - 1];
звільнити(М, повтор.позиції_вказівок_виходу.дані);
код.повтори.розмір -= 1;
}
внутрішня дія отримати_останній_повтор_з_коду(М: *Машина, код: *Код) -> *Повтор {
якщо код.повтори.розмір == 0 {
вернути пусто;
}
вернути код.повтори.дані[код.повтори.розмір - 1]::адреса;
}
внутрішня дія додати_позицію_перезапису_вказівки_стрибнути_для_виходу_з_повтору(М: *Машина, повтор: *Повтор, позиція: п32) {
покласти_в_накопичувач<п32>(М, повтор.позиції_вказівок_виходу::адреса, позиція);
}
дія перекласти(
М: *Машина,
шлях: *ПредметДаних,
сирий_текст: кд,
знаки: розбирач::Знаки,
здійснимі: розбирач::Сполуки,
вихід_коду: **Код,
вихід_помилки: *ПомилкаПерекладу
) -> логічне;
}
дія перекласти_в_код(
М: *Машина,
шлях: *ПредметДаних,
сирий_текст: кд,
знаки: розбирач::Знаки,
здійснимі: розбирач::Сполуки,
вихід_коду: **ПредметКоду,
вихід_помилки: *перекладач::ПомилкаПерекладу
) -> логічне;
}