Рефал-05 — минималистичный самоприменимый компилятор минималистичного диалекта Рефала, имеющий общее подмножество с классическим Рефалом-5. На этом подмножестве он и написан.
Ставились две цели разработки:
Удалось достичь объёма исходного кода примерно в 6000 строк, включая исходники компилятора, библиотеки встроенных функций, рантайма и скриптов сборки. И, по мнению автора, это минимум. Формально код можно уменьшить, сократив имена переменных и функций, но это пагубно сказалось бы на стиле исходного кода, ведь подразумеваемой целью были также понятные и прозрачные исходники.
Также целью было сделать не игрушку, вещь в себе, которая может только самоприменяться, но и сохранить возможности практического инструмента. Об этом в разделе «Установка и использование».
Разработка велась на основе старой версии Простого Рефала путём как отсечения избыточных возможностей, так и путём подгонки синтаксиса к Рефалу-5. Поэтому архитектурно и идейно он наследует Простой Рефал. Причём даже, по духу и идее он близок к Простому Рефалу версии 001, только при этом совместим с Рефалом-5 и в исходниках существенно меньше говнокода.
<s.Func e.Arg>
.$ENUM
(локальная) и $EENUM
(entry):
$EENUM FloatType, IntegerType, CharType, StringType;
*$СЛОВО
и СЛОВО
является корректным ключевым словом, то текст комментария считается
кодом на Рефале (в конце строки неявная ;
). Предыдущую строку можно
записать как
*$EENUM FloatType, IntegerType, CharType, StringType
Т.е. этот «комментарий» определит четыре пустые функции.
unsigned long int
для используемого
компилятора.Add
, Compare
, Div
, Mod
, Mul
, Sub
— как уже
сказано, беззнаковая и без контроля переполнения,Chr
, Explode
, Numb
, Ord
, Symb
,
Type
— функция Explode
возвращает имя для заданной функции,
функция Numb
не проверяет переполнение,Card
, Get
, Open
, Prout
, Putout
, Close
,
ExistFile
,Arg
, GetEnv
, Exit
, System
,Mu
— просто вызывает функцию по указателю,Br
, Dg
,First
,ListOfBuiltin
, возвращающая список встроенных функций (она есть
и в Рефале-5 тоже).Из соображений минимализма оставлены только те функции, которые реально
используются в компиляторе. Единственное исключение — функция Card
.
Потому что Рефал без поддержки перфокарт — это ущербный Рефал.
Для раскрутки компилятора у Вас должен быть установлен Рефал-5 версии
PZ Oct 29 2004
, набор библиотек для Рефала-5 refal-5-framework,
а также компилятор языка Си89.
Установите библиотеки репозитория Mazdaywik/refal-5-framework согласно инструкции в его README.
bootstrap.bat
. Cкрипт развёртки создаст файл
c-plus-plus.conf.bat
и сообщит о том, что не указан компилятор языка Си.c-plus-plus.conf.bat
(да, я его скопировал у Рефала-5λ
и забыл переименовать), указав в нём командную строку для запуска компилятора
(см. инструкции в самом файле).bootstrap.bat
— компилятор должен успешно собраться
и должны выполниться все автотесты (часть автотестов сообщают об ошибках
синтаксиса, это так и должно быть).Если у Вас установлен компилятор GCC (или Clang на macOS), то достаточно первого шага:
./bootstrap.sh
. В этом случае тоже будет создан файл
c-plus-plus.conf.sh
, где по умолчанию будет указан компилятор gcc
,
всё должно собраться (некоторые автотесты сообщат о синтаксических ошибках,
это так и должно быть).Если у Вас GCC не установлен, или для раскрутки желаете использовать другой
компилятор, то нужно будет отредактировать файл c-plus-plus.conf.sh
и запустить ./bootstrap.sh
повторно.
После раскрутки будет создана папка bin
, в которой будет располагаться
исполнимый файл refal05c.exe
(или refal05c
). Его уже можно запускать.
Если его вызвать с именем исходного файла, он скомпилирует его в исходник
на Си. Но, чтобы получать с его помощью получать исполнимые файлы, выполните
следующие действия:
PATH
путь к папке bin
данного дистрибутива.
Тогда компилятор можно будет запускать из любой папки.R05CCOMP
с командной строкой запуска
компилятора Си. Например, gcc -Wall -O3 -g
, cl /EHcs /W3 /wd4996 /O2
,
bcc -w
. Когда эта переменная установлена, refal05c
будет вызывать
сишный компилятор после генерации исходников.R05PATH
, указав в ней через точку с запятой
(Windows) или двоеточие (unix-like) пути к папкам lib
и src
этого каталога. Например:
set R05PATH=C:\Refal-05\lib;C:\Refal-05\src
или
export R05PATH="~/Refal-05/lib:~/Refal-05/src"
В этом случае компилятор сможет находить и подключать библиотеки (рантайм и встроенные функции).
Примечание. На POSIX-системах (Linux или macOS) в переменную R05CCOMP
желательно добавлять -DR05_POSIX
(например, gcc -DR05_POSIX
) — в этом
случае функция System
будет корректно возвращать код возврата. Без данного
флага работать всё равно всё будет, только System
будет возвращать сырое
значение функции system
языка Си, которое может отличаться от фактического
кода возврата (см. man 2 wait
для более подробных сведений).
Классический пример — Hello, World!:
$ENTRY Go {
= <Prout 'Hello, World!'>
}
Сохраните этот текст в файл hello.ref
и выполните в командной строке команду
refal05c hello refal05rts Library
Здесь hello
— это имя нашего исходника (расширение .ref
здесь можно
не писать), refal05rts
— библиотека поддержки времени выполнения (на жаргоне —
«рантайм»), содержит функции, которые вызываются из сгенерированного кода,
и Library
— библиотека со встроенными функциями Рефала (той же Prout
).
В результате в текущей папке должен появиться файлик hello.c
— результат
компиляции в Си и исполнимый файл, который, в зависимости от операционной
системы и компилятора Си, может называться hello.exe
, a.exe
или a.out
.
Примечание. Некоторые компиляторы языка Си оставляют после себя мусор
из объектных файлов (.obj
) и других служебных файлов (.tds
, .pch
и т.д.), этот мусор можно (и нужно) удалять. Также можно удалить hello.c
.
Теперь мы можем запустить программу и увидеть что-то вроде:
Hello, World!
Как-то так.
За основу были взяты ранние коммиты Простого Рефала, но чутка переписаны.
003
.Исходную историю и исходные коммиты можно найти в репозитории Рефала-5λ.
Компилятор распространяется по двухпунктной лицензии BSD с оговоркой относительно компонентов стандартной библиотеки и рантайма — их можно распространять в бинарной форме без указания копирайта. При отсутствии данной оговорки для скомпилированных программ пришлось бы указывать копирайт самого компилятора, что неразумно.