# [3.3.1] — 2021-04-08
## Исправлена ошибка сборки на MinGW64

* Не подумав, удалил небольшой, но важный параметр для сборки в окружении GitHub
  Actions. Из-за этого сборка в GitHub Actions валилась.
* Исправлена ошибка в скрипте компиляции библиотек `src\lib\make.bat`,
  из-за которой дистрибутив для UNIX-like создавался с ошибками.


# [3.3] — 2021-04-07
## `NEWS.md`, пошаговый отладчик, `-Wrepeated`, `e.X$a`, `-Wdeprecated`

### Файл `NEWS.md`

В репозиторий добавлен файл `NEWS.md` (который вы сейчас читаете), в нём будут
описываться новшества каждой следующей версии. Файл сформирован основе сообщений
коммитов в репозитории [simple-refal-distrib.git][simple-refal-distrib].
Последние три года коммиты в нём создавались при выпуске новой версии, описания
фиксаций включали в себя новшества разной степени детализации. Ранние коммиты
прокомментированы скупо, более поздние — подробно.

Файл был создан полуавтоматически — сформирована заготовка при помощи `git log`
с хитро заданным форматом, результат был вручную отформатирован в разметке
`Markdown`.

Для некоторых ранних версий (особенно, представленных несколькими
последовательными коммитами в репозитории дистрибутива) было написано новое
описание вручную.

Возможно, в дальнейшем ранние версии будут прокомментированы подробнее.

### Пошаговый отладчик

