Skip to content

Mazdaywik/Refal-05

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Компилятор Рефала-05

О языке и компиляторе

Рефал-05 — подмножество Рефала-5 и альтернативная реализация Рефала-5, компилирующаяся в C89.

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

Ставились следующие цели разработки:

  • Совместимость с Рефалом-5 — должно быть точное подмножество, как описано выше, подмножество должно быть максимально полным, насколько это не противоречит другим целям.
  • Компиляция в язык C89 и расширяемость — можно писать собственные функции на Си и вызывать их из кода на Рефале.
  • Минималистичность — в реализации следует избегать сложных конструкций и алгоритмов, всё, по возможности, должно быть компактно и просто.
  • Эффективность — в реализации следует избегать намеренно неэффективных конструкций.
  • *Самоприменение — компилятор написан на себе.
  • Практичность — это не тестовый стенд для экспериментов по компиляции, это полноценный компилятор Рефала, который можно использовать при написании собственных программ.
  • Прозрачность — реализация должна быть тщательно документирована, исходники максимально прозрачными и понятными. Реализация может служить учебным пособием по реализации Рефала.
  • Педантичность — компилятор выдаёт синтаксические ошибки на неиспользуемые функции и внешние ссылки, форматы встроенных функций могут быть строже, чем у Рефала-5.

Отличия от Рефала-5

  • На данный момент поддерживаются не все встроенные функции (полный перечень в документации), большинство из них малоизвестные (их нет в учебнике Турчина) или редкоиспользуемые (функции по работе с метакодом).
  • Есть тонкие отличия в семантике метафункций — можно привести пример программы на Рефале-5, которая не будет работать в Рефале-05. Ограничение несущественное, т.к. в большинстве программ такие тонкости не используются. Подробности и примеры см. в документации.
  • Нет поддержки длинной арифметики — аргументы арифметических функций должны содержать одну макроцифру, результат Numb должен влезать в одну макроцифру, иначе ошибка времени выполнения.
  • Входная точка — всегда GO. Если вы компилируете программу со входной точкой Go, добавьте модуль Go.c к списку исходников вашей программы.

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

Преимущества:

  • Расширяемость — можно писать собственные функции на Си и вызывать их из Рефала.
  • Эффективность — компиляция не в байткод, а в Си, бо́льшая скорость выполнения.
  • Переносимость — поддерживается Windows и unix-подобные операционные системы.
  • Педантичность — дополнительные семантические ограничения способствуют более чистому коду ваших программ (если для вас это недостаток, значит, вы — говнокодер и компилятор не для вас).

Недостатки:

  • Зависимость от компилятора Си — без установленного компилятора Си нельзя собрать программу.
  • Неполное подмножество Рефала-5, о чём говорилось выше.

Установка и использование

Для раскрутки компилятора у Вас должен быть установлен Рефал-5 версии PZ Oct 29 2004, набор библиотек для Рефала-5 refal-5-framework, а также компилятор языка Си89.

Установка набора библиотек «refal-5-framework»

Установите библиотеки репозитория Mazdaywik/refal-5-framework согласно инструкции в его README.

Раскрутка на Windows

  • Запустите файл bootstrap.bat. Cкрипт развёртки создаст файл c-plus-plus.conf.bat и сообщит о том, что не указан компилятор языка Си.
  • Отредактируйте файл c-plus-plus.conf.bat (да, я его скопировал у Рефала-5λ и забыл переименовать), указав в нём командную строку для запуска компилятора (см. инструкции в самом файле).
  • Запустите ещё раз bootstrap.bat — компилятор должен успешно собраться и должны выполниться все автотесты (часть автотестов сообщают об ошибках синтаксиса, это так и должно быть).

Раскрутка на POSIX (Linux, macOS)

Если у Вас установлен компилятор 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!

Как-то так.

Замечание о дереве коммитов

За основу были взяты ранние коммиты Простого Рефала, но чутка переписаны.

  • Все исходники были конвертированы в UTF-8, включая самый нижний коммит.
  • Приписана правильная история к метке 003.
  • Из истории удалены коммиты интерпретируемого представления, разработанного Игорем Дрогуновым. Я решил, что лучше очистить историю (сделав её более «прямой»), чем оставлять те правки, которые потом всё равно удалятся.

Исходную историю и исходные коммиты можно найти в репозитории Рефала-5λ.

Лицензия

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