Releases: bmstu-iu9/refal-5-lambda
Рефал-5λ, версия 3.3.1
Исправлена ошибка сборки на MinGW64
- Не подумав, удалил небольшой, но важный параметр для сборки в окружении GitHub Actions. Из-за этого сборка в GitHub Actions валилась.
- Исправлена ошибка в скрипте компиляции библиотек
src\lib\make.bat
, из-за которой дистрибутив для UNIX-like создавался с ошибками.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-3.3.1.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-3.3.1.zip
или bootstrap-refal-5-lambda-3.3.1.tar.gz
)
Рефал-5λ, версия 3.3
NEWS.md
, пошаговый отладчик, -Wrepeated
, e.X$a
, -Wdeprecated
Файл NEWS.md
В репозиторий добавлен файл NEWS.md
, в нём будут описываться новшества каждой следующей версии. Файл сформирован основе сообщений коммитов в репозитории simple-refal-distrib.git. Последние три года коммиты в нём создавались при выпуске новой версии, описания фиксаций включали в себя новшества разной степени детализации. Ранние коммиты прокомментированы скупо, более поздние — подробно.
Файл был создан полуавтоматически — сформирована заготовка при помощи git log
с хитро заданным форматом, результат был вручную отформатирован в разметке Markdown
.
Для некоторых ранних версий (особенно, представленных несколькими последовательными коммитами в репозитории дистрибутива) было написано новое описание вручную.
Возможно, в дальнейшем ранние версии будут прокомментированы подробнее.
Пошаговый отладчик
Станислав Санталов aka @Santalov в рамках курсовой работы по «Конструированию компиляторов» расширил возможности встроенного пошагового отладчика. Работа велась в рамках задачи #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 в рамках курсовой работы реализовал выдачу предупреждений на подозрительные повторные переменные.
Рефал-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
в случае ошибки — так сделано для отладки ошибок, обнаруженных в среде непрерывной интеграции.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-3.3.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-3.3.zip
или bootstrap-refal-5-lambda-3.3.tar.gz
)
[DimaY...
Рефал-5λ, версия 3.2
В данной версии, прежде всего, существенно расширились возможности древесной оптимизации. Метки $SPEC
и $DRIVE
стали безопасными, появилась возможность оптимизировать все функции, которые оптимизировать возможно (т.е. метки $SPEC
и $DRIVE
теперь могут назначаться автоматически), компилятор может статически вычислять некоторые встроенные функции.
Также появился инструмент статического анализа — обнаружение экранируемых предложений. На такие предложения выводится предупреждение.
Были и другие изменения, о которых ниже.
Некоторые средства компилятора устарели, составлен список нерекомендуемых (deprecated) средств.
__INIT
и __FINAL
ВАЖНО! Нарушилась обратная совместимость!
Новая версия компилятора считает функциями инициализации и финализации не INIT
и FINAL
, а __INIT
и __FINAL
. При этом, функции __INIT
и __FINAL
должны быть локальными — их определение как $ENTRY
является ошибкой синтаксиса.
Режим -OA
— оптимизация всех функций
Режим -OA
— оптимизация всех (all) функций, вызовы которых можно оптимизировать. Если функция может прогоняться, её вызовы будут прогоняться, если функция может специализироваться, её вызовы будут специализироваться.
Для достижения этой цели синтаксическое дерево сканируется и выявляются функции, которым можно поставить метки $DRIVE
и $SPEC
. Расстановка меток $INLINE
не поддерживается, т.к. статически выявлять такие функции слишком сложно.
Кроме того, в данном режиме выполняется постобработка дерева после выполнения древесных оптимизаций. Дело в том, что после выполнения циклов прогонки и специализации в дереве могут появиться экземпляры специализированных функций, которые можно успешно прогнать в точки вызова.
Компонент разметки функций разработан совместно Еленой Калининой aka @Kaelena и Александром Коноваловым aka @Mazdaywik.
Более безопасная специализация
Теперь пометка функции как $SPEC
не может привести к бесконечному циклу построения новых экземпляров. История построения экземпляров отслеживается, и если в истории обнаружилась сигнатура, похожая на предыдущую, строится экземпляр не для новой сигнатуры, а для сигнатуры, полученной как ГСО старой и новой.
Сходство двух сигнатур определяется так: если в новой сигнатуре можно стереть какие-либо элементы (символы, параметры, пары скобок), что получится предыдущая без учёта имён параметров, то значит новая похожа на эту предыдущую. В математике этот критерий называется отношением Хигмана-Крускала и для него доказывается, что он является хорошим предпорядком. Т.е. для любой бесконечной цепочки сигнатур рано или поздно найдётся такая, что будет похожа на предыдущую.
Поскольку отношение похожести прерывает любые бесконечные цепочки, а число возможных обобщений в виде жётского выражения (что вычисляет ГСО) для любого выражения конечно, любая бесконечная цепочка экземпляров рано или поздно прервётся. Таким образом, процесс специализации теоретически конечен.
На практике это означает, что большинстве случаев назначение метки $SPEC
не приводит к проблемам при компиляции. Это используется, в частности, в рассмотренном режиме -OA
, который назначает метки $SPEC
всем функциям, для которых можно построить шаблон с как минимум одной статической переменной.
Однако, 100%-но безопасной специализацию назвать нельзя. Иногда до обнаружения похожей сигнатуры может потребоваться много проходов оптимизатора (например, для взаимно-рекурсивных функций) и при этом на каждом проходе создаётся по несколько новых экземпляров. В таких случаях компилятор может надолго задуматься и съесть всю доступную память, прежде чем будет достигнуто теоретическое прерывание цикла.
Для борьбы с подобными ситуациями проблемным функциям можно вручную назначить сигнатуру с одними только динамическими параметрами, либо воспользоваться псевдофункцией gen_e__
(см. далее).
Прерывание зацикливания специализации совместно разработано Андреем Кошелевым aka @koshelevandrey и Александром Коноваловым aka @Mazdaywik.
Встроенные функции могут вычисляться на стадии компиляции (-Oi
)
Некоторые из встроенных функций теперь считаются «интринсиками» — функциями, вызовы которых компилятор распознаёт и может оптимизировать статически.
К ним относятся все функции арифметики, функции работы со строками (First
, Last
, Lenw
), функции преобразования типов, функции Type
и Mu
. Вызовы этих функций оптимизируются, если на стадии компиляции информации достаточно, чтобы их вызов правильно преобразовать. Так, например, функции Type
достаточно знать первый терм своего аргумента (он не должен быть переменной или вызовом функции).
Оптимизация интринсиков включается опцией -Oi
. Для того, чтобы компилятор начал распознавать некоторую функцию как интринсик, она должна быть объявлена при помощи директивы $INTRINSIC
:
$INTRINSIC Add, Mu, Type;
Оптимизация интринсиков совместно разработана Ханагой Агазаде aka @Cstyler и Александром Коноваловым aka @Mazdaywik.
Распознавание экранируемых предложений (-Wscreening
)
В компилятор был добавлен первый серьёзный инструмент статического анализа кода для поиска в нём дефектов.
При использовании опции -Wscreening
компилятор распознаёт случаи экранирования предложений и выдаёт на них предупреждения. Предложение называется экранируемым, если множество значений, описываемым его левой частью, является подмножеством множества, описываемого левой частью одного из предшествующих образцов.
При распознавании экранирования используются два подхода:
- Использование алгоритма совместного сопоставления с образцом — образец «нижнего» предложения сопоставляется с «верхним» без сужений.
- Использование подхода, основанного на языках образцов.
Каждый из этих подходов может распознавать случаи экранирования, недоступные другому подходу, поэтому используются они оба.
При тестировании алгоритм верно выявил экранирования в исходных текстах самого компилятора, суперкомпиляторов SCP4 и MSCP-A. Экранирования в исходных текстах самого компилятора устранены, о случаях экранирования в суперкомпиляторов сообщено их авторам.
Распознавание экранируемых предложений совместно разработано Александром Барлукой aka @nexterot, Антониной Непейвода aka @TonitaN и Александром Коноваловым aka @Mazdaywik.
Поддержка предупреждений, появившаяся в прошлой версии, также была разработана Александром Барлукой aka @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. - Некоторые главы документации были незначительно актуализированы.
- Анастасия Кузнецова aka @suova исправила множество грамматических ошибок в сообщениях компилятора об ошибках (в основном, пропущенные артикли).
- Незначительно улучшено форматирование дерева в логе.
- Незначительно изменена кодогенерация в режиме
-OP
: размер групп предложений не превышает 50. - После выполнения древесных оптимизаций из программы удаляются функции с суффиксами, недоступные прямо или косвенно из функций без суффиксов.
- Метка
$DRIVE
стала безопасной — инструмент разметки меток$DRIVE
может не только добавлять новые, но и удалять имеющиеся пометки. Из-за того, что б...
Рефал-5λ, версия 3.1
Предупреждения
Компилятор теперь поддерживает выдачу предупреждений (#273, #281). Синтаксис позаимствован у GCC:
-Wимя
— включает предупреждение с заданным именем,-Wno-имя
— отключает предупреждение с заданным именем,-Wall
— включает все предупреждения,-Werror=имя
— трактует указанное предупреждение как синтаксическую ошибку — останавливает компиляцию,-Werror
— трактует все включенные предупреждения как ошибки.
Доступные предупреждения:
-Wscreening
— поиск и вывод экранируемых предложений (пока не реализовано),-Winit-final-entry
— выдаёт предупреждение, если функцияINIT
илиFINAL
определена как$ENTRY
,-Wnul-in-compound
— предупреждает об идентификаторах вида"abc\x00def"
, такие идентификаторы усекаются до первого\x00
в имени,-Wignored-pseudocomments
— если включен режим совместимости с классическим Рефалом-5 (--classic
), то выдаётся предупреждение на псевдокомментарии, что они в этом режиме игнорируются.
Поддержка предупреждений реализована Александром Барлукой (@nexterot).
Список поддерживаемых предупреждений в будущих версиях будет пополняться.
Оптимизации
-
Небольшие оптимизации в самом компиляторе, компилятор стал работать немного быстрее (#194).
-
Вложенные функции (включая также неявно создаваемые функции для присваиваний и блоков) теперь не только прогоняются, но и специализируются по переменным контекста (#160). Это позволяет передавать информацию о значениях связанных переменных, даже если прогонка не удалась.
-
В режиме рассахаривания условий (
-OC-
) вспомогательные функции, имитирующие семантику условий, также прогоняются и специализируются по переменным контекста (#283). Это позволяет оптимизировать программы на классическом Рефале, где условия используются в роли присваиваний. -
Глобальная оптимизация (#255) — синтаксические деревья отдельных единиц трансляции объединяются в одно. Это позволяет определить встраиваемую или прогоняемую функцию в одной единице трансляции, и оптимизировать её вызов в другой.
Включается опцией
-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) исправила огромное количество ошибок в переводах документации на английский язык (#280).
- В архивах
*.tar.gz
теперь будут правильно выставляться флаги исполнимости. - Лексер для Рефала-5 допускал пустые индексы переменных вида
e.
Исправлено.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-3.1.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-3.1.zip
или bootstrap-refal-5-lambda-3.1.tar.gz
)
Рефал-5λ, версия 3.0.1
Документация (#149)
- Написано «Приложение B. Краткий справочник».
- На страницы документации добавлены содержания, исправлены уровни заголовков (которые стали заметны благодаря содержаниям).
Оптимизации (#194)
-
Незначительно оптимизирована библиотека Library:
__Step-Drop
для одношаговых обёрток, функцииFirst
,Last
иLenw
переписаны на Си++. -
Оптимизировано распределение памяти: время копирования повторных переменных ускорено примерно в 1,5–2 раза, линейное время построения результата — на 8 %.
-
Общее ускорение компилятора: использование более быстрой библиотеки, оптимизация в лексическом анализаторе. Кумулятивное ускорение в обычном режиме (без оптимизаций) составило 16 %.
Был выполнен стандартный бенчмарк на коммите, помеченном как 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 % является достоверным.
Замеры:
-
Ускорение работы компилятора в некоторых режимах:
- незначительное в режиме
-OD
: 5,5 %; - существенное в режиме
-OR
: примерно в 3 раза; - существенное в режиме
--log=filename.log
: примерно в 2 раза.
- незначительное в режиме
Флаги оптимизации
Добавлены пустые флаги: -OG
(глобальная оптимизация) как задел на будущее, экспериментальные -Ox
, -Oy
, -Oz
, которые нужны для удобства отладки (их можно поместить глобально в RLMAKE_FLAGS
и вызывать makeself-s.*
).
Улучшения отчёта профилировщика функций (#194)
- Вывод единиц измерения времени для функций (ms).
- Подсчёт относительной продолжительности шага функции (по отношению к продолжительности среднего шага). Величина много больше единицы означает, что функция работает медленно — содержит открытые, повторные или копируемые переменные, либо это функция ввода-вывода.
- Для функций учитываются их области видимости — одноимённые локальные функции считаются раздельно. Теперь если в отчёте видно, что, скажем
Map@3
выполняется долго, можно понять — из какой она единицы трансляции.
Исправлены ошибки
- Не выполнялась прогонка и встраивание в аргументах косвенных вызовов функций (#277).
- Мелкая ошибка в режиме
-OS
при специализации функций с условиями. - Мелкая ошибка анализе флагов оптимизации в командной строке.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-3.0.1.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-3.0.1.zip
или bootstrap-refal-5-lambda-3.0.1.tar.gz
)
Рефал-5λ, версия 3.0
Наконец-то завершён переход от Простого Рефала к Рефалу-5λ!
Удалены последние артефакты Простого Рефала, можно закрывать https://github.com/bmstu-iu9/refal-5-lambda/milestone/6 и устанавливать номер версии 3.0!
- Удалены устаревшие функции Простого Рефала (#58). Они или дублировали аналогичные встроенные функции, или имели неудачное имя, или были не нужны. Список удалённых функций:
FOpen
(переименована вOpen-Auto
),FClose
,FReadLine
,FWriteLine
,FReadBytes
(переименована вReadBytes
),FWriteBytes
(переименована вWriteBytes
),ReadLine
,WriteLine
,IntFromStr
,FastIntFromStr
,StrFromInt
,- комбинатор неподвижной точки
Y
, MapReduce
,Seq
(они были синонимами дляMapAccum
иPipe
соответственно).
- Удалены устаревшие утилиты командной строки (в скобках указаны новые имена) (#69):
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
. -
Специализатор осуществлял подстановки переменных не параллельно (независимо), а последовательно, из-за чего порождал неправильный код на некоторых примерах.
-
Неправильно определялся случай тривиальной сигнатуры (#262), из-за чего снижалась глубина оптимизации.
Сигнатурой называется подстановка статических параметров для вызова специализируемой функции. Тривиальная сигнатура — подстановка-переименовка, вызов с тривиальной сигнатурой оптимизировать нет смысла.
По ошибке считалось, что тривиальная сигнатура — подстановка, просто отображающая переменные на переменные. Из-за этого не оптимизировались те вызовы, которые, тем не менее, оптимизировать можно.
-
Специализатор теперь умеет оптимизировать вызовы с активными статическими аргументами (#245).
Изначально специализатор мог оптимизировать, но делал это неправильно. В качестве временного решения оптимизация таких вызовов была запрещена.
-
При ошибке отождествления в экземпляре специализированной функции дамп отображается понятнее (#240). Упавший вызов выглядит как вызов функции
<Func@0 …>
, аргумент которой совпадает с тем аргументом, который был бы у функции<Func …>
без специализации. -
Если в предложении были и прогоняемые, и специализируемые вызовы, глубина оптимизации могла бы быть не полной (#263). Исправлено.
Исправление этой проблемы потребовало переработки архитектуры древесного оптимизатора, из-за чего изменился смысл опции
--opt-tree-cycles=N
. Ранее числоN
означало количество проходов оптимизации, каждый из них включал проход прогонки и проход специализации. Сейчас проходы прогонки и специализации считаются отдельно. -
Повышена производительность древесного оптимизатора. В прогонщике найдены ошибочные повторные переменные. После прохода специализации оптимизированные функции помечаются как «холодные» и на последующих проходах игнорируются.
Добавлен синтаксис безымянных переменных (#258).
- Безымянная переменная — переменная, индекс которой начинается на
_
:e._
,t._A
,s.__
… - Безымянные переменные допустимы только в образцовых выражениях.
- Каждая такая переменная неявно получает новое уникальное имя, поэтому повторными они быть не могут. Например, сопоставление
'ab' : s._ s._
всегда успешно. - Синтаксис
e._x^
(безымянная переменная со знаком сокрытия) запрещён, поскольку бессмысленный.
Изменена реализация метафункций (#254). Теперь компилятор поддерживает ключевое слово $META
, определяющее метафункцию. Метафункция, объявленная как $META Foo;
, неявно вызывает внешнюю функцию __Meta_Foo
, передавая ей свой аргумент и таблицу функций текущей области видимости. Функции Mu
и Residue
переписаны через этот механизм.
Компилятор поддерживает флаги оптимизации -Oi
(оптимизация intrinsic-функций) и -OA
(автоматическая расстановка меток $DRIVE
, $INLINE
и $SPEC
). На данный момент сами оптимизации не реализованы, ключи добавлены для возможности раскрутки следующей версии при помощи текущей.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-3.0.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-3.0.zip
или bootstrap-refal-5-lambda-3.0.tar.gz
)
Рефал-5λ, версия 2.6
Интерпретатор, исправления ошибок, мелкие изменения
-
Даниил Гавриловский (@GDVFox) подготовил плагин для Visual Studio Code, инструкция по установке находится в
editors/README.md
(#269). -
Анастасия Кузнецова (@suova) исправила огромное количество ошибок в переводах документации на английский язык (#270, #272, #274).
-
Исправлена ошибка некорректной загрузки модулей, если модуль ссылался на себя по псевдониму (#266).
-
Скомпилированные библиотеки лежат не в
/bin
, а в/lib
(#76). -
Путь к папке
/lib
в инсталляторах прописывается вRL_MODULE_PATH
. -
Программы зависали, если переменная
RL_MODULE_PATH
содержала более одной папки (#76, #100).
• В релизных сборках физически отсутствует диагностический код (#261). Соответственно, ранее в релизных сборках (без ключа--debug
) выполнялось профилирование (и не только), но результат распечатать было невозможно. Теперь лишних действий не выполняется, программы, собранные без диагностики примерно на 10 % быстрее программ, собранных с диагностикой. -
Написан интерпретатор, аналог
refgo
классического Рефала-5 (#48). Интерпретатор называется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
(#58). -
Для функций
FOpen
,FReadBytes
,FWriteBytes
созданы синонимы, соответственно,Open-Auto
,ReadBytes
,WriteBytes
(#58). -
**Функции
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). В следующем релизе они будут удалены. - Компилятор называется
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-2.6.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-2.6.zip
или bootstrap-refal-5-lambda-2.6.tar.gz
)
Рефал-5λ, версия 2.5
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-модули (
.dll
,.so
): их генерация и загрузка. -
Для стандартных библиотек
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. -
Префикс
rich(-debug).lib-prefix
, содержащийLibraryEx
,Hash
иGetOpt
. -
ИСПРАВЛЕНО: компилятор падал при наличии файла
filename.cpp
при отсутствииfilename.rasl
. -
Модуль может быть сам себе псевдонимом: допустима ситуация, когда модуль содержит и псевдоним
--incorporated=…
и ссылку с тем же именем. -
Скрипты
srefc(.bat)
иsrmake(.bat)
поддерживают новые ключи (в соответствии с #87):- ключи
--slim
,--rich
,--scratch
определяют префикс или его отсутствие, - ключи
--static
,--dynamic
,--auto
определяют компоновку с библиотекамиLirbraryEx
иGetOpt
: статическая, динамическая и по умолчанию (статическая для исполнимых файлов, динамическая для библиотек), - ключи
--debug
,--no-debug
включают и отключают компоновку с отладочными средствами, по умолчанию отладка отключена.
Эти ключи должны быть первыми параметрами srefc и srmake, их может следовать неограниченное количество, последние имеют приоритет.
- ключи
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-2.5.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-2.5.zip
или bootstrap-refal-5-lambda-2.5.tar.gz
)
Рефал-5λ, версия 2.4.2
Багфиксы, библиотека Platform
- Исправлена ошибка, препятствующая раскрутке компилятора под Linux.
- Уточнён вывод команды
--help
вsrefc-core
иsrmake-core
. - Библиотека
Platform
, совместимая с refal-5-framework, содержит платформенно-зависимые константы (разделитель каталогов, разделитель путей вPATH
). - Незначительное ускорение компиляции рантайма в режиме
--scratch
.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-2.4.2.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-2.4.2.zip
или bootstrap-refal-5-lambda-2.4.2.tar.gz
)
Рефал-5λ, версия 2.4.1
Багфиксы
- Вместо
--rename-exist-rasls
используется--overwrite-exist-rasls
(аналогично, вместо--dont-rename-…
—--dont-overwrite-…
). - Компилятор некорректно работал с опциями
--(dont-)keep-rasls
,--temp-dir=…
,--(dont-)overwrite-exist-rasls
. Сейчас работает корректно, но всё равно их игнорирует. - SRMake полностью поддерживает опции
--keep-rasls
,--dont-keep-rasls
,--temp-dir=…
,--overwrite-exist-rasls
,--dont-overwrite-exist-rasls
— в сущности, их просто пробрасывает вsrefc-core
. Также поддерживает (но игнорирует)--ref5rsl
. - В директивах
$SPEC
не работали квадратные скобки. - Теперь при одновременном указании
$SPEC
и$INLINE
/$DRIVE
для функции выдаётся сообщение об ошибке. Ранее в подобной ситуации$SPEC
молча игнорировался.
Для установки на Windows скачайте и запустите файл setup-refal-5-lambda-2.4.1.exe
.
Для установки на Linux и macOS выполните в терминале следующую команду:
curl -L https://bmstu-iu9.github.io/refal-5-lambda/setup.bash | bash
При этом на компьютере должен быть установлен компилятор GCC C++ или Clang.
Либо программу можно собрать из исходников (архивы bootstrap-refal-5-lambda-2.4.1.zip
или bootstrap-refal-5-lambda-2.4.1.tar.gz
)