[Станислав Санталов][Santalov] в рамках курсовой работы по «Конструированию
компиляторов» расширил возможности встроенного пошагового отладчика. Работа
велась в рамках задачи [#85](https://github.com/bmstu-iu9/refal-5-lambda/issues/85),
в которой требовалось добавить режимы вывода фрагментов поля зрения
и несколько новых команд.

* Вывод всего поля зрения по команде `print viewfield`.
* Команда `backtrace`, распечатывающая трассировку стека вызовов в виде
  ```
  @0  ^0   <H ...>
  @1       <I ...>
  @2  ^1   <G ...>
  @3       <J ...>
  @4  ^2   <F ...>
  ```
  для выражения
  ```
  <F <G <H> <I>> <J>>
  ```
  Ссылки `@n` позволяют ссылаться на n-ю функцию в очереди вызовов, `^n` —
  на n-й окружающий вызов. Эти ссылки можно использовать в командах `print`,
  `breakpoint`, `next`.
* Команда `next` принимает необязательный аргумент — имя функции, на которой
  нужно остановиться, т.е. фактически является точкой останова с автосбросом.
  Аргумент по умолчанию — `@1`, т.е. следующий вызов.
* Можно задавать режимы отображения вида
  ```
  <режим>
  ```
  или
  ```
  <режим>... : команда
  ```
  Режимом может быть
  - `oneline` — вывод выражения в одну строчку,
  - `multiline` — вывод выражения в несколько строк с отступами,
  - `full` — вывод выражения целиком,
  - `skeleton` — вывод только угловых скобок и имён вызываемых функций.

  Первый синтаксис устанавливает режим глобально, второй — только на время
  выполнения конкретной команды.

  Просмотреть режимы можно при помощи команды `mode`.
* Имена файлов для трассировки можно задавать в кавычках.
* Команда `list` выводит список точек останова и трассировок.
  В списке трассировок выводятся имена файлов.
* Для повторения предыдущей команды используется пустая строка (как в GDB).
  Ранее использовалась команда «точка» (`.`).

Отладчик может работать в неинтерактивном режиме — скрипт с командами может
задаваться в `@refal-5-lambda-diagnostics.ini` в параметре `debugger-script`.

### Предупреждение `-Wrepeated` на подозрительные повторные переменные

Лев Бакланов aka [@penachett][penachett] в рамках курсовой работы реализовал
выдачу предупреждений на подозрительные повторные переменные.

Рефал-5λ позволяет переопределять переменные — использовать одно и то же имя
переменной в предложении несколько раз для различных значений. В Рефале-5,
если некоторая переменная в области видимости связана, то в последующих
образцах (условиях и блоках) переменные с этим именем будут считаться
повторными. Рефал-5λ позволяет использовать одно и то же имя переменной для
разных значений, записывая после него знак `^`. Такой приём бывает полезен,
если речь идёт об одной и той же сущности, которая меняется в разные моменты
времени (например, пополняется некоторая внутренняя таблица).

Распространённой ошибкой является пропуск знака `^`, из-за чего переменная
становится повторной. Если повезёт, и новое вхождение переменной совпадёт
со старым, то это приведёт лишь к потере производительности на копирование
исхдоного значения и сравнения на равенство нового значения с ним. (Такое
бывает при оптимизации вроде замены `Map`, у которой замыкание захватывает
контекст, на `MapAccum`, неизменный контекст которой хранится в аккумуляторе.)
Если не повезёт — то будет логическая ошибка.

Добавленное предупреждение выявляет многие случаи, когда знак `^` пропущен
пользователем по ошибке (однако, случаются и ложные срабатывания).

### В промежуточном языке у переменных нет «глубины»

Компилятор преобразует программу в несколько проходов. Один из них называется
«рассахариванием» — переводом программы из более богатого входного языка
в более ограниченный промежуточный, т.к. большинство конструкций Рефала-5λ
являются синтаксическим сахаром. Промежуточный язык можно видеть в логе
компилятора (опция `--log=logfile.log`), переменные с именами из промежуточного
языка можно видеть внутри замыканий при включённой опции `--markup-context`.

Во входном языке благодаря сокрытию переменных (которому посвящено предыдущее
предупреждение) две переменные могут иметь разные значения. В промежуточном
языке сокрытия нет. Такая возможность обеспечивается путём переименования
переменных таким образом, чтобы исходная и сокрывающие переменные получали
различные имена.

Ранее переименование осуществлялось путём указания «глубины» переменных.
Глубина — натуральное число, которое для первого образца предложения равно `1`,
инкрементируется для каждого следующего образца на единицу. В логе и внутри
замыканий (в режиме `--markup-context`) глубина отделяется от индекса
переменной знаком `#`: `e.X#1`.

Вот так выглядело переименование переменных ранее:

    Eq {                       →          Eq {
      (e.X) (e.Y)              →            (e.X#1) (e.Y#1)
        = e.Y                  →              = e.Y#1
        : {                    →              : {
            e.X = True;        →                  e.X#1 = True;
            e.X^ = False;      →                  e.X#2 = False;
          }                    →                }
    }                          →          }

Из-за этих `…#n` лог читать было сложно, они были визуальным мусором.
К тому же усложнялась структура синтаксического дерева, и её описание.

Теперь правило изменилось. Первое вхождение переменной с некоторым именем
не имеет никакого суффикса. Первое сокрытие при помощи знака `^` даёт суффикс
`…$a`, второе — `…$b`, …, девятое — `…$i`. Десятое — `…$ao`, таким образом
десятичные цифры номера `1…90` отображаются в буквы `a…io`.

Отображение не в цифры, а в буквы связано с тем, что механизм переименования
переменных, используемый в древесных оптимизациях, добавляет переменным
целочисленные суффиксы, или, если переменная на такой суффикс заканчивалась,
то суффикс инкрементируется. При чтении лога возникло бы недопонимание, если бы
изменялся бы уровень сокрытия переменной.

Теперь преобразование выглядит так:

    Eq {                       →          Eq {
      (e.X) (e.Y)              →            (e.X) (e.Y)
        = e.Y                  →              = e.Y
        : {                    →              : {
            e.X = True;        →                  e.X = True;
            e.X^ = False;      →                  e.X$a = False;
          }                    →                }
    }                          →          }

### Предупреждение `-Wdeprecated` на устаревшие синтаксические конструкции

Синтаксические конструкции, которые будут удалены в будущих релизах,
вызывают предупржедение типа `-Wdeprecated`.

### **Deprecated**

* Знаки `^` после переменных, которые ничего не скрывают (т.е. новых
  переменных), в следующей версии станут синтаксическими ошибками.
* Ключевое слово `$SCOPEID` в следующей версии будет удалено.


### Прочее

* **ИСПРАВЛЕНО:** сборка на MinGW как на POSIX не работала, т.к. на MinGW
  отсутствует библиотека `libdl.a`, а в командной строке компилятора
  указывался флаг `-ldl`. Теперь для MinGW этот флаг не указывается.
* Поддержка сборки на MinGW64.
* Все скрипты сборки (`bootstrap.*`, `src/make.*` и др.) возвращают ненулевой
  код возврата при неудаче сборки.
* К хранилищу кода подключена система непрерывной интеграции GitHub Actions.
  В системе проверяется корректность сборки скриптами `bootstrap.*` на ОС
  Windows, Linux и macOS с использованием компиляторов GCC, MSVC и Clang
  (где какие доступны).
* Тесты на случайных файлах распечатывают исходный случайный файл на `stdout`
  в случае ошибки — так сделано для отладки ошибок, обнаруженных в среде
  непрерывной интеграции.


# [3.2] — 2020-12-10
## Оптимизации, статический анализ, `rlgo`, `__INIT` и `__FINAL`, deprecated

В данной версии, прежде всего, существенно расширились возможности древесной
оптимизации. Метки `$SPEC` и `$DRIVE` стали безопасными, появилась возможность
оптимизировать все функции, которые оптимизировать возможно (т.е. метки
`$SPEC` и `$DRIVE` теперь могут назначаться автоматически), компилятор может
статически вычислять некоторые встроенные функции.

Также появился инструмент статического анализа — обнаружение экранируемых
предложений. На такие предложения выводится предупреждение.

Были и другие изменения, о которых ниже.

Некоторые средства компилятора устарели, составлен список нерекомендуемых
(deprecated) средств.

### `__INIT` и `__FINAL`

**ВАЖНО! Нарушилась обратная совместимость!**

Новая версия компилятора считает функциями инициализации и финализации
не `INIT` и `FINAL`, а `__INIT` и `__FINAL`. При этом, функции `__INIT`
и `__FINAL` должны быть локальными — их определение как `$ENTRY` является
ошибкой синтаксиса.

Режим `-OA` — оптимизация всех функций
--------------------------------------

Режим `-OA` — оптимизация всех (all) функций, вызовы которых можно
оптимизировать. Если функция может прогоняться, её вызовы будут прогоняться,
если функция может специализироваться, её вызовы будут специализироваться.

Для достижения этой цели синтаксическое дерево сканируется и выявляются
функции, которым можно поставить метки `$DRIVE` и `$SPEC`. Расстановка меток
`$INLINE` не поддерживается, т.к. статически выявлять такие функции слишком
сложно.

Кроме того, в данном режиме выполняется постобработка дерева после выполнения
древесных оптимизаций. Дело в том, что после выполнения циклов прогонки
и специализации в дереве могут появиться экземпляры специализированных функций,
которые можно успешно прогнать в точки вызова.

Компонент разметки функций разработан совместно Еленой Калининой aka
[@Kaelena][Kaelena] и Александром Коноваловым aka [@Mazdaywik][Mazdaywik].

### Более безопасная специализация

Теперь пометка функции как `$SPEC` не может привести к бесконечному циклу
построения новых экземпляров. История построения экземпляров отслеживается,
и если в истории обнаружилась сигнатура, похожая на предыдущую, строится
экземпляр не для новой сигнатуры, а для сигнатуры, полученной как ГСО старой
и новой.

Сходство двух сигнатур определяется так: если в новой сигнатуре можно стереть
какие-либо элементы (символы, параметры, пары скобок), что получится предыдущая
без учёта имён параметров, то значит новая похожа на эту предыдущую.
В математике этот критерий называется отношением Хигмана-Крускала и для него
доказывается, что он является хорошим предпорядком. Т.е. для любой бесконечной
цепочки сигнатур рано или поздно найдётся такая, что будет похожа на предыдущую.

Поскольку отношение похожести прерывает любые бесконечные цепочки, а число
возможных обобщений в виде жётского выражения (что вычисляет ГСО) для любого
выражения конечно, любая бесконечная цепочка экземпляров рано или поздно
прервётся. Таким образом, процесс специализации теоретически конечен.

На практике это означает, что большинстве случаев назначение метки `$SPEC`
не приводит к проблемам при компиляции. Это используется, в частности,
в рассмотренном режиме `-OA`, который назначает метки `$SPEC` всем функциям,
для которых можно построить шаблон с как минимум одной статической переменной.

Однако, 100%-но безопасной специализацию назвать нельзя. Иногда до обнаружения
похожей сигнатуры может потребоваться много проходов оптимизатора (например,
для взаимно-рекурсивных функций) и при этом на каждом проходе создаётся
по несколько новых экземпляров. В таких случаях компилятор может надолго
задуматься и съесть всю доступную память, прежде чем будет достигнуто
теоретическое прерывание цикла.

Для борьбы с подобными ситуациями проблемным функцим можно вручную назначить
сигнатуру с одними только динамическими параметрами, либо воспользоваться
псевдофункцией `gen_e__` (см. далее).

Прерывание зацикливания специализации совместно разработано Андреем Кошелевым
aka [@koshelevandrey][koshelevandrey] и Александром Коноваловым aka
[@Mazdaywik][Mazdaywik].

### Встроенные функции могут вычисляться на стадии компиляции (`-Oi`)

Некоторые из встроенных функций теперь считаются «интринсиками» — функциями,
вызовы которых компилятор распознаёт и может оптимизировать статически.

К ним относятся все функции арифметики, функции работы со строками (`First`,
`Last`, `Lenw`), функции преобразования типов, функции `Type` и `Mu`. Вызовы
этих функций оптимизируются, если на стадии компиляции информации достаточно,
чтобы их вызов правильно преобразовать. Так, например, функции `Type` достаточно
знать первый терм своего аргумента (он не должен быть переменной или вызовом
функции).

Оптимизация интринсиков включается опцией `-Oi`. Для того, чтобы компилятор
начал распознавать некоторую функцию как интринсик, она должна быть объявлена
при помощи директивы `$INTRINSIC`:

    $INTRINSIC Add, Mu, Type;

Оптимизация интринсиков совместно разработана Ханагой Агазаде aka
[@CStyler][CStyler] и Александром Коноваловым aka [@Mazdaywik][Mazdaywik].

### Распознавание экранируемых предложений (`-Wscreening`)

В компилятор был добавлен первый серьёзный инструмент статического анализа кода
для поиска в нём дефектов.

При использовании опции `-Wscreening` компилятор распознаёт случаи экранирования
предложений и выдаёт на них предупреждения. Предложение называется экранируемым,
если множество значений, описываемым его левой частью, является подмножеством
множества, описываемого левой частью одного из предшествующих образцов.

При распознавании экранирования используются два подхода:

* Использование алгоритма совместного сопоставления с образцом — образец
  «нижнего» предложения сопоставляется с «верхним» без сужений.
* Использование подхода, основанного на языках образцов.

Каждый из этих подходов может распознавать случаи экранирования, недоступные
другому подходу, поэтому используются они оба.

При тестировании алгоритм верно выявил экранирования в исходных текстах самого
компилятора, суперкомпиляторов SCP4 и MSCP-A. Экранирования в исходных текстах
самого компилятора устранены, о случаях экранирования в суперкомпиляторов
сообщено их авторам.

Распознавание экранируемых предложений совместно разработано Александром
Барлукой aka [@nexterot][nexterot], Антониной Непейвода aka [@TonitaN][TonitaN]
и Александром Коноваловым aka [@Mazdaywik][Mazdaywik].

Поддержка предупреждений, появившаяся в прошлой версии, также была разработана
Александром Барлукой aka [@nexterot][nexterot].

### Псевдофункция `gen_e__`

Для управления процессом оптимизации компилятор предоставляет псевдофункцию
`gen_e__`. При помощи этой функции пользователь может динамически помечать
участки результатного выражения, которые с точки зрения специализатора должны
считаться e-переменными (т.е. попадать в сигнатуру как e-переменные).

Функция `gen_e__` не встроенная. Она должна быть определена пользователем как
локальная тождественная функция:

    gen_e__ { e.Arg = e.Arg }

Имя переменной может быть любым. Если её определить иначе (с `$ENTRY` или другим
телом), то она не будет распознана оптимизатором как псевдофункция. В этих
случаях компилятор выдаст предупреждение.

Функцию `gen_e__` можно оборачивать вокруг переменных-аккумуляторов, т.к. именно
с ними в этой версии возникают проблемы с избыточными специализациями.

В будущих версиях арсенал псевдофункций пополнится.

### Интерпретатор `rlgo`

Интерпретатор позволяет запускать как программы модули динамической загрузки
(`.dll`, `.so`, `.rasl-module`), если те содержат функцию `Go` или `GO`. Синтаксис
командной строки:

    rlgo [опция-диагностики...] имя-модуля [параметры-модуля...]

Здесь опции диагностики это параметры, которые можно установить
в `@refal-5-lambda-diagnostics.ini`, предварённые двумя знаками `--`, например,
`--print-statistics=bool`, `--memory-limit=number` и т.д.

Если имя модуля записано без пути, оно ищетсяв списке `RL_MODULE_PATH`. Поэтому,
чтобы вызовать модуль из текущей папки, нужно обязательно указать путь вида
`./имя-модуля`.

Параметры модуля — это те парамеры, которые модуль увидит посредством встроенной
функции `<Arg s.N>`.

### Нерекомендуемые (deprecated) возможности языка

В будущих версиях языка следующие из этих возможностей могут быть удалены:

• `$SCOPEID`.
• Вставки кода на C++. Вместо них будет предложен удобный FFI для написания
  библиотечных функций на C/C++.
• Текущий API на C++98 будет заменён новым на C89.
• `$LABEL`.
• Ключевые слова `$DRIVE`, `$SPEC`, `$INLINE` — вместо них будут использоваться
  псевдокомментарии.
• `$INCLUDE`.
• Синтаксис вида `$ENTRY Func1, Func2, Func3`;
• Поддержка Простого Рефала.
• LexGen.
• Режим рассахаривания условий, включаемый как `-OC-`.

Не все из перечисленных возможностей будут удалены, по некоторым пунктам
я колеблюсь. Вероятность удаления возможностей убывает к концу списка.

Перечисленные средства будут, скорее всего, удаляться не сразу, процесс
затянется на несколько версий.

### Другие мелкие изменения

* Функции в `LibraryEx` стали использовать `Mu`: библиотека стала совместима
  [refal-5-framework][refal-5-framework].
* Некоторые главы документации были незначительно актуализированы.
* Анастасия Кузнецова aka [@suova][suova] исправила множество грамматических
  ошибок в сообщениях компилятора об ошибках (в основном, пропущенные артикли).
* Незначительно улучшено форматирование дерева в логе.
* Незначительно изменена кодогенерация в режиме `-OP`: размер групп предложений
  не превышает 50.
* После выполнения древесных оптимизаций из программы удаляются функции
  с суффиксами, недоступные прямо или косвенно из функций без суффиксов.
* Метка `$DRIVE` стала безопасной — инструмент разметки меток `$DRIVE` может
  не только добавлять новые, но и удалять имеющиеся пометки. Из-за того, что
  безымянным функциям неявно присваивалась метка `$DRIVE`, предыдущая версия
  компилятора могла зациклиться на некоторых хитрых примерах. Нынешняя
  не зацикливается.
* **ИСПРАВЛЕНО:** теперь при оптимизации `-OG` вызываются функции инициализации
  и финализации.
* LexGen добавляет метки `$SPEC` с динамическими аккумуляторами для подавления
  паразитной специализации по ним (как раз тот случай, когда проверка похожести
  не срабатывает).


# [3.1] — 2020-05-17
## Предупреждения, оптимизации, псевдокомментарии, орфография и мелкие багфиксы

### Предупреждения

Компилятор теперь поддерживает выдачу предупреждений. Синтаксис позаимствован
у GCC:

• `-Wимя` — включает предупреждение с заданным именем,
• `-Wno-имя` — отключает предупреждение с заданным именем,
• `-Wall` — включает все предупреждения,
• `-Werror=имя` — трактует указанное предупреждение как синтаксическую
  ошибку — останавливает компиляцию,
• `-Werror` — трактует все включенные предупреждения как ошибки.

Доступные предупреждения:

• `-Wscreening` — поиск и вывод экранируемых предложений (пока не реализовано),
• `-Winit-final-entry` — выдаёт предупреждение, если функция `INIT` или `FINAL`
  определена как $ENTRY,
• `-Wnul-in-compound` — предупреждает об идентификаторах вида `"abc\x00def"`,
  такие идентификаторы усекаются до первого `\x00` в имени,
• `-Wignored-pseudocomments` — если включен режим совместимости с классическим
  Рефалом-5 (`--classic`), то выдаётся предупреждение на псевдокомментарии,
  что они в этом режиме игнорируются.

Поддержка предупреждений реализована Александром Барлукой ([@nexterot][nexterot]).

Список поддерживаемых предупреждений в будущих версиях будет пополняться.

### Оптимизации:

* Небольшие оптимизации в самом компиляторе, компилятор стал работать немного
  быстрее.
* Вложенные функции (включая также неявно создаваемые функции для присваиваний
  и блоков) теперь не только прогоняются, но и специализируются по переменным
  контекста. Это позволяет передавать информацию о значениях связанных
  переменных, даже если прогонка не удалась.
* В режиме рассахаривания условий (`-OC-`) вспомогательные функции, имитирующие
  семантику условий, также прогоняются и специализируются по переменным
  контекста. Это позволяет оптимизировать программы на классическом Рефале,
  где условия используются в роли присваиваний.
* Глобальная оптимизация — синтаксические деревья отдельных единиц трансляции
  объединяются в одно. Это позволяет определить встраиваемую или прогоняемую
  функцию в одной единице трансляции, и оптимизировать её вызов в другой.
  Включается опцией `-OG`. Имена локальных функций во избежание конфликтов
  получают суффикс `~n`, при компиляции создаётся файл
  `〈имя-программы〉-locals.lst`, содержащий соответствия суффиксов именам единиц
  трансляции.
  Режим глобальной оптимизации сам по себе на быстродействие не влияет. Он лишь
  позволяет объединять единицы трансляции вместе, чтобы режимы `-OD`, `-OI` и `-OS`
  могли оптимизировать вызовы помеченных функций из других единиц трансляции.

### Псевдокомментарии

Компилятор теперь имеет ограниченную поддержку псевдокомментариев. Комментарии
вида

    *$DRIVE GetNodeName, GetNodeType, GetNodeChildren;

    *$INLINE Apply;

    *$SPEC Map t.FUNC e.items;

теперь интерпретируются точно также, как соответствующие объявления без
звёздочки в начале. Это позволяет писать программы, одновременно совместимые
с классическим Рефалом-5, и оптимизируемые Рефалом-5λ.

Синтаксические и семантические ошибки в них в текущей реализации обрабатываются
как обычные синтаксические ошибки — компиляция прерывается. Таким образом,
существуют программы на Рефале-5, трактуемые как некорректные в Рефале-5λ. Если
необходимо обеспечить совместимость с такими программами, следует использовать
ключ `--classic`, в котором все псевдокомментарии игнорируются. Ключ
`-Wignored-pseudocomments` позволяет выводить сообщения о таких комментариях.

### Исправленные ошибки

* Анастасия Кузнецова ([@suova][suova]) исправила огромное количество ошибок
  в переводах документации на английский язык.
* В архивах `*.tar.gz` теперь будут правильно выставляться флаги исполнимости.
* Лексер для Рефала-5 допускал пустые индексы переменных вида e. Исправлено.


# [3.0.1] — 2020-05-05
## Документация, оптимизации, пустые флаги, профилировщик, багфиксы

### Документация

* Написано «Приложение B. Краткий справочник».
* На страницы документации добавлены содержания, исправлены уровни
  заголовков (которые стали заметны благодаря содержаниям).

### Оптимизации

* Незначительно оптимизирована библиотека `Library`: `__Step-Drop` для
  одношаговых обёрток, функции `First`, `Last` и `Lenw` переписаны на Си++.
* Оптимизировано распределение памяти: время копирования повторных
  переменных ускорено примерно в 1,5–2 раза, линейное время построения
  результата — на 8 %.
* Общее ускорение компилятора: использование более быстрой библиотеки,
  оптимизация в лексическом анализаторе. Кумулятивное ускорение
  в обычном режиме (без оптимизаций) составило 16 %¹.
* Ускорение работы компилятора в некоторых режимах:
  - незначительное в режиме `-OD`: 5,5 %;
  - существенное в режиме `-OR`: примерно в 3 раза;
  - существенное в режиме `--log=filename.log`: примерно в 2 раза.

Добавлены пустые флаги: `-OG` (глобальная оптимизация) как задел на будущее,
экспериментальные `-Ox`, `-Oy`, `-Oz`, которые нужны для удобства отладки (их
можно поместить глобально в `RLMAKE_FLAGS` и вызывать `makeself-s.*`).

### Улучшен отчёт профилировщика функций:

* Вывод единиц измерения времени для функций (ms).
* Подсчёт относительной продолжительности шага функции (по отношению
  к продолжительности среднего шага). Величина много больше единицы
  означает, что функция работает медленно — содержит открытые, повторные
  или копируемые переменные, либо это функция ввода-вывода.
* Для функций учитываются их области видимости — одноимённые локальные
  функции считаются раздельно. Теперь если в отчёте видно, что, скажем
  Map@3 выполняется долго, можно понять — из какой она единицы трансляции.

### Исправлены ошибки:

* Не выполнялась прогонка и встраивание в аргументах косвенных вызовов
  функций.
* Мелкая ошибка в режиме `-OS` при специализации функций с условиями.
* Мелкая ошибка анализе флагов оптимизации в командной строке.

### Примечание

¹ Был выполнен стандартный бенчмарк на коммите, помеченном как 3.0
  и на коммите-предке для 3.0.1. Выполнялось 13 проходов с ключами
  `RLC_FLAGS=-OC`, `RLMAKE_FLAGS=`, `BENCH_FLAGS=`.
  Компьютер: Intel® Core™ i5-2430M 2,40 ГГц, ОЗУ 8 Гбайт.
  Операционная система: Windows 10 x64 1909.
  Компилятор C++: Borland C++ Compiler 5.5.1 (2000 года).
  Процент вычислялся для метрики Total program time,
  до оптимизации:
    медиана 27,218 с, доверительный интервал 27,188…27,250 с,
  после оптимизации:
    медиана 22,875 с, доверительный интервал 22,750…23,094 с.
  Прирост 4,3 с или 16,0 % является достоверным.


# [3.0] — 2020-04-16
## Версия 3.0, Рефал-5λ, багфиксы, безымянные переменные, метафункции, -OiA

Наконец-то завершён переход от Простого Рефала к Рефалу-5λ!

Удалены последние артефакты Простого Рефала, можно закрывать
<https://github.com/bmstu-iu9/refal-5-lambda/milestone/6> и устанавливать
номер версии 3.0!

* Удалены устаревшие функции Простого Рефала. Они или дублировали аналогичные
  встроенные функции, или имели неудачное имя, или были не нужны. Список
  удалённых функций:
  - `FOpen` (переименована в `Open-Auto`), `FClose`, `FReadLine`, `FWriteLine`,
  - `FReadBytes` (переименована в `ReadBytes`), `FWriteBytes` (переименована
    в `WriteBytes`),
  - `ReadLine`, `WriteLine`,
  - `IntFromStr`, `FastIntFromStr`, `StrFromInt`,
  - комбинатор неподвижной точки `Y`,
  - `MapReduce`, `Seq` (они были синонимами для `MapAccum` и `Pipe`
    соответственно).
* Удалены устаревшие утилиты командной строки (в скобках указаны новые
  имена):
  - `srefc`, `srefc-core` (`rlc`, `rlc-core`),
  - `srmake`, `srmake-core` (`rlmake`, `rlmake-core`),
  - `lexgen` (`rl-lexgen`),
  - `rsl-decompiler` (`rl-rsl-decompiler`).
* Удалены другие артефакты
  - скрипты `rlc` и `rlmake` не пользуются переменной окружения `%CPPLINE_FLAGS%`,
  - вместо переменных окружения `%SREFC_FLAGS%` и `%SRMAKE_FLAGS%` следует
    использовать `%RLC_FLAGS%` и `%RLMAKE_FLAGS%`,
  - утилита `rlmake` вместо опции `-s`/`--sref-command`/`--srefc-command`
    использует только опцию `--rlc-command`,
  - примеры программ в `doc/examples` переписаны на Рефал-5λ.

### Исправлен ряд ошибок:

* Компилятор падал (или мог порождать неверный код) для специализируемых
  функций с условиями в режиме компиляции `-OCS`. Ранее эта ошибка
  не обнаруживалась, поскольку в «боевом» коде функции с условиями
  не специализировались, а автотесты не проверяли режим `-OCS`.
* Специализатор осуществлял подстановки переменных не параллельно
  (независимо), а последовательно, из-за чего порождал неправильный
  код на некоторых примерах.
* Неправильно определялся случай тривиальной сигнатуры, из-за чего снижалась
  глубина оптимизации.

  Сигнатурой называется подстановка статических параметров для вызова
  специализируемой функции. Тривиальная сигнатура — подстановка-переименовка,
  вызов с тривиальной сигнатурой оптимизировать нет смысла.

  По ошибке считалось, что тривиальная сигнатура — подстановка, просто
  отображающая переменные на переменные. Из-за этого не оптимизировались
  те вызовы, которые, тем не менее, оптмизировать можно.
* Специализатор теперь умеет оптимизировать вызовы с активными аргументами.
  Изначально специализатор мог оптимизировать, но делал это неправильно.
  В качестве временного решения оптимизация таких вызовов была запрещена.
* При ошибке отождествления в экземпляре специализированной функции
  дамп отображается понятнее. Упавший вызов выглядит как вызов функции
  `<Func@0 …>`, аргумент которой совпадает с тем аргументом, который
  был бы у функции `<Func …>` без специализации.
* Если в предложении были и прогоняемые, и специализируемые вызовы,
  глубина оптимизации могла бы быть не полной. Исправлено.

  Исправление этой проблемы потребовало переработки архитектуры древесного
  оптимизатора, из-за чего изменился смысл опции `--opt-tree-cycles=N`.
  Ранее число `N` означало количество проходов оптимизации, каждый из них
  включал проход прогонки и проход специализации. Сейчас проходы прогонки
  и специализации считаются отдельно.
* Повышена производительность древесного оптимизатора. В прогонщике
  найдены ошибочные повторные переменные. После прохода специализации
  оптимизированные функции помечаются как «холодные» и на последующих
  проходах игнорируются.

### Добавлен синтаксис безымянных переменных.

* Безымянная переменная — переменная, индекс которой начинается на `_`:
  `e._`, `t._A`, `s.__` …
* Безымянные переменные допустимы только в образцовых выражениях.
* Каждая такая переменная неявно получает новое уникальное имя, поэтому
  повторными они быть не могут. Например, сопоставление `'ab'` : `s._` `s._`
  всегда успешно.
* Синтаксис `e._x^` (безымянная переменная со знаком сокрытия) запрещён,
  поскольку бессмысленный.

### Изменена реализация метафункций

Теперь компилятор поддерживает ключевое слово `$META`, определяющее
метафункцию. Метафункция, объявленная как `$META Foo;`, неявно вызывает
внешнюю функцию `__Meta_Foo`, передавая ей свой аргумент и таблицу функций
текущей области видимости. Функции `Mu` и `Residue` переписаны через этот
механизм.

Компилятор поддерживает флаги оптимизации `-Oi` (оптимизация
intrinsic-функций) и `-OA` (автоматическая расстановка меток `$DRIVE`, `$INLINE`
и `$SPEC`). На данный момент сами оптимизации не реализованы, ключи добавлены
для возможности раскрутки следующей версии при помощи текущей.


# [2.6] — 2020-04-07
## Интерпретатор, исправления ошибок, мелкие изменения

* Даниил Гавриловский ([@GDVFox][GDVFox]) подготовил плагин для Visual Studio
  Code, инструкция по установке находится в `editors/README.md`.
* Анастасия Кузнецова ([@suova][suova]) исправила огромное количество ошибок
  в переводах документации на английский язык.
* Исправлена ошибка некорректной загрузки модулей, если модуль ссылался
  на себя по псевдониму.
* Скомпилированные библиотеки лежат не в `/bin`, а в `/lib`.
* Путь к папке `/lib` в инсталляторах прописывается в `RL_MODULE_PATH`.
* Программы зависали, если переменная `RL_MODULE_PATH` содержала более одной
  папки.
* В релизных сборках физически отсутствует диагностический код.
  Соответственно, ранее в релизных сборках (без ключа `--debug`) выполнялось
  профилирование (и не только), но результат распечатать было невозможно.
  Теперь лишних действий не выполняется, программы, собранные без диагностики
  примерно на 10 % быстрее программ, собранных с диагностикой.
* Написан интерпретатор, аналог `refgo` классического Рефала-5.
  Интерпретатор называется `rlgo` и может выполнять R- и N-модули, содержащие
  экспортируемую функцию `Go` или `GO` (последняя имеет приоритет).
  Интерфейс командной строки доступен по команде `rlgo --help`.
* Конфигурационный файл диагностики теперь имеет расширение `.ini` вместо `.txt`
  (`@refal-5-lambda-diagnostics.ini`, `progname@refal-5-lambda-diagnostics.ini`).
* Незначительные изменения парсера этого конфигурационного файла.
* Для параметров `idents_limit` и `memory_limit` значение `0` означает отсутствие
  ограничений (аналогичный смысл давно уже был у `step_limit`
  и `start_step_trace`).
* Незначительные изменения диагностического кода: генерируются макросы
  `COOKIE1_` и `COOKIE2_`.
* Удалены устаревшие (deprecated) функции `Seq` и `MapReduce`.
* Для функций `FOpen`, `FReadBytes`, `FWriteBytes` созданы синонимы, соответственно,
  `Open-Auto`, `ReadBytes`, `WriteBytes`.
* Функции `FOpen`, `FClose`, `FReadLine`, `FWriteLine`, `ReadLine`, `WriteLine`,
  `IntFromStr`, `StrFromInt`, `FReadBytes`, `FWriteBytes` становятся **устаревшими
  (deprecated)**, в следующем релизе они будут удалены.
* Переименованы исполнимые файлы:
  - Компилятор называется `rlc` (`rlc-core`).
  - Утилита поиска зависимостей — `rlmake` (`rlmake-core`).
  - Генератор лексических анализаторов — `rl-lexgen`.
  - Декомпилятор `.rsl` — `rl-rsl-decompiler`.

  Старые имена (`srefc`, `srefc-core`, `srmake`, `srmake-core`, `lexgen`,
  `rsl-decompiler`) остаются доступны, но являются **устаревшими (deprecated).**
  В следующем релизе они будут удалены.


# [2.5] — 2020-01-31
## N-модули, новые ключи командной строки и режимы компиляции

* Опция `--ref5rsl` добавляет в путь поиска переменную окружения `REF5RSL`.
* Сгенерированные файлы `.rasl` и `.cpp` помещаются по умолчанию в текущую папку,
  альтернативную папку можно указать при помощи `--temp-dir=…` (эта опция ранее
  поддерживалась, но игнорировалась).
* Работает опция `--keep-rasls`, ранее она игорировалась.
  По умолчанию .rasl-файлы удаляются после перекомпиляции.
* Работает опция `--overwrite-exist-rasls`, ранее она игнорировалась.
  По умолчанию существующие .rasl-файлы с теми же именами перезаписываются.
* **ИСПРАВЛЕНО:** формирование имени целевого файла. Ранее оно могло иметь вид
  `sourcefile@1.exe` в некоторых редких случаях.
* Флаги `--cpp-command-exe-suf=…`, `--cpp-command-lib-suf=…`. На Windows они могут
  использоваться для передачи .def-файла для библиотек, на Linux для передачи
  дополнительных внешних библиотек (вроде `-lm`, `-ldl`).
* В шаблоне конфигурации компилятора C++ задаются переменные `CPPLINEL`,
  `CPPLINEESUF`, `CPPLINELSUF`.
* **ИСПРАВЛЕНО:** в случае успешной компиляции выдаётся сообщение «Compilation
  succeeded» вместо ошибочного «Compilation successed».
* Для поддержки N-модулей изменился API рантайма.
* Поддерживаются N-модули: их генерация и загрузка.
* Для стандартных библиотек `Hash`, `Library`, `GetOpt`, `LibraryEx`, `Platform`
  генерируются `.dll`/`.so` для динамической загрузки, располагаются в папке `/bin`.
* Инсталлятор на Windows устанавливает переменную среды `RL_MODULE_PATH`.
* Небольшие уточнения в `README.md`.
* Префикс `slim(-debug).exe-prefix` не содержит библиотеку `Hash`.
* Расширен аварийный дамп. Помимо поля зрения выдаётся сводка из домена:
  списки загруженных модулей, функций в них и идентификаторов.
* **ИСПРАВЛЕНО:** предупреждение компилятора GCC на рантайм.
* **ИСПРАВЛЕНО:** функция Compare выполняется за один виртуальный шаг.
* Вместо папки `/srlib` используется папка `/lib`.
* Флаг компилятора `--no-sources`, позволяющий создать целевой файл
  содержащий только ссылки и/или флаги `--incorporated`. Без флага
  `--no-sources` компилятор выдаёт сообщение об ошибке о том, что исходники
  отсутствуют.
* Изменена структура папки `/lib` в соответствии с задачей
  [#87][https://github.com/bmstu-iu9/refal-5-lambda/issues/87].
* Префикс `rich(-debug).lib-prefix`, содержащий `LibraryEx`, `Hash` и `GetOpt`.
* **ИСПРАВЛЕНО:** компилятор падал при наличии файла filename.cpp при отсутствии
  `filename.rasl`.
* Модуль может быть сам себе псевдонимом: допустима ситуация, когда модуль
  содержит и псевдоним `--incorporated=…` и ссылку с тем же именем.
* Скрипты `srefc(.bat)` и `srmake(.bat)` поддерживают новые ключи (в соответствии
  с [#87](https://github.com/bmstu-iu9/refal-5-lambda/issues/87):
  - ключи `--slim`, `--rich`, `--scratch` определяют префикс или его отсутствие,
  - ключи `--static`, `--dynamic`, `--auto` определяют компоновку с библиотеками
    `LirbraryEx` и `GetOpt`: статическая, динамическая и по умолчанию (статическая
    для исполнимых файлов, динамическая для библиотек),
  - ключи `--debug`, `--no-debug` включают и отключают компоновку с отладочными
    средствами, по умолчанию отладка отключена.

  Эти ключи должны быть первыми параметрами `srefc` и `srmake`, их может следовать
  неограниченное количество, последние имеют приоритет.


# [2.4.2] — 2019-08-12
## Багфиксы, библиотека Platform

* Исправлена ошибка, препятствующая раскрутке компилятора под Linux.
* Уточнён вывод команды `--help` в `srefc-core` и `srmake-core`.
* Библиотека `Platform`, совместимая с refal-5-framework, содержит
  платформенно-зависимые константы (разделитель каталогов, разделитель
  путей в `PATH`).
* Незначительное ускорение компиляции рантайма в режиме `--scratch`.


# [2.4.1] — 2019-08-12
## Багфиксы

* Вместо `--rename-exist-rasls` используется `--overwrite-exist-rasls`
  (аналогично, вместо `--dont-rename-…` `--dont-overwrite-…`).
* Компилятор некорректно работал с опциями `--(dont-)keep-rasls`, `--temp-dir`,
  `--(dont-)overwrite-exist-rasls`.
* В директивах `$SPEC` не работали квадратные скобки.
* Теперь при одновременном указании `$SPEC` и `$INLINE`/`$DRIVE` для функции
  выдаётся сообщение об ошибке. Ранее в подобной ситуации `$SPEC` молча
  игнорировался.


# [2.4] — 2019-08-02
## Оптимизации прогонки и специализации; багфиксы

* Реализована оптимизация прогонки и встраивания
  ([Кирилл Ситников][InfiniteDisorder] + мои   доработки). Есть ограничения,
  например, не оптимизируются вызовы в предложениях с условиями. Но в целом
  работает.
* Реализована оптимизация специализации ([Дарья Сухомлинова][StrixSeloputo]
  + мои доработки). Тоже есть ограничения, например, вызовы с активными
  аргументами в статических параметрах не специализируются.
* Функции библиотеки `LibraryEx` размечены для оптимизации. Чтобы их
  задействовать, нужно использовать `$INCLUDE "LibraryEx";` вместо
  extern’ов.
* Сообщения о синтаксических ошибках выводятся на `stderr`.
* Исправлено множество грамматических ошибок в документации. Спасибо
  Варваре Соболевой ([@sovarka][sovarka]), Владиславу Орлову
  ([@torrentino555][torrentino555]), Екатерине Гимрановой
  ([@kategimranova][kategimranova]).
* Исправлено предупреждение компилятора Visual C++ на код в рантайме.
* `srmake` и `lexgen` поддерживают ключи `--help` и `--version`.
* `srefc`, `srmake` и `lexgen` поддерживают ключи `-h`, `-?` и `-v`.
* Добавлен простой профилировщик функций. Включается при помощи
  `enable-profiler = true`
  в конфигурационном файле диагностики.
* Программа не падает на 4 294 967 295 шаге.
* Компилятор в дистрибутиве стал работать быстрее, поскольку
  перекомпилирован с ключами `-OdDPRS` (максимальная оптимизация на данный момент).


# [2.3.5] — 2019-06-17
## Поддержка директивы `$SPEC` (которая, однако, ничего не делает)


# [2.3.4] — 2019-06-10
## Исправлена ошибка в оптимизации совместного сопоставления с образцом


# [2.3.3] — 2019-06-03
## Багфиксы, синтаксис для прогонки и встраивания, ключи командной строки

* Ключевые слова `$DRIVE` и `$INLINE`, поддерживаются во входном языке,
  но пока не работают. Также поддерживается синтаксис списка entry-функций
  вида `$ENTRY F, G, H;`.
* Исправлено огромное количество орфографических ошибок в документации,
  большое спасибо Андрею Смирнову [@kupihleba][kupihleba] и Дмитрию Яковлеву
  [@DimaYakov][DimaYakov].
* Актуализированы файлы раскраски синтаксиса для поддержки ключевых
  слов `$DRIVE`, `$INLINE`, `$SPEC`.
* Добавлена поддержка компилятора Zapcc в `c-plus-plus.conf.template`.
* Добавлены опции `--help` и `--version` для `srefc-core`. Добавлены
  игнорируемые опции `--keep-rasls`, `--temp-dir`, `--ref5rsl`,
  --`rename-exist-rasls`, которые будут реализованы в следующей версии.
  Некоторые из них  в виде пустышек нужны сейчас для успешной раскрутки
  следующей версии.
* **ИСПРАВЛЕНО:** скрипты `srefc` и `srmake` не поддерживали пути
  к дистрибутиву с пробелами.
* **ИСПРАВЛЕНО:** встроенные функции арифметики поддерживают формат вида
  `<Add '-' 3 10>`.
* **ИСПРАВЛЕНО:** если программа падала по лимиту шагов, отображался кривой
  дамп. Теперь отображается нормально.


# [2.3.2] — 2019-04-30
## Багфиксы и REFAL_5_LAMBDA_SKIP_GETTIME

* Багфиксы в рантайме в финализации домена.
* Компилятор не падает при отрицательных кодах возврата System.
* Макрос `REFAL_5_LAMBDA_SKIP_GETTIME` для POSIX, пропускающий каждый
  N-й вызов функции `clock_gettime()` в профилировщике. Если он установлен
  (`-DREFAL_5_LAMBDA_SKIP_GETTIME=N`), то программа немного ускоряется
  (на Windows Subsystem for Linux — существенно ускоряется) ценой
  снижения точности профилировки.


# [2.3.1] — 2019-04-23
## Исправление раскрутки на Linux, исправлена ошибка с $EXTERN

* Ранее исходники не собирались на Linux, поскольку не был подклю́чен
  заголовочный файл `<stdlib.h>` в `refalrts-vm.h`.
* Также исправлено несколько предупреждений для GCC.
* Если в файле присутствовал `$EXTERN` с именем локальной функции,
  скомпилированная программа оказывалась неработоспособной.


# [2.3] — 2019-04-21
## Оптимизация, изменения API, орфография

В этой версии заметно ускорены компилируемые программы — был изменён
и генерируемый код, и рантайм. При измерении на компьютере с процессором
Intel® Core™ i5-2430M 2.40GHz, кэшами 128 Кбайт/512 Кбайт/3,0 Мбайт,
8 Гбайт ОЗУ, Windows 10 x64 и с компилятором BCC 5.5.1 (оптимизация
с ключом -o) получились следующие цифры.

Измерялось чистое время Рефала (Total refal time), был сделан 21 замер,
использовался «стандартный бенчмарк» `src/compiler/benchmark.bat`,
выбирались медиана и два квартиля.

Компиляция без оптимизаций (за исключением `-OC`, но она по умолчанию).

До оптимизации (т.е. версия 2.2.7) — 21,427 секунд (доверительный
интервал 21,299–21,646), после оптимизации — 16,652 секунды (16,525–16,754).
Ускорение: 22 %, более чем достоверное.

Компиляция со всеми оптимизациями (`-OdRPC`):

До оптимизации — 8,904 секунды (8,813–9,005), после оптимизации —
7,386 секунд (7,210–7,497). Ускорение: 17 %, достоверное.

Изменился API: теперь счётчики производительности стали `double` вместо
`long int`, функции выделения памяти стали «безотказными». Функции выделения
памяти возвращают void, при недостатке памяти они делают нелокальный переход
(`longjmp`) к соответствующему обработчику. Пользователь может перехватывать
ошибки выделения памяти при помощи функции `refalrts::checked_alloc()`.

Дескрипторы функций больше не удаляются по счётчику ссылок, они живут
до конца жизни домена, как и идентификаторы.

На POSIX (Linux и macOS) используются более быстрые функции запроса
времени, что ускорило выполнение программ на соответствующих ОС.

Исправлена ошибка с составными символами вида `"Abc\x00def"`.

[Роман Хурчаков][romahurchakov] исправил 11 орфографических ошибок
в руководстве пользователя и внутренней документации.

Версию для Windows можно собрать с макросом `REFAL_5_LAMBDA_USE_QPC`,
в этом случае для замера времени будет использоваться функция
`QueryPerformanceCounter()`. Она замедляет общее время работы, но обеспечивает
более точный замер времени.


# [2.2.7] — 2019-03-22
## Изменения в прямой кодогенерации, багфиксы

* В прямой кодогенерации больше не используются `ExternalReference`
  и `IdentReference`.
* Составные символы в двойных кавычках с нулём внутри `"ABC\x00DEF"`
  обрезаются по нулю.
* Исправлена ошибка в функции `Mu`: не работали вызовы типа `<Mu '+' …>`
  и `<Mu "+" …>`.


# [2.2.6.1] — 2019-03-19
## Мелкие багфиксы

* Теперь программа не падает при диагностической сортировке.
* Вызов замыкания (включая блок Рефала-5) выполняется за 1 шаг.


# [2.2.6] — 2019-03-19
## Поддержка .rsl-файлов и внутренний рефакторинг

* Поддержка 32-разрядных .rsl-файлов — утилита декомпиляции
  `rsl-decompiler` + автоматический её вызов из компилятора `srefc`.
  `srefc` и `srmake` понимают .rsl-файлы как исходники. Утилита сборки
  извлекает зависимости из `.rsl.froms`.
* Некоторый рефакторинг внутри, который снаружи не виден.


# [2.2.5] — 2019-02-26
## Перевод исходников на Рефал-5λ, исправления ошибок

* Исправлено некоторое количество недочётов в программе:
  - предупреждения нового GCC,
  - имена функций и переменных, начинающиеся с прочерка — правильно работают
    в Рефале-5λ, являются синтаксическими ошибками в классическом режиме.
* Исправлено более трёх десятков ошибок и опечаток в руководстве, большое
  спасибо за них [Анне Синявской][anyasinyavskaya]!
* Исходники переведены на Рефал-5λ с Простого Рефала. Включая включаемые
  файлы (`.srefi` → `.refi`).
* Язык Рефал-5λ поддерживает ключевое слово `$LABEL`, которое, однако,
  **deprecated,** в будущих версиях может быть удалено. Оно даже
  не поддерживается в файлах раскраски синтаксиса.


# [2.2.4] — 2019-02-05
## Синтаксис `$SPEC`, мелкие багфиксы

* Частично поддерживается синтаксис `$SPEC`, поддержка давно была реализована
  [Дарьей Сухомлиновой][StrixSeloputo], сейчас я её перенёс на `master`.
* Добавлено приложение к документации про типы и форматы функций.
* В исходниках исправлено несколько грамматических ошибок.
* Исправлены ошибки и предупреждения, выявленные новым GCC.


# [2.2.3] — 2018-10-02
## Исправление раскрутки, улучшение трассировки, `-OC`, ошибка с `Sub`

* Исправлены ошибки в `bootstrap.*` — диагностические префиксы собираются
  с диагностикой и наоборот.
* В трассировке не отображаются «служебные шаги» — реализация встроенных
  функций и функции `INIT` и `FINAL`. Видны только содержательные шаги, которые
  не удивят программиста на классическом Рефале-5. Для их показа нужно
  установить диагностическую настройку `show-hidden-steps=true`.
* Скрипты `srefc` и `srmake` по умолчанию устанавливают флаг `-OC`. Для его отмены
  нужно явно использовать `-OC-`.
* Исправлена «тихая» ошибка со встроенной функцией `Sub` — раньше она
  не считалась за один шаг для функции `Step` и улучшенной трассировки.
* При развёртывании дистрибутива выводятся имена собираемых программ.
* **FIXED:** отладочные префиксы собираются с поддержкой диагностики.

  А релизные префиксы — без поддержки диагностики.

  До правки отладочные префиксы по умолчанию (без опции `--debug`) собирались
  как и всё остальное — без поддержки диагностики.


# [2.2.2] — 2018-10-02
## Документация, дамп без cookie, улучшения установщика

* Дописан параграф про сопоставление с образцом.
* В диагностических префиксах по умолчанию не выводятся cookie.
* Доработана процедура установки: `bootstrap.sh` умеет восстанавливать права
  доступа.
* Поддержка ключа `bootstrap.***` `--debug` для сборки с отладчиком

  Теперь, если для `bootstrap.bat` / `bootstrap.sh` не указан ключ `--debug`,
  исполнимый файл собирается без поддержки диагностики и отладчика.


# [2.2.1] — 2018-09-10
## Обновлён номер версии :-)


# [2.2] — 2018-09-10
## Поддержка R-модулей, реентерантный рантайм

* Компилятор умеет генерировать R-модули.
* Рантайм умеет модули загружать и выгружать. Причём умеет загружать
  модули по ссылкам. Выгрузка интеллектуальная — используется сборка мусора
  для определения ненужных модулей. Модули выгружаются в порядке, обратном
  загрузке.
* Ключ компилятора `--reference=…` добавляет ссылку на указанный модуль,
  ключ `--incorporated=…` добавляет псевдоним для модуля.
* SRMake понимает те же ключи, и в довесок псевдокомментарии
  `//REFERENCE` и `//INCORPORATED`.
* В Library появилось API динамической загрузки модулей и извлечения
  функций из них (функции `Module-…`).
* Символы-функции в поле зрения имеют счётчик ссылок. Поэтому в поле зрения
  не могут возникнуть висячие ссылки на функции выгруженных модулей.
  (Эти ссылки можно, например, распечатать. При попытке вызвать выгруженную
  функцию получается корректное recognition impossible вместо аварийного
  segfault’а).
* Теперь есть диагностические и недиагностические префиксы.
  Диагностические: `--rich-debug` и `--slim-debug` (по умолчанию),
  без диагностики: `--rich` и `--slim`.
* Диагностика теперь управляется конфигурационным файлом
  `@refal-5-lambda-diagnostics.txt` или `prog.exe@refal-5-lambda-diagnostics.txt`.
  В них в формате `ключ=значение` можно задать параметры `idents-limit`,
  `memory-limit`, `step-limit`, `start-step-trace` (целочисленные),
  `print-statistics`, `dump-free-list`, `enable-debugger` (булевские),
  `dump-file` (строковой). Если имя файла для дампа содержит пробелы, его
  можно заключить в кавычки.
* Рантайм стал реентерантным — API рантайма принимает теперь указатель
  на виртуальную машину, этот указатель передаётся вместе с `arg_begin`
  и `arg_end` в нативные функции. Значения глобальных переменных в нативном
  коде также ассоциированы с виртуальной машиной (вернее, с доменом).
* Монолитный рантайм был посечён на несколько отдельных файлов исходного
  кода, что упрощает его чтение и понимание.
* В папку `/doc` добавлена презентация с бауманского рефал-семинара 2018-06-05.
* Разные мелкие доделки и улучшения.


# [2.1] — 2018-07-18
## Улучшение алгоритма оптимизации совместного сопоставления с образцом

* Улучшен алгоритм оптимизации совместного сопоставления с образцом,
  теперь для похожих образцов строится дерево отождествления,
  образцы разбиваются на группы.
* Зачатки оптимизации на уровне деревьев:
  - поддержка висячего `$ENTRY` для front-end’а Простого Рефала,
  - обход дерева с раскрытием конструкторов замыканий вслед
    за открывающей угловой скобкой,
  - опции командной строки `-OT`, `-OD`, `-OS`, `-OI`, на данный момент они
    ничем не различаются (раскрывают конструктор замыкания).
* Функция `MapAccum` как синоним функции `MapReduce`.
* Функция `MapReduce` признана **нерекомендуемой (deprecated).**


# [2.0.5.1] — 2018-04-15
## Дистрибутив пересобран с ключом `-OC`


# [2.0.5] — 2018-04-15
## Реализована полная поддержка условий

* Полная поддержка условий (условия обрабатываются на уровне рантайма),
* Логгер (`--log=filename.log`) теперь дампит промежуточное представление
  на выходе из обессахаривателя в псевдо-Рефале.


# [2.0.4] — 2018-03-11
## FIXED: компилятор не падает на флаге `-e`/`--error-file`


# [2.0.3] — 2018-02-18
## Багфиксы, функциональность, документация (и английская тоже)

* Исправлен ряд ошибок в рассахаривателе условий.
* Появилась недописанная актуальная документация по Рефалу-5λ.
* Переводы на английский язык актуальной и важной исторической документации
  (за подготовку переводов особая благодарность студентам группы Л4-71).
* Рефакторинги в коде, которые никому не видны.
* Логирование промежуточного состояния: высокоуровневый RASL и синтаксическое
  дерево (последнее в псевдокоде, максимально приближенном к Рефалу).
  Включается опцией `--log=filename.txt`.
* Исправлены мелкие ошибки в оптимизации совместного сопоставления с образцом
  и в восстановлении после ошибок во front-end’е Рефала-5λ.
* Новые стандартные функции `LibraryEx`: `OneOf` и `Unique`.


# [2.0.2] — 2018-01-10
## Ряд багфиксов

* Исправлена сборка под Borland C++ Compiler 5.5.
* Исправлена ошибка в функции деления с остатком (в некоторых случаях
  остаток оказывался пустым выражением вместо нуля).
* Исправлена ошибка в запуске режима `--syntax-check` — не поддерживался
  Рефал-5λ.
* Не поддерживалсф пробельный символ `\r` в исходных текстах Рефала-5λ.
* Ошибка в восстановлении после ошибок в парсере.


# [2.0.1] — 2018-01-05
## Вывод номера версии, мелкие багфиксы


# [2.0] — 2018-01-05
## Полностью реализован запланированный синтаксис Рефала-5λ


# [1.7.5] — 2018-01-02
## Префикс «slim» и лямбды

* Префикс «slim», который включает в себя только рантайм, `Library` и `Hash`.
  Установлен по умолчанию и рекомендуется для компиляции программ
  классического РЕФАЛа-5 (например, SCP4).
* Рефал-5λ: классический и расширенный режимы, управляемые, соответственно,
  псевдокомментариями `*$CLASSIC[;]` и `*$EXTENDED[;]`. В первом случае
  запрещены конструкции Рефала-5λ.
* Рефал-5λ: поддержка функций высших порядков: `&Func`, `<<GetFunc…>…>`,
  `<s.FuncName …>`, вложенные функции `{ … }`. Наконец-то, Рефал-5λ оправдывает
  своё название.
* Исправлена мелкая ошибка в оптимизации совместного сопоставления
  с образцом.


# [1.7.4] — 2017-12-24
## Режим `--rich` по умолчанию, не требуется компилятор C++


# [1.7.3] — 2017-12-21
## Merge branch 'refal-5-lambda'

Ветка «λ» влита в основную ветку.


# [1.λ.15, ветка «λ»] — 2017-12-21
## Полная поддержка РЕФАЛа-5, условия в Простом Рефале, изменения кодогенерации

* Полностью реализована поддержка всех встроенных функций РЕФАЛа-5
  за исключением метафункций (`Up`, `Dn`, `Ev-met` и соседних с ними).
* В Простом Рефале реализован синтаксис условий.
* Замыкания создаются за 0 шагов.
* Несущественные правки изменения генерации предобъявлений (в частности,
  функции теперь по алфавиту, что видно в diff’е).
* Появились встроенные функции длинной арифметики, копилки и обработки
  строк и преобразования типов.
* Добавлены составные кирпичики для чистовой реализации функции `Mu`:
  функция `PtrFromName` и автоматическая генерация функции `_Mu` — функция
  Mu на данный момент просто вызывает `_Mu`.
* Обновлён механизм конфигурирования (`c-plus-plus.conf`)
  Теперь этот скрипт копируется из файла `scripts/c-plus-plus.conf.*.template`.
* Мелкое исправление кодогенерации, устраняющее предупреждение GCC,
  причём предупреждение на пустом месте (но из-за этого много файлов
  поменялось).
* Удалена функция `Compare` из `LibraryEx`.
* Мелкие рефакторинги и устранения предупреждений компилятора.
* Небольшое изменение кодогенерации — расстановка команд сохранения.
  Добавляет избыточные команды, но при этом компилятор работает быстрее
  и кодовая база его прозрачнее. Из-за этого такой длинный дифф этого
  коммита.
* Частично улушенная поддержка встроенных функций Рефала-5λ (реализованы
  функция `Type` и функции ввода-вывода). Удалены `SymbType` и `Type` из,
  соответственно, `Library` и `LibraryEx`.
* Изменение, ради которого создавалась эта стабильная версия. Вместо
  функции `Compare` в `LibraryEx` введена `TermCompare`, функция `Compare`
  объявлена как **deprecated.**
* Раз уж пересоздаётся стабильная версия, был добавлен синтаксис блоков
  в Простой Рефал. Добавить его быстро, но ради него обновлять стабильную
  версию не хотелось.
* Реализована раскраска синтаксиса Рефала-5λ для Vim и Far Colorer.
* Влита функциональность версии 1.7.2.
* Оптимизация front-end’а Рефала-5


# [1.7.2] — 2017-11-02
## Полунаписанный новый LexGen, мелкие правки в отладчике

Елена Бурлова aka [KazuriCode][KazuriCode] частично написала front-end для
генератора лексических анализаторов, принимающий на входе регулярные
выражения. Однако, компиляция регулярных выражений в лексический распознаватель
реализована не была.


# [1.λ.14, ветка «λ»] — 2017-08-06
## Расширения синтаксиса, багфиксы, подсветки синтаксиса

Добавлена поддержка идентификаторов в стиле РЕФАЛа-5 (с маленькой буквы
и с различием `-` и `_`), составные символы в кавычках и директива `$INCLUDE`.

Добавлен каталог с параметрами конфигурации подсветки синтаксиса для
нескольких текстовых редакторов.

LexGen содержит наполовину реализованный генератор лексических анализаторов
на основе регулярных выражений. Просто из-за того, что в ветку `refal-5-lambda`
влилась ветка `master`.

Кроме того имеем мелкие багфиксы и другие мелкие изменения.


# [1.λ.13, ветка «λ»] — 2017-07-03
## Поддержка модулей типа I0, багфиксы, вычисления хешей

* Поддержка модулей типа I0.
* Работает режим `--rich`.
* Поддержка ключа `--compile-only` (`-C`). Ранее ключ `-C` задавал
  дополнительные ключи для компилятора C++.
* Поддержка ключа `--chmod-x-command=…`.


# [1.λ.12.2, ветка «λ»] — 2017-05-23
## FIXED: мелкие багфиксы в механизме развёртывания дистрибутива

* `rasl-appender` теперь проверяет открытие файла RASL.
* Скрипты `bootstrap.*` останавливаются на первой ошибке компиляции.
* Поддержка ключей `--rich`, `--slim` и `--scratch` в скриптах `srefc`
  и `srmake`, которые, однако, ничего не делают (все режимы эквивалентны
  режиму `--scratch`).


# [1.λ.12.1, ветка «λ»] — 2017-05-23
* Багфиксы; удаление предупреждений `g++` в рантайме


# [1.λ.12, ветка «λ»] — 2017-05-21
## Обновлены скрипты `srefc` и `srmake`; багфиксы; новые опции командной строки

* Опции `--exesuffix=…` (вместо `--targsuffix=…`), `--cpp-command-exe=…`
  (как синоним для старой `--cpp-command=…`), `--cpp-command-lib=…`,
  `--incorporated=…`, `--prefix=…`, `--reference=…`, `--makeexe` (`-x`),
  `--makelib` (`-l`), `-R`.


# [1.λ.11.2, ветка «λ»] — 2017-03-14
* Merge branch 'master' into refal-5-lambda


# [1.7.1] — 2017-03-14
* Исправлена ошибка в компиляции присваиваний


# [1.λ.11.1, ветка «λ»] — 2017-03-14
* Префикс командной строки теперь называется `CPPLINEE`


# [1.λ.11, ветка «λ»] — 2017-03-14
* Merge branch 'master' into refal-5-lambda


# [1.7] — 2017-03-14
* Добавлена поддержка синтаксиса присваиваний


# [1.λ.10, ветка «λ»] — 2017-03-08
* Merge branch 'master' into refal-5-lambda


# [1.6] — 2017-03-08
* Реализован интерактивный пошаговый отладчик


# [1.λ.9.1, ветка «λ»] — 2017-02-26
## Поддержка macOS, багфиксы

* Поддержка macOS.
* **HOTFIX:** приписывание RASL’а в конец исполнимых файлов.

  Комментарий из дистрибутива:

  Теперь ведь исполнимый файл, созданный Простым Рефалом, состоит из префикса —
  исполнимого файла ОС, собранного из исходников C++, и суффикса — файлов
  с RASL’ом, которые приписываются в конец, но начиная со смещения 4096.

  Здесь (в дистрибутиве) у нас нет `srefc`, чтобы собрать правильный исполнимый
  файл. Поэтому была написана утилита, добавляющая правильным образом RASL
  в конец.
* **HOTFIX:** отсутствовал заголовочный файл `<errno.h>`


# [1.λ.9] — 2017-02-26
* Файлы `*.rasl` используются, `*.rasl.cpp` уже не генерируются


# [1.λ.8.1, ветка «λ»] — 2017-02-25
## Багфиксы; схема именования файлов; платформенно-зависимый рантайм

* Вместо `*.native.cpp` генерируются файлы `*.cpp`.
* Генерируются (пока не используемые) файлы `*.rasl`.
* Поддержка платформенно-зависимых функций в рантайме. В платформенно-
  зависимой части пока только одна функция —
  `platform_specific::get_main_module_name()`, единственный её вызов —
  отладочный.


# [1.λ.8, ветка «λ»] — 2017-01-08
## Новые опции командной строки, новое поведение `CPPLINE`

* Командная строка `CPPLINE` должна теперь заканчиваться на опцию имени
  целевого файла, например `g++ -o` для GNU C++, `cl … /Fe` для MSVC,
  `bcc32 -e` для BCC 5.5.1.
* Опция `-o` у `srefc` и `srmake`.
* Опция `--targsuffix=…` (`--targsuf`, `--targetsuffix`), задающая расширение
  целевого файла (задаётся как `.exe` на Windows, как пустая строка на POSIX).


# [1.λ.7, ветка «λ»] — 2017-01-08
* Некоторые изменения в кодогенерации;
* новые функции в библиотеке


# [1.λ.6, ветка «λ»] — 2017-01-04
* Поддержка двоичного ввода-вывода в библиотеке


# [1.λ.5, ветка «λ»] — 2017-01-03
* Встроенный целый тип — 32-разрядный


# [1.λ.4, ветка «λ»] — 2016-11-21
* Динамическое связывание функций


# [1.λ.3, ветка «λ»] — 2016-11-07
* Идентификаторы сделаны динамическими


# [1.λ.2, ветка «λ»] — 2016-11-06
* Подготовка к созданию интерпретатора; багфиксы


# [1.5.1] — 2016-11-06
* Багфиксы. Главный из них — в `FastGen`


# [1.λ.1, ветка «λ»] — 2016-11-04
* Инкапсуляция на основе cookie


# [1.λ.0, ветка «λ»] — 2016-10-24
* Функция `HashLittle2-Chars`


# [1.5] — 2016-09-25
* Основным циклом программы сделан цикл интерпретации RASL
* Все функции интерпретируемые; `stop_sentence()`; система команд RASL’а


# [1.4.2] — 2016-09-22
* Профилировщик считает runtime overhead


# [1.4.1] — 2016-09-11
* Удаление макроса `MODULE_REFAL`
* Использование `refalrts::RefalNativeFunction`

  Последний пункт — первый шаг при выполнении задачи
  <https://github.com/bmstu-iu9/simple-refal/issues/62>

* Добавлено пасхальное яйцо


# [1.4] — 2016-09-01
* Стилевые правки `refalrts.*`, обновлён копирайт


# [1.3.5] — 2016-08-29
* Рефакторинг библиотеки `Library.sref`


# [1.3.4.1] — 2016-08-20
* FIXUP: переменная контекста может быть с дефисами


# [1.3.4] — 2016-08-20
* Улучшения кодогенерации,
* опция `--markup-context`


# [1.3.3.1] — 2016-08-20
* Улучшения перехвата внутренних ошибок


# [1.3.3] — 2016-08-19
* Багфиксы компилятора и LexGen’а, общие улучшения LexGen’а


# [1.3.2] — 2016-08-13
* Параметр `STEP_LIMIT` рантайма, багфиксы


# [1.3.1] — 2016-08-12
* HOTFIX: предыдущий вариант не работал с Visual C++ (#46)


# [1.3] — 2016-08-12
* Для функций генерируются дескрипторы


# [1.2] — 2016-08-09
* Реализована поддержка вставок кода на C++
* Функции `Trim-L` и `Trim-R` в LibraryEx
* Расширен диапазон символов в сообщениях об ошибках LexGen’а
* Уточнение и актуализация целей в `README.md`


# [1.1.4] — 2016-08-08
## Большой рефакторинг внутри, небольшие изменения кодогенерации снаружи

Изменения кодогенерации:

* вложенные функции имеют человекопонятные имена,
* отображаемые (в дампе и отладочных комментариях) имена функций
  и идентификаторов пишутся через дефисы, а не подчёркивания,
* комментарии оптимизации совместного сопоставления с образцом
  пишутся в унифицированном виде с другими комментариями в коде,
  без пробелов на концах строк.


# [1.1.3] — 2016-07-26
* Оптимизация алгоритма GST;
* новые функции стандартной библиотеки `LibraryEx`: `Min` и `Max`.


# [1.1.2] — 2016-07-22
* FIXED: исправлена пара ошибок в оптимизации образцовых выражений


# [1.1.1] — 2016-07-22
* Оптимизации `-OP` и `-OR` работают совместно (`-OPR`, `-ORP`)


# [1.1.0] — 2016-06-30
## Оптимизация совместного сопоставления с образцом

Иван Скрыпников aka [mrbell270][mrbell270] реализовал оптимизацию совместного
сопоставления с образцом. Оптимизация включается опцией `-OP`.


# [1.0.4] — 2016-06-30
## Оптимизация результатных выражений и другие правки

* Евгений Копьёв aka [AsadiR][AsadiR] реализовал оптимизацию построения
  результатных выражений. Оптимизация включается опцией `-OR`.
* Реализована подсветка синтаксиса для ряда текстовых редакторов.
* Исправлены ошибки при разборе параметров командной строки.
* Опция командной строки `-D` для `srefc`/`srmake` задаёт пути поиска, которые
  также должны транслироваться в опции `-I` для компилятора C++.
* Уточнено README.md


# [1.0.3] — 2016-03-20
## Изменения в кодогенерации + библиотечный модуль `GetOpt.sref`

<https://github.com/bmstu-iu9/refal-5-lambda/25>

* Изменения кодогенерации коснулись, в основном, отладочных комментариев
  в сгенерированном коде.
* Библиотечный модуль написан, описание API в `srlib/src/GetOpt.sref`.
* Изменения в кодогенерации
  1. Теперь неиспользуемые e-переменные больше не пропускаются.
  2. Исправлена ошибка в `TextFromPattern-Char`.
* Удалён неактуальный код в рантайме


# [1.0.2] — 2016-02-24
## Исправлены ошибки в скриптах


# [1.0.1] — 2016-02-08
## Исправлены ошибки в скрипте

* Bash не поддерживает конструкцию `if` с пустым телом.
* Ключи командной строки нужно было заключать в кавычки.


# [1.0] — 2016-02-07
* Актуализирована документация
* Опции `-Wall` и `-g` для компиляторов `g++` и `clang++` для unix-like
* Свободное гнездо для другого компилятора C++
* Пользовательская установка имеет приоритет
* Унификация скриптов компиляции Windows/unix-like (Mazdaywik/simple-refal#9)
* Восстановлена зависимость `LibraryEx` → `Library` (Mazdaywik/simple-refal#9)
* Добавлена документация в дистрибутив (Mazdaywik/simple-refal#9)
* Поддержка скриптов `srefc` и `srmake`
* Сборка дистрибутива без вывода статистики
* Скрипты очистки папки, `.gitignore`
* Исходный текст `LibraryEx.sref` восстановлен
* Хранение `LibraryEx` в скомпилированном виде
* Базовая структура дистрибутива
* `LICENSE` и `README.md` синхронизированы с Простым Рефалом


[simple-refal-distrib]: https://github.com/bmstu-iu9/simple-refal-distrib.git
[Santalov]:             https://github.com/Santalov
[penachett]:            https://github.com/penachett
[Kaelena]:              https://github.com/Kaelena
[Mazdaywik]:            https://github.com/Mazdaywik
[koshelevandrey]:       https://github.com/koshelevandrey
[CStyler]:              https://github.com/CStyler
[nexterot]:             https://github.com/nexterot
[TonitaN]:              https://github.com/TonitaN
[refal-5-framework]:    https://github.com/Mazdaywik/refal-5-framework
[suova]:                https://github.com/suova
[GDVFox]:               https://github.com/GDVFox
[InfiniteDisorder]:     https://github.com/InfiniteDisorder
[StrixSeloputo]:        https://github.com/StrixSeloputo
[sovarka]:              https://github.com/sovarka
[torrentino555]:        https://github.com/torrentino555
[kategimranova]:        https://github.com/kategimranova
[kupihleba]:            https://github.com/kupihleba
[DimaYakov]:            https://github.com/DimaYakov
[romahurchakov]:        https://github.com/romahurchakov
[anyasinyavskaya]:      https://github.com/anyasinyavskaya
[KazuriCode]:           https://github.com/KazuriCode
[mrbell270]:            https://github.com/mrbell270
[AsadiR]:               https://github.com/AsadiR
