From 2b4deb64019085a302e462d4582debbc7a125b7f Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 9 Jan 2024 05:07:43 +0700 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=20=D0=B2=D1=8B=D0=B7=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BD=D1=83=D0=B6=D0=BD=D1=8B=D0=B5?= =?UTF-8?q?=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=87=D0=B0=D1=82=D0=B8=20=D0=B2=20=D0=B7=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8=20=D0=BE=D1=82=20?= =?UTF-8?q?=D1=82=D0=B8=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- исходники/компилятор.rs | 35 ++++++++++++++++++++++++++++++----- прелюдия.хуя | 14 ++++++-------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/исходники/компилятор.rs b/исходники/компилятор.rs index cc766a2..62091cf 100644 --- a/исходники/компилятор.rs +++ b/исходники/компилятор.rs @@ -454,6 +454,27 @@ fn скомпилировать_выражение(пп: &mut ПП, имена: } } +fn достать_и_проверить_процедуру_печати<'ы>(имена: &'ы Имена, имя_принтера: &str, тип: &Тип, лок: &Лок) -> Результат<&'ы СкомпПроцедура> { + if let Some(процедура) = имена.процедуры.get(имя_принтера) { + let арность = 1; + let [параметр] = процедура.параметры.as_slice() else { + диагностика!(лок, "ОШИБКА", "Процедура «{имя_принтера}» ответственная за печать данного аргумента типа «{тип}» имеет некорректную сигнатуру. Она должна принимать {арность} {параметров} типа «{тип}»", тип = тип.текст(), параметров = ЧИСУЩ_ПАРАМЕТР.текст(арность)); + диагностика!(&процедура.имя.лок, "ИНФО", "Но по факту, она принимает {число_параметров}", число_параметров = процедура.параметры.len()); + return Err(()); + }; + if параметр.тип != *тип { + диагностика!(лок, "ОШИБКА", "Процедура «{имя_принтера}» ответственная за печать данного аргумента типа «{тип}» имеет некорректную сигнатуру. Она должна принимать {арность} {параметров} типа «{тип}»", тип = тип.текст(), параметров = ЧИСУЩ_ПАРАМЕТР.текст(арность)); + диагностика!(&процедура.имя.лок, "ИНФО", "Но по факту, она принимает тип «{тип}»", тип = параметр.тип.текст()); + return Err(()); + } + + Ok(процедура) + } else { + диагностика!(лок, "ОШИБКА", "Чтобы печатать значения тип «{тип}», нужно чтобы где-нибудь была определена процедура с именем «{имя_принтера}», которая принимает один аргумент типа «{тип}» и печатает его. Мы не смогли найти определение такой процедуры. Обычно все нужные процедуры печати определены в модуле «прелюдия». Возможно мы не смогли его загрузить.", тип = тип.текст()); + Err(()) + } +} + fn скомпилировать_утвержление(пп: &mut ПП, имена: &Имена, параметры: &Vec<СкомпПараметр>, утверждение: &Утверждение) -> Результат<()> { match утверждение { Утверждение::Присваивание{ключ, имя, значение} => { @@ -530,18 +551,22 @@ fn скомпилировать_утвержление(пп: &mut ПП, имен for арг in аргументы { let тип = скомпилировать_выражение(пп, имена, параметры, &арг)?; match тип { - Тип::Строка => пп.код.push(Инструкция{ вид: ВидИнструкции::ПечатьСтроки, лок: имя.лок.clone() }), + Тип::Строка => { + пп.код.push(Инструкция{ вид: ВидИнструкции::ПечатьСтроки, лок: арг.лок().clone() }) + } Тип::Цел64 => { - сделать!(арг.лок(), "печать цел(8)"); - return Err(()) + let процедура = достать_и_проверить_процедуру_печати(имена, "печать_цел", &тип, &арг.лок())?; + пп.код.push(Инструкция { вид: ВидИнструкции::ВызватьПроцедуру(процедура.точка_входа), лок: арг.лок().clone() }); + пп.код.push(Инструкция { вид: ВидИнструкции::Вытолкнуть(процедура.параметры.len()), лок: арг.лок().clone() }); } Тип::Цел8 => { сделать!(арг.лок(), "печать цел(1)"); return Err(()) } Тип::Лог => { - сделать!(арг.лок(), "печать логического типа"); - return Err(()) + let процедура = достать_и_проверить_процедуру_печати(имена, "печать_лог", &тип, &арг.лок())?; + пп.код.push(Инструкция { вид: ВидИнструкции::ВызватьПроцедуру(процедура.точка_входа), лок: арг.лок().clone() }); + пп.код.push(Инструкция { вид: ВидИнструкции::Вытолкнуть(процедура.параметры.len()), лок: арг.лок().clone() }); } Тип::Массив{..} => { сделать!(арг.лок(), "печать массивов"); diff --git a/прелюдия.хуя b/прелюдия.хуя index acdb151..d9dcf8e 100644 --- a/прелюдия.хуя +++ b/прелюдия.хуя @@ -2,6 +2,9 @@ пер буфер: массив(ОБЪЁМ, цел8); пер размер: цел; +// СДЕЛАТЬ: загрузка модуля «прелюдия» (я пока не знаю как) +// СДЕЛАТЬ: ввести функцию печать_строки, которая делает системный вызов SYS_write + про печать_цел(число: цел) нч если число == 0 нч печать(«0»); @@ -32,17 +35,12 @@ кц про тест(а: цел, б: цел) нч - печать_цел(а + б); - печать(«\н»); + печать(а + б, «\н»); кц про главная() нч - печать_цел(0); печать(«\н»); - печать_цел(69); печать(«\н»); - печать_цел(1234567890); печать(«\н»); - печать(«----------\н»); - печать_лог(69 == 69); печать(«\н»); - печать_лог(69 == 420); печать(«\н»); + печать(«Печать чисел: », 0, «, », 69, «, », 1234567890, «\н»); + печать(«Печать логических: », 69 == 69, «, », 69 == 420, «\н»); печать(«----------\н»); тест(34, 35); кц