РЕкурсивных Формул АЛгоритмический является одним из старейший языков программирования. Создал его в 60-х годах прошлого столетия Валентин Фёдорович Турчин. С тех пор вышел ряд отличающихся синтаксисом и семантикой версий. Интересующимся рекомендуется ознакомиться со сравнением, которое составил ведущий разработчик компилятора Рефал-5λ Александр Коновалов.
Рефал-машина предназначена для исполнения написанных на РЕФАЛ сценариев (на данный момент поддерживается Базисный РЕФАЛ, за исключением нескольких встроенных функций) в ОС Linux. Реализована на яыке Си и имеет минимум зависимостей (в том числе от стандартной библиотеки Си). Представляет собой (потенциально) встраиваемый интерпретатор, предварительно транслирующий исходный текст в байт-код, который и исполняется. Трансляция выполняется в один проход, однако, поддерживается традиционный для РЕФАЛ произвольный порядок определения функций.
Основные отличия:
-
Поддержка кириллицы (и практически любых Уникод-сомволов) в идентификаторах.
-
Префиксы
s.
t.
иe.
переменных могут быть соответственно?
!
и.
или…
-
Начинающиеся с
$
директивы упразднены (добавлена поддержка модулей). -
В вычислительных скобках
< >
имя вызываемой функции не обязательно должно идти непосредственно после открывающей скобки, перед ним можно расположить данные или простой идентификатор. Транслятор знает, что можно вызвать. Это же послабление относится и к функцииMu
, которая выполняет поиск вызываемой функции среди аргументов во время выполнения (пропуская структурные скобки). -
Помимо точки входа
Go
возможно использоватьMain
, которая принимает в поле зрения аргументы командной строки (каждый заключён в структурные скобки, как в результатеArgList
из LibraryEx). Кроме того, поддерживается точка входаНачало
— в таком случае интерпретатор проверяет, содержит ли первое её предложение образец, надо ли передавать аргументы. Допустимы вышеперечисленные имена, начинающиеся со строчной буквы — результат их исполнения выводится, а не отбрасывается. -
Поддержаны функции из одного предложения, без блока
{ }
.// Допустимы комментарии в одну строку в стиле С++ * Вариант классической РЕФАЛ-программы. Начало = <Палиндром? <удалить пробелы "я разуму уму заря ">> <Палиндром? <удалить пробелы "я иду съ мечемъ судия">>; * Гавриил Державин Палиндром? { ?символ … ?символ = <Палиндром? …>; ?символ = <Вывод "Палиндром">; = <Вывод "Палиндром">; … = <Вывод "Остаток: "…>; } удалить { пробелы .символы " " .остаток = .символы <удалить пробелы .остаток>; пробелы … = …; } * явное определение не обязательно. пробелы; Вывод . = <Prout .>;
Для вызова функций, реализованных в другой единице трансляции (модуле), следует импортировать модуль явно. Для чего указывается имя модуля, завершаемое двоеточием:
Модуль: функция1 функция2;
РЕФАЛ-машина ищет реализацию модуля в файлах Модуль.реф
и Модуль.ref
.
Указанные в команде импорта идентификаторы вносится в текущую область пространства
имён. Остальные идентификаторы модуля так же доступны, если их имя предварительно
квалифицировать именем модуля:
* Импортируем идентификаторы тест1 и тест2 из файла "Модуль1.реф"
Модуль1: тест1 тест2;
go = <тест1> <тест2>
* Вызов по полному имени.
<Модуль1 тест3>;
На текущем этапе интерпретатор способен исполнять компилятор Refal-05 после адаптации его исходных текстов.
Нижеприведённые данные не претендуют на результаты измерений (погрешность не определялась) и предоставлены в качестве грубой оценки.
Интерпретатор версии 0.1.4 собран командой make clean all
при помощи gcc (Gentoo 10.3.0 p1) без оптимизации под архитектуру процессора. Этот же gcc используется при компиляции refal05c с -O2. Запуск на процессоре Zen+ 3,6ГГц.
Запуск под интерпретатором (лишний вывод вырезан)
$ time R05CCOMP= refal src/refal05c.ref \
Refal-05/src/refal05c \
Refal-05/src/R05-AST \
Refal-05/src/R05-CompilerUtils \
Refal-05/src/R05-Lexer \
Refal-05/src/R05-Parser \
Refal-05/src/R05-Generator \
Refal-05/src/LibraryEx \
Library refal05rts
real 0m1,941s
user 0m1,935s
sys 0m0,003s
Запуск откомпилированного refal05c
$ time R05CCOMP= refal05c \
Refal-05/src/refal05c \
Refal-05/src/R05-AST \
Refal-05/src/R05-CompilerUtils \
Refal-05/src/R05-Lexer \
Refal-05/src/R05-Parser \
Refal-05/src/R05-Generator \
Refal-05/src/LibraryEx \
Library refal05rts
real 0m0,598s
user 0m0,196s
sys 0m0,401s
Исходный текст: lambda.ref
Интерпретация:
$ time echo 5 | refal lambda.ref
Enter a number:
120
real 2m47,046s
user 2m46,415s
sys 0m0,014s
Скомпилировано Рефал-05 (refal05c lambda.ref Library refal05rts
и переименовано)
$ time echo 5 | ./lambda-05
Enter a number:
120
real 3m32,260s
user 3m30,360s
sys 0m1,193s
Скомпилировано Рефал-5λ (rlc lambda.ref -o lambda-5λ
)
$ time echo 5 | ./lambda-5λ
Enter a number:
120
real 3m31,053s
user 3m30,366s
sys 0m0,030s
Исходные тексты: кириллический и Базисный Рефал
$ time ./простые.реф > /dev/null
real 0m0,944s
user 0m0,943s
sys 0m0,000s
$ time ./primes5-05 > /dev/null
real 0m4,646s
user 0m1,381s
sys 0m3,258s
$ time ./primes5-5λ > /dev/null
real 0m3,604s
user 0m3,591s
sys 0m0,004s
Компиляция в байт-код при помощи Refal-5 Compiler. Version PZ Oct 29 2004 с последующим исполнением. 32-х разрядные исполняемые файлы, wine-6.9 (Staging).
$ time ./REFC.EXE primes5.ref
real 0m0,270s
user 0m0,074s
sys 0m0,056s
$ time ./REFGO.EXE primes5.rsl > /dev/null
real 0m4,016s
user 0m0,062s
sys 0m0,074s