====== Эмулятор Эль76-Эльбрус (версия 1.0b) ====== //Copyright © ВК№2 Сергей Стрелков, Александр Страшнов, Александр Ковернинский, Алексей Бояршинов// (Ссылки: {{http://web.archive.org/web/20030710092032/www.mstu.ru/studies/Others/War/IlbrusLanguage-emul.rar}}, {{http://web.archive.org/web/20030710091904/www.mstu.ru/studies/Others/War/IlbrusLanguage-docs.rar}}) Эмулятор L76 предназначен для создания и выполнения программ на языке Эль76 Эльбрус под управление операционной системы Windows 95/NT. Эмулятор включается в себя компилятор, поддерживающий некоторое подмножество языка Эль76 (смотри раздел [[#Алфавит]]), виртуальную машину Эль76, отладчик программ и редактор с подсветкой синтаксиса. ===== Алфавит ===== Конструкции языка представляются с помощью набора базовых символов. В этот набор входят: * русские и латинские буквы верхнего регистра * цифры от 0 до 9 * специальные символы [ . < ( + @ ] $ * ) & ; : ' # / | > , % ! "- = _ ^ * пробел. В эмуляторе применяется кодировка Windows 1251. ===== Лексемы ===== Лексический элемент языка - это <[[#Идентификатор|идентификатор]]>, <[[#Число|число]]>, <[[#Поэлементное представление|поэлементное представление]]>, подчеркнутый идентификатор или [[#Разделители|разделитель]]. Лексические элементы строятся из <букв>, <цифр>, <двоичных цифр>, <восьмеричных цифр>, <шестнадцатеричных цифр> и <литер>. > <буква> ::== А | В | С | D | Е | F | G | Н | I | J | К | L | M | N | O | P | R | S | T | U | V | W | X | Q | Y | Z | Ю | Б | Ц | Д | Ф | Г | Й | Л | Я | Ч | Ж | Ы | З | Ш | Щ | Э | Ъ | У > <цифра> ::== 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 > <двоичная цифра> ::== 0 | 1 > <восьмеричная цифра> ::== 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 > <шестнадцатеричная цифра> ::== 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | А | В | С | D | Е | F > <литера>::== <буква> | <цифра> | <вертикальная черта> | <кавычка> | [ | . | < | ( | + | @ | ^ | ] | $ | * | ) | ; | : | ‘ | # | / | , | % | > | ! | _ | & | = | - | <пробел> ===== Идентификатор ===== Идентификаторы используются для обозначения переменных и констант, вводимых с помощью описаний. > <идентификатор> ::== <[[#Буква|буква]]> {<буква или цифра>} ... > <буква или цифра> ::== <[[#Буква|буква]]> | <[[#Цифра|цифра]]> ===== Число ===== Числа <Целое> и <вещественное> - это десятичные числа в их обычном понимании. <Порядок> представляет собой степень числа 10. > <целое> ::== <цифра>... > <вещественное> ::== <целое>.<целое>{<порядок>} | <целое><порядок> > <порядок> ::== е{<знак>}<целое> > <знак> ::== + | - ===== Поэлементное представление ===== Поэлементное представление используется для обозначения строк, наборов и для обозначения чисел во внутреннем представлении. > <поэлементное представление> ::== 1"<двоичная цифра>..." | 3"<восьмеричная цифра>..." | 4"<шестнадцатеричная цифра>..." | 8"<литера>..." <Поэлементное представление> задает смежную последовательность двоичных, восьмеричных, шестнадцатеричных и байтовых элементов. Цифра, предшествующая первой кавычке определяет размер элемента в разрядах и способ кодировки. Длина последовательности (в разрядах) равна произведению размера элемента на количество элементов. ===== Формат ===== > <формат> ::== <простой формат> | <строчный формат> > <простой формат> ::== **ф32** | **ф64** | **ф128** > <строчный формат> ::== **ф1** | **ф4** | **ф8** В данной версии поддерживается только **ф32** формат. ===== Разделители ===== Разделители - это специальные символы и следующие слитные сочетания: := <:= <= > ** :=: +: -: /: *: ^: >= <= <> >/ =/ <=/ =/ <>/ // && % * ===== Комментарии ===== Комментарий может быть коротким и длинным. Короткий комментарий начинается с символом % и заканчивается концом той строки, на которой он начался. Непосредственно за символом % не может следовать символ *. Длинный комментарий - это последовательность символов, которая начинается и заканчивается ограничителем длинного комментария. Таким ограничителем является пара символов %*. Длинный комментарий может занимать несколько строк. ===== Описание ===== <Описание> вводит переменную или константу и связывает с ней идентификатор. Диапазон текста программы, внутри которого эта связь существует, называется областью действия описания. В программе может быть несколько описаний с одним и тем же идентификатором. 3а счет текстуальной вложенности конструкций области действия подобных описаний могут перекрываться. Тогда идентификатор в данной точке текста программы понимается в том смысле, который ему придан в минимальной охватывающей эту точку области действия. Контекстом идентификаторов для данной точки текста программы называется множество идентификаторов, описание которых действует в этой точке. С помощью <описаний> вводятся простые переменные и следующие константы: простые константы, статические ситуации, пропедуры-константы, базы участков базированных областей памяти, метки предложений, описатели полей и текстовые макросы. <Описание> может встречаться в составе последовательности описаний в начале <закрытого предложения> или <последовательного предложения>. Кроме того, существуют специфические описания, являющиеся составной частью связанных с ними конструкций. К ним относятся описание формальных в заголовков процедуры, описания статических ситуаций в заголовке структурного предложения и описание параметра цикла в заголовке цикла. Область действия описаний указывается в последующих разделах при изложении семантики этих конструкций. Общие для всех случаев ограничения состоят в следующем: * внутри одной и той же цепочки описаний один и тот же идентификатор не может быть описан дважды; * описание идентификатора должно предшествовать его использованию. > <описание> ::== > <описание простых переменных> | > <описание простых констант> | > <[[#Описание процедур|описание процедур-констант]]> | > <[[#Метки|описание меток]]> ===== Простые константы ===== <Описание простых констант> вводит константу, значением которой является значение <выражения>, находящегося в правой части <идентификации константы>. Одно описание может вводить несколько констант. > <описание простых констант> ::== **конст** <список идентификации констант> > <идентификация константы> ::== <идентификатор> = <выражение> Если в правой части <идентификация константы> находится выражение статического класса, то вновь созданная константа является константой статического класса. В правой части <идентификации константы> нельзя рекурcивно использовать <идентификатор> левой части. ===== Простые переменные ===== <Описание простых переменных> вводит одну или несколько переменных одинакового <простого формата> и связывает с ними <[[#Идентификатор|идентификаторы]]>. > <описание простых переменных> ::== <простой формат><список идентификации переменных> > <идентификация переменной> ::== <[[#Идентификатор|идентификатор]]> {:= <выражение>} > <[[#Идентификатор|идентификатор]]> = <[[#Идентификатор|идентификатор]]> <Идентификация переменной> может содержать <выражение>, значение которого задаёт начальное значение переменной. В этом <выражении> нельзя использовать <идентификатор> из левой части <идентификации переменной>. (По умолчанию переменная формата **ф32** или **ф64** инициализируется пустым объектом соответствующего формата, а переменная формата **ф128** - пустым объектом формата **ф64**). В области действия описания переменная обозначается <[[#Идентификатор|идентификатором]]>, связанным с нею при описании. ===== Массив ===== Массив создается с помощью <генератора массива>. <Генератор в маcсива> предназначен для создания многомерного в-массим, а <генератор с-вектора>-для создания с-веитора. > <генератор массива> ::== <генератор в-массива> | <генератор с-вектора> > <генератор в-массива> ::== <локализация>[<список выражений>]<формат> > <генератор с-вектора> ::== <локализация> **вект** [<выражение> {: <выражение>}] <формат> > <локализация> ::== **лок** | **глоб** В-массив состоит из элементов заданного <формата>. Размерность массива равна числу <выражений> в скобках. Индекс по р-му измерению может заключаться в пределах от 0 до Kр-1, где Kр - значение р-го <выражения> (Kр - целое неотрицательное число). Значением генератора является указатель паспорта созданного массива. Например, в результате выполнения генератора || **лок** [10,10] **ф64** || создается матрица размером 10x10 элементов формата **ф64**. Если генератор массива использовать в правой части описания константы, например || **конст** с = лок [10,10] **ф64**; || то образуется описание, эквивалентное традиционному описанию массива. С-вектор состоит из к элементов заданного формата, где к - значение первого <выражения>. Значением генератора является указатель, описывающий созданный вектор. Локализация. Компонента <локализация> определяет время жизни созданного массива: **лок** означает, что массив является локальным, а **глоб**-глобальным. ===== Замкнутое предложение ===== <Замкнутое предложение> представляет собой простейший способ структурирования описаний и предложений. Оно используется в основном для организации блоков с локальными описаниями (в частности для оформления тела процедуры), а также для изменения порядка вычислений в <формулах>. <Замкнутое предложение> представляет собой <последовательное предложение>, заключенное в скобках: ( и ), или **начало** и **конец**. > <замкнутое предложение> ::== (<последовательное предложение>) | **начало** <последовательное предложение> **конец** Пример. Блок с описанием. начало ф128 с := вещ128 0; для i до вг цикл c := c + в128 f(i)**2; повторить конец ===== Условное предложение ===== Условное предложение позволяет из нескольких альтернатив выбрать и выполнить ту, для которой <условие> принимает значение истина. > <условное предложение> ::== **если** <выражение> **то** <последовательный оператор>  > {**инес** <выражение> **то** <последовательный оператор>}...  > {**иначе** <последовательный оператор>}  > **все** При выполнении <условного предложения> последовательно выполняются <условия> до первого, <выражение> которого принимает значение **истина**. Затем выполняется соответствующее <последовательное предложение>. Если такого <условия> не нашлось, по <условное предложение> содержит альтернативу **иначе**, то выполняется <последовательное предложение> из этой альтернативы. Если же ни одно <условие> не выполнилось и нет альтернативы **иначе**, то ни одно <последовательное предложение> не выполняется. <Условное выражение> и <условная переменная> с необходимостью должны содержать альтернативу **иначе**. ===== Выбирающее предложение ===== <Выбирающее предложение> позволяет выбрать одну из пронумерованных альтернатив и выполнять ее. Номер выполняемой альтернативы вычисляется в заголовке <выбирающего предложения>. > <выбирающий оператор> ::== **выбор** <выражение> **из** > {{<выражение>:,}... <выражение>: <последовательный оператор>,}... > {<выражение>:,}... <выражение>: <последовательный оператор>  > **иначе** <последовательный оператор>  > **всевыб** Альтернативы <выбирающего предложения> нумеруются либо в явной форме, либо неявно. В первом случае <выбирающее предложение> строятся из <размеченных альтернативных предложений>. Каждой альтернативе можно приписать один или несколько <номеров>. <Номер>–это выражение статического класса, значением которого может быть целое или набор. Во втором случае номер в явном виде отсутствует, и считается, что альтернативы пронумерованы от 0 до n–1, где n– число альтернатив. Выполнение <выбирающего предложения> происходит следующим образом. Выполняется <вычисление номера>. Значение <выражения> определяет номер альтернативы, которую следует выполнить. Если такая альтернатива существует, то выполняется ее <последовательное предложение>. Если же такой альтернативы нет, но есть альтернатива **иначе**, то выполняется последовательное предложение из альтернативы иначе. В противном случае ни одно <последовательное предложение> не выполняется. <Выбирающее выражение> и <выбирающее переменную> обязательно должны содержать альтернативу **иначе**. Примеры. выбор день из  1:, 3:, 7: печать(стр8”дневная смена”) 2:, 4: печать(стр8”вечерняя смена”) 5:, 6: печать(стр8”выходной день”) иначе печать(стр8”неверно задан день”) всевыб ===== Цикл ===== Конструкция <цикл> предназначена для организации повторяющегося процесса выполнения ее <операторов>. > <цикл> ::== {**для** <идентификатор> {**от** <выражение>} {**до** <выражение> | **вниздо** <выражение>}} **цикл** <последовательный оператор>  > **повторить** Повторяющееся выполнение <операторов> цикла без заголовка может быть прекращено с помощью <структурного перехода>, пересекающего границы цикла (и, кроме того. с помощью обычного перехода на метку). Цикл с заголовком определяет, что <операторы> выполняются столько раз. сколько задано в <заголовке цикла>. > <заголовок цикла>::== **для** <идентификатор> {**от** <выражение>} {<компонента-до>}  > | **от** <выражение> {<компонента-до>} ><компонента до> ::== **до** <выражение> | **вниздо** <выражение> В <заголовке цикла> задается <идентификатор> параметра цикла. Появление этого идентификатора в заголовке одновременно является и его описанием в пределах данного <цикла>. Начальное значение параметра цикла задается <выражением> в компоненте **от**, а конечное значение -- выражением в <компоненте-до>. Ограничитель <компоненты-до> задает направление изменения параметра цикла: на каждой итерации его значение увеличивается на 1 в случае ограничителя **до** и уменьшается на 1 в случае ограничителя **вниздо**. Семантика выполнения цикла с заголовком отображается следующей программой: ... установить начальное значение i... до кц цикл если (i–u)*s > 0 то кц! все; ... выполнить операторы цикла ... ... увеличить (уменьшить) i на 1 ...  повторить где i – параметр цикла (начальное значение задается в заголовке), u–конечное значение параметра цикла, s = 1 для цикла по возрастанию значения параметра и s=–1 для цикла по убыванию значения параметра. Начальное и конечное значение параметра цикла вычисляется один раз при входе в цикл. Значения <выражений> должны быть целыми числами. В. <выражениях> <заголовка цикла> нельзя использовать <идентификатор> параметра того же цикла. Если компонента **от** и/или <компонента-до> опущены, то начальное и/или конечное значение выбираются по умолчанию. Умолчание для .начального значения –0, а для конечного значения –220–1. Параметр цикла на каждой итерации рассматривается как константа. Его значение нельзя изменять с помощью присваивания. его нельзя использовать в качестве параметра, передаваемого именем, и в качестве объекта при формировании указателя. Идентификатор параметра цикла действует только внутри цикла. Однако, если выполнение цикла прекращается <структурным переходом>, то текущее значение параметра можно передать в качестве фактического параметра реакции. Пример. Найти значение x в векторе а[0;n+1] начало а[n] :-= x; ix := до найден для i до n цикл если а[i] = x то найден!(i) все  повторить при найден(k): если k = n то -1! иначе k все  всесит конец Компоненту для можно опускать в том случае, если в <операторах> цикла параметр цикла не используется. <Описания> из тела <цикла> выполняются один раз при входе в цикл. Областью действия каждого такого описания является вся последующая часть <цикла>, вплоть до закрывающего ограничителя поморить. Пример. Умножение матриц а и b размера nxn. для i до n-1 цикл ф128 cij; для j до n-1 цикл cij := 0; для k до n-1 цикл сij := сij + а [i,k] умнд b[k,j] повторить с[i,j]:= вещб4окр сij % округление результата  повторить  повторить ===== Структурное предложение ===== > <структурный оператор> ::== **до **<[[#Идентификатор|идентификатор]]> {,<идентификатор>} <закрытое предложение> ===== Описание процедур ===== > <описание процедур-констант> ::== **процедура**  <идентификатор> { = <текст процедуры>} {,  > <идентификатор> { = <текст процедуры>}}... > <текст процедуры> ::== **проц** ({**ф32** | **ф64** | **ф128**** **<идентификатор>{,<идентификатор>}...;} **ф32** | **ф64**  > | **ф128**** **<идентификатор>{,<идентификатор>}...) <закрытый оператор> | **функция** ({**ф32** | **ф64** | **ф128**** **<идентификатор>{,<идентификатор>}...;} **ф32** | **ф64** | **ф128**** **<идентификатор>{,<идентификатор>}...) <закрытое выражение> ===== Метки ===== > <описание меток> ::== **метка** <идентификатор> {, <идентификатор>}... ===== Переход ===== > <переход> ::== **на **<идентификатор> ===== Ситуации ===== > <описание статических ситуаций> ::== **статсит** <идентификатор> {, <идентификатор>}... ===== Преобразование типов ===== В данной версии поддерживаются следующие операции преобразования типов: * **целокр** - в целое с округлением  * **целобр** - в целое с обрубанием  * **вещокр** - в вещественное с округлением  * **вещобр** - в вещественное с обрубанием  ===== Генерация случайных чисел ===== Функция //случ()// возвращает случайные числа равномерно распределенные в интервале от 0 до 1 числа. Пример. ф32 ы := случ(); ===== Вывод в окно терминала ===== Для вывода информации в окно терминала используются три встроенные функции. Функция //печать(...)// осуществляет вывод числа. //Пример.// ф32 ы; ы := 12345; печать(ы) Функция //печатьмс(...)//  осуществляет вывод массива символов. //Пример.// ф32 ы; ы := стр8 8"абракадабра"; печатьмс(ы) Функция печатькс() переводит курсор терминала на новую сроку. ===== Ввод из окна терминала ===== Для ввода информации из окна терминала используются две встроенные функции. Функция //ввод()// осуществляет ввод с клавиатуры числа. //Пример.// ф32 ы; ы := ввод(); печать(ы) Функция //вводмс()// осуществляет ввод с клавиатуры массива символов. //Пример.// ф32 ы; ы := вводмс(); печатьмс(ы) ===== Математические функции ===== В данной версии поддерживаются следующие встроенные математические функции: * //синус//(**ф32** x) — синус х * //косинус//(**ф32** x) — косинус х * //тангенс//(**ф32** x) — тангенс х * //котангенс//(**ф32** x) — котангенс х * //арксинус//(**ф32** x) — арксинус х * //арккосинус//(**ф32** x) — арккосинус х * //арктангенс//(**ф32** x) — арктангенс х * //арккотангенс//(**ф32** x) — арккотангенс х * //арктангенс2//(**ф32** x) — арккотангенс2 х Аргумент тригонометрических функций задается в радианах. * //логарифм//(**ф32** x) — натуральный логарифм х * //экспонента//(**ф32** x) — е в степени х