mirror of
https://github.com/tsoding/good_training_language.git
synced 2026-09-12 19:50:53 +05:00
Цикл «для»
This commit is contained in:
parent
c88594805a
commit
18ac43be10
8
ПЛАН.txt
8
ПЛАН.txt
@ -28,12 +28,14 @@
|
||||
- [x] Инициализация локальных переменных
|
||||
- [x] Локальные массивы
|
||||
- [x] Локальные константы
|
||||
- [ ] Циклы «для»
|
||||
- [x] Циклы «для»
|
||||
- [ ] Объявление переменных в цикле «для»
|
||||
- [ ] Перечисления в каком-нибудь виде
|
||||
- [ ] Switch-case-ы в каком-то виде
|
||||
- [ ] Динамическая память в каком-нибудь виде
|
||||
- [ ] Типизированные константы
|
||||
- [ ] Через интерпретацию ПП
|
||||
- [ ] Передача переменных по ссылке
|
||||
- [ ] Перечисления в каком-нибудь виде
|
||||
- [ ] Динамическая память в каком-нибудь виде
|
||||
- [ ] Знаковые целые
|
||||
- [ ] Что дальше?
|
||||
|
||||
|
||||
@ -304,19 +304,10 @@ fn скомпилировать_выражение(пп: &mut ПП, имена:
|
||||
return Ok(Тип::Цел64);
|
||||
}
|
||||
if let Some((переменная, локация)) = найти_переменную_по_имени(&лексема.текст, имена, текущая_процедура, локальные_имена) {
|
||||
match локация {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ГлобальныеДанные(переменная.смещение), лок: лексема.лок.clone() });
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(переменная.смещение), лок: лексема.лок.clone() });
|
||||
}
|
||||
}
|
||||
локация.протолкнуть_смещение(пп, &лексема.лок, переменная.смещение);
|
||||
if переменная.тип.примитивный() {
|
||||
прочитать_примитивный_тип(&лексема.лок, &mut пп.код, переменная.тип.размер(&имена.структуры))?;
|
||||
}
|
||||
|
||||
return Ok(переменная.тип.clone());
|
||||
}
|
||||
|
||||
@ -566,15 +557,7 @@ fn скомпилировать_выражение(пп: &mut ПП, имена:
|
||||
}
|
||||
|
||||
// СДЕЛАТЬ: принимать срез по аналогии с ПечатьСтроки
|
||||
match локация {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ГлобальныеДанные(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
}
|
||||
локация.протолкнуть_смещение(пп, &имя.лок, переменная.смещение);
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Целое(*размер), лок: имя.лок.clone() });
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Ввод, лок: имя.лок.clone() });
|
||||
return Ok(Тип::Цел64);
|
||||
@ -622,16 +605,7 @@ fn скомпилировать_выражение(пп: &mut ПП, имена:
|
||||
|
||||
let тип_размера_среза = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, &размер_среза, временный_размер)?;
|
||||
проверить_типы(&размер_среза.лок(), &Тип::Цел64, &тип_размера_среза)?;
|
||||
|
||||
match локация {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ГлобальныеДанные(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
}
|
||||
локация.протолкнуть_смещение(пп, &имя.лок, переменная.смещение);
|
||||
|
||||
let тип_начала = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, &начало_среза, временный_размер)?;
|
||||
проверить_типы(&размер_среза.лок(), &Тип::Цел64, &тип_начала)?;
|
||||
@ -747,15 +721,7 @@ fn скомпилировать_выражение(пп: &mut ПП, имена:
|
||||
return Err(());
|
||||
};
|
||||
|
||||
match локация {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{вид: ВидИнструкции::ГлобальныеДанные(переменная.смещение), лок: имя.лок.clone()});
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{вид: ВидИнструкции::Кадр(переменная.смещение), лок: имя.лок.clone()});
|
||||
}
|
||||
}
|
||||
локация.протолкнуть_смещение(пп, &имя.лок, переменная.смещение);
|
||||
|
||||
// СДЕЛАТЬ: проверка входа за границы массива.
|
||||
|
||||
@ -880,6 +846,20 @@ enum Локация {
|
||||
Стековая,
|
||||
}
|
||||
|
||||
impl Локация {
|
||||
fn протолкнуть_смещение(&self, пп: &mut ПП, лок: &Лок, смещение: i32) {
|
||||
match self {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ГлобальныеДанные(смещение), лок: лок.clone() });
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(смещение), лок: лок.clone() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn найти_константу_по_имени<'ы>(имя: &str, имена: &'ы Имена, локальные_имена: Option<&'ы ЛокальныеИмена>) -> Option<&'ы СкомпКонстанта> {
|
||||
if let Some(локальные_имена) = локальные_имена {
|
||||
if let Some(константа) = локальные_имена.найти_константу_по_имени(имя) {
|
||||
@ -936,15 +916,7 @@ fn скомпилировать_левое_выражение(пп: &mut ПП,
|
||||
}
|
||||
Выражение::Идент(имя) => {
|
||||
if let Some((переменная, локация)) = найти_переменную_по_имени(&имя.текст, имена, текущая_процедура, локальные_имена) {
|
||||
match локация {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ГлобальныеДанные(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
}
|
||||
локация.протолкнуть_смещение(пп, &имя.лок, переменная.смещение);
|
||||
return Ok(переменная.тип.clone());
|
||||
}
|
||||
|
||||
@ -959,15 +931,7 @@ fn скомпилировать_левое_выражение(пп: &mut ПП,
|
||||
let индекс = &аргументы[0];
|
||||
|
||||
if let Some((переменная, локация)) = найти_переменную_по_имени(&имя.текст, имена, текущая_процедура, локальные_имена) {
|
||||
match локация {
|
||||
Локация::Глобальная => {
|
||||
пп.заплатки_неиниц_указателей.push(пп.код.len());
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ГлобальныеДанные(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
Локация::Стековая => {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(переменная.смещение), лок: имя.лок.clone() });
|
||||
}
|
||||
}
|
||||
локация.протолкнуть_смещение(пп, &имя.лок, переменная.смещение);
|
||||
let тип_элемента = индексировать_массив(&имя.лок, переменная, пп, имена, текущая_процедура, локальные_имена, индекс, временный_размер)?;
|
||||
return Ok(тип_элемента);
|
||||
}
|
||||
@ -1027,6 +991,16 @@ fn скомпилировать_левое_выражение(пп: &mut ПП,
|
||||
}
|
||||
}
|
||||
|
||||
fn записать_тип(лок: &Лок, код: &mut Vec<Инструкция>, структуры: &HashMap<String, Структура>, тип: &Тип) -> Результат<()> {
|
||||
if тип.примитивный() {
|
||||
записать_примитивный_тип(лок, код, тип.размер(структуры))?;
|
||||
} else {
|
||||
код.push(Инструкция{ вид: ВидИнструкции::Целое(тип.размер(структуры)), лок: лок.clone() });
|
||||
код.push(Инструкция{ вид: ВидИнструкции::СкопироватьПамять, лок: лок.clone() });
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn скомпилировать_утверждение(пп: &mut ПП, имена: &Имена, текущая_процедура: &СкомпПроцедура, локальные_имена: &mut ЛокальныеИмена, утверждение: &Утверждение, отложенные_возвраты: &mut Vec<usize>) -> Результат<()> {
|
||||
match утверждение {
|
||||
Утверждение::Присваивание{ключ, левое, правое} => {
|
||||
@ -1034,12 +1008,7 @@ fn скомпилировать_утверждение(пп: &mut ПП, имен
|
||||
let правый_тип = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, правое, &mut временный_размер)?;
|
||||
let левый_тип = скомпилировать_левое_выражение(пп, имена, текущая_процедура, локальные_имена, левое, &mut временный_размер)?;
|
||||
проверить_типы(правое.лок(), &левый_тип, &правый_тип)?;
|
||||
if левый_тип.примитивный() {
|
||||
записать_примитивный_тип(&ключ.лок, &mut пп.код, левый_тип.размер(&имена.структуры))?;
|
||||
} else {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Целое(левый_тип.размер(&имена.структуры)), лок: ключ.лок.clone() });
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::СкопироватьПамять, лок: ключ.лок.clone() });
|
||||
}
|
||||
записать_тип(&ключ.лок, &mut пп.код, &имена.структуры, &левый_тип)?;
|
||||
if временный_размер > 0 {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ОсвободитьСоСтека(временный_размер as u64), лок: ключ.лок.clone() })
|
||||
}
|
||||
@ -1193,12 +1162,7 @@ fn скомпилировать_утверждение(пп: &mut ПП, имен
|
||||
let тип = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, &выражение, &mut временный_размер)?;
|
||||
проверить_типы(&выражение.лок(), &результат.тип, &тип)?;
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(результат.смещение_от_кадра), лок: ключ.лок.clone() });
|
||||
if тип.примитивный() {
|
||||
записать_примитивный_тип(&ключ.лок, &mut пп.код, тип.размер(&имена.структуры))?;
|
||||
} else {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Целое(тип.размер(&имена.структуры)), лок: ключ.лок.clone() });
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::СкопироватьПамять, лок: ключ.лок.clone() });
|
||||
}
|
||||
записать_тип(&ключ.лок, &mut пп.код, &имена.структуры, &тип)?;
|
||||
let размер_всех_локальных_переменных = локальные_имена
|
||||
.стек_областей
|
||||
.iter()
|
||||
@ -1251,6 +1215,69 @@ fn скомпилировать_утверждение(пп: &mut ПП, имен
|
||||
пп.код[точка_условного_прыжка].вид = ВидИнструкции::УсловныйПрыжок(точка_выхода);
|
||||
Ok(())
|
||||
}
|
||||
Утверждение::Для{ключ, индекс, нижняя_граница, верхняя_граница, тело} => {
|
||||
if let Some((переменная, локация)) = найти_переменную_по_имени(&индекс.текст, имена, текущая_процедура, локальные_имена) {
|
||||
проверить_типы(&индекс.лок, &Тип::Цел64, &переменная.тип)?;
|
||||
|
||||
// Инициализация индексной переменной
|
||||
let mut временный_размер = 0;
|
||||
let тип_нижней_границы = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, &нижняя_граница, &mut временный_размер)?;
|
||||
проверить_типы(&нижняя_граница.лок(), &переменная.тип, &тип_нижней_границы)?;
|
||||
локация.протолкнуть_смещение(пп, &индекс.лок, переменная.смещение);
|
||||
записать_тип(&индекс.лок, &mut пп.код, &имена.структуры, &переменная.тип)?;
|
||||
if временный_размер > 0 {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ОсвободитьСоСтека(временный_размер as u64), лок: ключ.лок.clone() });
|
||||
временный_размер = 0;
|
||||
}
|
||||
|
||||
// Проверка условия выхода из цикла
|
||||
let точка_условия = пп.код.len();
|
||||
локация.протолкнуть_смещение(пп, &индекс.лок, переменная.смещение);
|
||||
прочитать_примитивный_тип(&индекс.лок, &mut пп.код, переменная.тип.размер(&имена.структуры))?;
|
||||
let тип_верхней_границы = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, &верхняя_граница, &mut временный_размер)?;
|
||||
проверить_типы(&верхняя_граница.лок(), &переменная.тип, &тип_верхней_границы)?;
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ЦелБольше, лок: ключ.лок.clone() });
|
||||
let точка_условного_прыжка = пп.код.len();
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Ноп, лок: ключ.лок.clone() });
|
||||
if временный_размер > 0 {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ОсвободитьСоСтека(временный_размер as u64), лок: ключ.лок.clone() });
|
||||
}
|
||||
|
||||
let переменная_тип = переменная.тип.clone();
|
||||
let переменная_смещение = переменная.смещение;
|
||||
|
||||
// Тело
|
||||
локальные_имена.стек_областей.push(Default::default());
|
||||
for утверждение in тело.iter() {
|
||||
скомпилировать_утверждение(пп, имена, текущая_процедура, локальные_имена, утверждение, отложенные_возвраты)?;
|
||||
}
|
||||
let размер_области = локальные_имена
|
||||
.стек_областей
|
||||
.pop()
|
||||
.expect("Тело цикла «для» не трогает область которую мы протолкнули")
|
||||
.размер_переменных_на_стеке;
|
||||
if размер_области > 0 {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ОсвободитьСоСтека(размер_области as u64), лок: ключ.лок.clone() });
|
||||
}
|
||||
|
||||
// Инкремент
|
||||
локация.протолкнуть_смещение(пп, &индекс.лок, переменная_смещение);
|
||||
прочитать_примитивный_тип(&индекс.лок, &mut пп.код, переменная_тип.размер(&имена.структуры))?;
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Целое(1), лок: ключ.лок.clone() });
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ЦелСложение, лок: ключ.лок.clone() });
|
||||
локация.протолкнуть_смещение(пп, &индекс.лок, переменная_смещение);
|
||||
записать_тип(&индекс.лок, &mut пп.код, &имена.структуры, &переменная_тип)?;
|
||||
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Прыжок(точка_условия), лок: ключ.лок.clone() });
|
||||
let точка_выхода = пп.код.len();
|
||||
пп.код[точка_условного_прыжка].вид = ВидИнструкции::УсловныйПрыжок(точка_выхода);
|
||||
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
диагностика!(&индекс.лок, "ОШИБКА", "Неизвестная переменная «{имя}»", имя = индекс.текст);
|
||||
Err(())
|
||||
}
|
||||
Утверждение::ДекларацияПеременной{ключ, имя, тип, значение} => {
|
||||
let размер_всех_локальных_переменных = локальные_имена
|
||||
.стек_областей
|
||||
@ -1271,12 +1298,7 @@ fn скомпилировать_утверждение(пп: &mut ПП, имен
|
||||
let тип_значения = скомпилировать_выражение(пп, имена, текущая_процедура, локальные_имена, значение, &mut временный_размер)?;
|
||||
проверить_типы(&значение.лок(), &тип_переменной, &тип_значения)?;
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Кадр(смещение), лок: ключ.лок.clone() });
|
||||
if тип_переменной.примитивный() {
|
||||
записать_примитивный_тип(&ключ.лок, &mut пп.код, тип_переменной.размер(&имена.структуры))?;
|
||||
} else {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::Целое(тип_переменной.размер(&имена.структуры)), лок: ключ.лок.clone() });
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::СкопироватьПамять, лок: ключ.лок.clone() });
|
||||
}
|
||||
записать_тип(&ключ.лок, &mut пп.код, &имена.структуры, &тип_переменной)?;
|
||||
if временный_размер > 0 {
|
||||
пп.код.push(Инструкция{ вид: ВидИнструкции::ОсвободитьСоСтека(временный_размер as u64), лок: ключ.лок.clone() });
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ pub const ПРИСТАВКИ_ПРЕПИНАНИЙ: &[(&[char], ВидЛексе
|
||||
(&['('], ВидЛексемы::ОткрытаяСкобка),
|
||||
(&[')'], ВидЛексемы::ЗакрытаяСкобка),
|
||||
(&[';'], ВидЛексемы::ТочкаЗапятая),
|
||||
(&['.', '.'], ВидЛексемы::ТочкаТочка),
|
||||
(&['.'], ВидЛексемы::Точка),
|
||||
(&[':', '='], ВидЛексемы::Присваивание),
|
||||
(&[':'], ВидЛексемы::Двоеточие),
|
||||
@ -29,6 +30,7 @@ pub const КЛЮЧЕВЫЕ_СЛОВА: &[(&str, ВидЛексемы)] = &[
|
||||
("то", ВидЛексемы::КлючТо),
|
||||
("иначе", ВидЛексемы::КлючИначе),
|
||||
("пока", ВидЛексемы::КлючПока),
|
||||
("для", ВидЛексемы::КлючДля),
|
||||
("вернуть", ВидЛексемы::КлючВернуть),
|
||||
("не", ВидЛексемы::КлючНе),
|
||||
("мн", ВидЛексемы::КлючМн),
|
||||
@ -57,6 +59,7 @@ pub enum ВидЛексемы {
|
||||
КлючТо,
|
||||
КлючИначе,
|
||||
КлючПока,
|
||||
КлючДля,
|
||||
КлючВернуть,
|
||||
КлючНе,
|
||||
КлючМн,
|
||||
@ -76,6 +79,7 @@ pub enum ВидЛексемы {
|
||||
ЗакрытаяСкобка,
|
||||
ТочкаЗапятая,
|
||||
Точка,
|
||||
ТочкаТочка,
|
||||
Двоеточие,
|
||||
Запятая,
|
||||
Плюс,
|
||||
@ -106,6 +110,7 @@ impl ВидЛексемы {
|
||||
ВидЛексемы::КлючТо => Сущ{текст: "«то»", род: Род::Сред},
|
||||
ВидЛексемы::КлючИначе => Сущ{текст: "«иначе»", род: Род::Сред},
|
||||
ВидЛексемы::КлючПока => Сущ{текст: "«пока»", род: Род::Сред},
|
||||
ВидЛексемы::КлючДля => Сущ{текст: "«для»", род: Род::Сред},
|
||||
ВидЛексемы::КлючВернуть => Сущ{текст: "«вернуть»", род: Род::Сред},
|
||||
ВидЛексемы::КлючНе => Сущ{текст: "«не»", род: Род::Сред},
|
||||
ВидЛексемы::КлючМн => Сущ{текст: "«мн»", род: Род::Сред},
|
||||
@ -126,6 +131,7 @@ impl ВидЛексемы {
|
||||
ВидЛексемы::ЗакрытаяСкобка => Сущ{текст: "закрытая скобка", род: Род::Жен},
|
||||
ВидЛексемы::ТочкаЗапятая => Сущ{текст: "точка с запятой", род: Род::Жен},
|
||||
ВидЛексемы::Точка => Сущ{текст: "точка", род: Род::Жен},
|
||||
ВидЛексемы::ТочкаТочка => Сущ{текст: "точка точка", род: Род::Жен},
|
||||
ВидЛексемы::Двоеточие => Сущ{текст: "двоеточие", род: Род::Сред},
|
||||
ВидЛексемы::Запятая => Сущ{текст: "запятая", род: Род::Жен},
|
||||
ВидЛексемы::Плюс => Сущ{текст: "плюс", род: Род::Муж},
|
||||
@ -262,7 +268,9 @@ impl<'a> Лексер<'a> {
|
||||
while self.символы.get(self.позиция).map(|сим| сим.is_numeric()).unwrap_or(false) {
|
||||
self.отрезать_символ();
|
||||
}
|
||||
if let Some('.') = self.символы.get(self.позиция) {
|
||||
// Это условие крайне важно, чтобы разобрать выражение
|
||||
// "1..10" как "1", "..", "10".
|
||||
if Some('.') == self.символы.get(self.позиция).cloned() && Some('.') != self.символы.get(self.позиция + 1).cloned() {
|
||||
self.отрезать_символ();
|
||||
while self.символы.get(self.позиция).map(|сим| сим.is_numeric()).unwrap_or(false) {
|
||||
self.отрезать_символ();
|
||||
|
||||
@ -211,6 +211,7 @@ pub enum Утверждение {
|
||||
Присваивание{ключ: Лексема, левое: Выражение, правое: Выражение},
|
||||
Выражение{выражение: Выражение},
|
||||
Пока{ключ: Лексема, условие: Выражение, тело: Vec<Утверждение>},
|
||||
Для{ключ: Лексема, индекс: Лексема, нижняя_граница: Выражение, верхняя_граница: Выражение, тело: Vec<Утверждение>},
|
||||
Если{ключ: Лексема, условие: Выражение, тело: Vec<Утверждение>, иначе: Vec<Утверждение>},
|
||||
Вернуть{ключ: Лексема, выражение: Option<Выражение>},
|
||||
ДекларацияПеременной{ключ: Лексема, имя: Лексема, тип: Выражение, значение: Option<Выражение>},
|
||||
@ -258,6 +259,16 @@ fn разобрать_утверждение(лекс: &mut Лексер) -> Р
|
||||
let тело = разобрать_блок_кода(лекс)?;
|
||||
Ok(Утверждение::Пока{ключ, условие, тело})
|
||||
}
|
||||
ВидЛексемы::КлючДля => {
|
||||
let ключ = лекс.вытащить_лексему().unwrap();
|
||||
let индекс = лекс.вытащить_лексему_вида(&[ВидЛексемы::Идент])?;
|
||||
let _ = лекс.вытащить_лексему_вида(&[ВидЛексемы::Присваивание])?;
|
||||
let нижняя_граница = Выражение::разобрать(лекс)?;
|
||||
let _ = лекс.вытащить_лексему_вида(&[ВидЛексемы::ТочкаТочка])?;
|
||||
let верхняя_граница = Выражение::разобрать(лекс)?;
|
||||
let тело = разобрать_блок_кода(лекс)?;
|
||||
Ok(Утверждение::Для{ключ, индекс, нижняя_граница, верхняя_граница, тело})
|
||||
}
|
||||
ВидЛексемы::КлючВернуть => {
|
||||
let ключ = лекс.вытащить_лексему().unwrap();
|
||||
if лекс.подсмотреть_лексему()?.вид == ВидЛексемы::ТочкаЗапятая {
|
||||
|
||||
@ -4,8 +4,5 @@
|
||||
|
||||
про главная() нч
|
||||
пер а: цел = 0;
|
||||
пока а мн РАЗМЕР нч
|
||||
печать(а, «\н»);
|
||||
а := а + 1;
|
||||
кц
|
||||
для пер а := 1..РАЗМЕР то печать(а-1, «\н»);
|
||||
кц
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
вкл прелюдия;
|
||||
|
||||
конст ЛИМИТ = 100;
|
||||
|
||||
про главная() нч
|
||||
// // СДЕЛАТЬ: цикл «для»
|
||||
// для счет := 1..ЛИМИТ нч
|
||||
пер счет: цел = 1;
|
||||
пока счет мн ЛИМИТ + 1 нч // СДЕЛАТЬ: ввести операцию мнрв
|
||||
// СДЕЛАТЬ: объявление индексной переменной прямо в цикле
|
||||
// для пер счет := 1..100 нч
|
||||
пер счет: цел;
|
||||
для счет := 1..100 нч
|
||||
если счет % 15 == 0 то печать(«ФиззБазз\н»);
|
||||
// СДЕЛАТЬ: подумать как сократить конструкцию «иначе то если»
|
||||
иначе то если счет % 3 == 0 то печать(«Физз\н»);
|
||||
иначе то если счет % 5 == 0 то печать(«Базз\н»);
|
||||
иначе то печать(счет, «\н»);
|
||||
счет := счет + 1;
|
||||
кц
|
||||
кц
|
||||
|
||||
@ -24,13 +24,12 @@
|
||||
про главная() нч
|
||||
установить_случайное_семя(69);
|
||||
|
||||
пер индекс: цел = 0;
|
||||
пока индекс мн ОБЪЁМ нч
|
||||
пер индекс: цел;
|
||||
для индекс := 0..ОБЪЁМ-1 нч
|
||||
позиции(индекс).икс := случайное_вещественное()*50.0;
|
||||
позиции(индекс).игрек := случайное_вещественное()*10.0;
|
||||
дельты(индекс).икс := случайное_вещественное()*400.0;
|
||||
дельты(индекс).игрек := случайное_вещественное()*200.0;
|
||||
индекс := индекс + 1;
|
||||
кц
|
||||
|
||||
открыть_окно(800, 600, адрес(«Привет, Raylib!»));
|
||||
@ -45,8 +44,7 @@
|
||||
|
||||
начать_рисовать();
|
||||
очистить_фон(ЦВЕТ_ФОНА);
|
||||
индекс := 0;
|
||||
пока индекс мн ОБЪЁМ нч
|
||||
для индекс := 0..ОБЪЁМ-1 нч
|
||||
если не пауза нч
|
||||
пер новая_позиция: Вектор2;
|
||||
новая_позиция.икс := позиции(индекс).икс + дельты(индекс).икс*дельта_времени;
|
||||
@ -64,7 +62,6 @@
|
||||
позиции(индекс).игрек как цел,
|
||||
ШИРИНА, ВЫСОТА, ЦВЕТ_КРАСНЫЙ);
|
||||
|
||||
индекс := индекс + 1;
|
||||
кц
|
||||
закончить_рисовать();
|
||||
кц
|
||||
|
||||
@ -5,10 +5,7 @@
|
||||
|
||||
про отступ(ширина: цел) нч
|
||||
пер индекс: цел = 0;
|
||||
пока индекс мн ширина нч
|
||||
печать(« »);
|
||||
индекс := индекс + 1;
|
||||
кц
|
||||
для индекс := 1..ширина то печать(« »);
|
||||
кц
|
||||
|
||||
про дерево(глубина: цел) нч
|
||||
|
||||
Loading…
Reference in New Issue
Block a user