Автоматически вызывать нужные функции печати в зависимости от типа

This commit is contained in:
rexim 2024-01-09 05:07:43 +07:00
parent b270d1f9e7
commit 2b4deb6401
2 changed files with 36 additions and 13 deletions

View File

@ -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() });
}
Тип::Массив{..} => {
сделать!(арг.лок(), "печать массивов");

View File

@ -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);
кц