среда, 20 октября 2010 г.

Hello, Word на Модульном Рефале

По традиции начнём изложение языка с написания простейшей программы на этом языке. Для этого создадим текстовый файл с именем Hello.mref (расширение файлов исходного текста Модульного Рефала — .mref) со следующим содержанием:

$PROGRAM Hello;

/*
  Эта программа выводит на экран строку Hello, World!
*/

$IMPORT MInOut;

$ENTRY Go {
  // Вывод строки на экран
  = <MInOut::WriteLine 'Hello, World!'>;
}

$END Hello.
Программа на Модульном Рефале состоит из модулей. Каждый модуль может начинаться с ключевого слова $PROGRAM или $MODULE. Модуль, помеченный как $PROGRAM, является головным модулем — он должен присутствовать в любой программе и при этом в единственном экземпляре. Такие модули нельзя импортировать. Модули, которые помечены как $MODULE, импортировать можно и даже нужно, т.к. других способов ими воспользоваться нет. Такие модули называются регулярными.

Имя модуля всегда должно совпадать с именем файла исходного текста, иначе компилятор не сможет их найти.

Строка $IMPORT MInOut; означает, что в этом модуле используются возможности из модуля MInOut — библиотечный модуль для консольного ввода-вывода.

В нашем примере программа состоит из головного модуля Hello и регулярных модулей, содержащих реализации библиотечных функций ввода-вывода, включающих в себя модуль MInOut, а также модули, которые MInOut импортирует. Библиотечные модули компилятор находит самостоятельно, программисту заботиться о них не нужно.

Дальше располагается определение функции Go. Ключевое слово $ENTRY перед именем функции делает функцию экспортируемой (далее по тексту entry-функцией), то есть её можно вызывать извне данного модуля. Функции без ключевого слова называются локальными, к ним можно обращаться только из других функций этого модуля (хотя entry-функция может вернуть указатель на такую функцию, но создать указатель на функцию можно только внутри модуля).

Любая программа на Модульном Рефале начинает своё выполнение с вызова функции Go, определённой в головном модуле программы (в главе, посвящённой модулям, описаны исключения из правила). Она всегда должна объявляться как entry, так как вызывается извне модуля (библиотекой поддержки времени выполнения) с пустым аргументом.

Функция на Рефале представляют собой набор предложений вида образцовое_выражение = результатное_выражение;, ограниченный фигурными скобками. В данном случае функция состоит из одного предложения с пустым образцовым выражением и с результатным выражением <MInOut::WriteLine 'Hello, World!'>.

Примечание. В разделе, посвящённом Модульному Рефалу, для краткости под Рефалом будет подразумеваться Модульный Рефал, если это не оговорено особо; в разделе, посвящённом Простому Рефалу — Простой Рефал.

Результатное предложение состоит из единственного вызова функции WriteLine, определённой в модуле MInOut с аргументом 'Hello, World!'. Вызовы функций на Рефале записываются в угловых скобках, если функция импортируется из модуля, то перед ней всегда указывается имя модуля, отделённое от имени функции квадроточием (так называемое квалифицированное имя).

Модуль завершается ключевым словом $END, после которого снова следует имя модуля. Имена, указанные в начале модуля и в конце, должны совпадать. Модуль завершается символом точки. Такой синтаксис был заимствован из языков Модула-2 и Оберон-2.

Как уже догадались читатели, программирующие на языках с C-подобным синтаксисом, текст между /* и */ является многострочным комментарием, а после // — однострочным комментарием (который заканчивается в конце строки).

Для компиляции такой программы запустите в командной строке (о том, как установить компилятор, рассказывается в Приложении А).

compile_mr -profile:C++/SR -make Hello.mref

Заклинание сие означает, что будет использован back-end, генерирующий код на C++, совместимый с Простым Рефалом и компиляция модулей будет произведена по необходимости (подробнее в главе, посвящённой процессу компиляции). В результате должен появиться исполнимый файл Hello.exe, который при запуске выводит на консоль строчку Hello, World!.