Содержание


Bigloo — компилируемая модификация языка Scheme: Часть 1. Общий обзор

Comments

Серия контента:

Этот контент является частью # из серии # статей:

Следите за выходом новых статей этой серии.

Этот контент является частью серии:

Следите за выходом новых статей этой серии.

Каждому, кто в той или иной степени имел дело с языком программирования Scheme (одним из вариантов реализации Lisp), наверняка хорошо известны интерпретаторы DrScheme и Guile. Но существует ещё и компилятор Scheme под названием Bigloo. Вот о нём-то и пойдёт речь в данной серии статей.

1. Общая характеристика Bigloo

Итак, Bigloo представляет собой реализацию компилируемой версии языка программирования Scheme. И хотя автор компилятора Мануэль Серрано [Manuel Serrano] (сотрудник института исследований в области ИТ INRIA, Франция) декларирует "максимально возможное соответствие Bigloo стандарту R5RS (Revised(5) Report on the Algorithmic Language Scheme)", тем не менее, полного соответствия с обычным Scheme нет. Причина этого заключается в следующем: задачей Bigloo является не только создание обычных выполняемых файлов, но и обеспечение связывания генерируемых объектных файлов с файлами, созданными из исходных кодов на языках C, Java и языках платформы .NET. Таким образом, "на выходе" Bigloo может давать объектные файлы (".o" или ".obj"), связываемые с объектными C-файлами, файлы, содержащие байт-код JVM (".class"), которые могут взаимодействовать с обычными Java-классами, а также файлы классов платформы .NET, которые могут работать, например, в среде Mono.

1.1. Scheme-ядро компилятора

Несмотря на все сделанные выше примечания, функциональной основой компилятора Bigloo всё же является Scheme, то есть, основные переменные среды, функции и поцедуры. Кроме того, Bigloo поддерживает некоторые требования SRFI. Аббревиатура SRFI означает Scheme Request For Implementation, то есть документы SRFI определяют синтаксические и процедурные требования к реализации расширений в соответствии со стандартом Scheme R5RS. Ознакомиться с SRFI-документами во всех подробностях можно на специальной странице SRFI.

Рассматриваемая в данной статье версия 3.2b Bigloo поддерживает следующие SRFI:

  • srfi-0 - ветвление потока выполнения по результатам проверки условий.
  • srfi-2 - реализация конструкции and-let* - последовательное присваивание (связывание переменных с значениями) с проверкой заданного условия и прекращением выполнения при получении в результате проверки логического значения "ложь" (#f).
  • srfi-6 - реализация основных процедур, необходимых для работы со строковыми портами open-input-string, open-output-string и get-output-string.
  • srfi-8 - receive - конструкция, предназначенная для упрощения работы с процедурами, возвращающими несколько значений.
  • srfi-9 - создание новых типов - записей - define-record-type.
  • srfi-18 - реализация многопоточности
  • srfi-22 - вызов интерпретатора скриптов
  • srfi-28 - основные (базовые) строки формата
  • srfi-30 - многострочные комментарии

2. Связь с языками C и Java

2.1. Интерфейс с языком программирования C

Одной из главных целей компилятора Bigloo является объединение программирования высокого уровня, которое может осуществляться в данном конкретном случае на языке Scheme, и программирования низкого уровня, которое обычно реализуется с помощью языка C. Именно поэтому Bigloo спроектирован таким образом, чтобы производимые им модули без затруднений стыковались с модулями, написанными на C.

Механизм объединения состоит из двух компонентов: интерфейс вызовов функций и интерфейс обращения к структурам данных. Из кода Bigloo могут быть вызваны C-функции и наоборот: функции C-программы могут обращаться к процедурам Bigloo. То же самое касается и структур данных - взаимный доступ обеспечен "в обоих направлениях".

2.2. Интерфейс с языком программирования Java

Компилятор Biloo способен генерировать байт-код для выполнения на виртуальной машине Java Virtual Machine (JVM). Результатом такой генерации являются обычные файлы классов (.class), которые могут быть интегрированы в Java-программу.

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

3. Особенности компиляции

3.1. Общие положения

Как и любой полноценный компилятор, Bigloo предоставляет возможность получить из исходного кода Scheme на выходе обычный выполняемый файл. Но "главным оружием" Bigloo является раздельная компиляция - генерация отдельных компонуемых модулей, а не готовых программ.

Вообще говоря, модуль является основной единицей компиляции в Bigloo. Сам по себе модуль состоит из объявления модуля (module declaration) и тела модуля (module body). Для упрощения тело модуля можно считать Scheme-программой, не подготовленной полностью к выполнению, в некотором роде "незавершённой".

Bigloo осуществляет строгий контроль связывания переменных и значений. Поэтому в теле модуля любое обращение к несвязанной (unbound) переменной является недопустимым.

В объявлении модуля некоторые переменные могут быть объявлены, как неизменяемые (immutable) функции. В дальнейшем для таких переменных компилятор проверяет количество передаваемых им аргументов при вызовах, и если обнаруживает несоответствие, то сообщает об ошибке и останавливает процесс компиляции.

3.2. Основные ключи компилятора

Перечень ключей компилятора Bigloo не столь обширен, как например, у gcc, но всё же достаточно велик. Поэтому я ограничусь здесь лишь кратким описанием наиболее часто используемых.

-help, --help - вывод краткой справочной информации по ключам bigloo

-help2 - вывод полной справочной информации по ключам bigloo

-help-manual - форматированный вывод полной справочной информации по ключам bigloo

-o имя_файла - вывод результата компиляции в заданный файл (по умолчанию a.out)

--to-stdout - запись сгенерированного C-кода в текущий открытый поток вывода

-c - отменить связывание (linking) и создать объектный (.o) файл

-suffix расширение - определить расширение файла исходного кода Scheme

-main имя_функции - определить имя main-функции (точки входа)

-with имя_модуля - импортировать дополнительный модуль

-library имя_библиотеки - компиляция/связывание с дополнительной библиотекой Bigloo

-srfi SRFI - объявление поддержки SRFI

-heapsize размер - задать начальный размер общедоступной памяти ("кучи") в мегабайтах

-I имя_каталога - добавить заданное имя каталога в путь поиска/загрузки

-L имя_каталога - задать дополнительный путь поиска библиотек

-native - скомпилировать модуль в объектный файл для текущей системы (через C)

-jvm - скомпилировать модуль в файл класса (.class) для JVM

-dotnet - скомпилировать модуль в объектный файл для среды .NET

-cc компилятор - определить используемый компилятор языка C

-stdc - генерировать C-код, строго соответствующий стандарту ISO C

-cgen - не выполнять компиляцию, а выдать файл с исходным кодом (.c)

-jvmas - сгенерировать .jas-файл для JVM

-il - сгенерировать .asm-файл (IL) для среды .NET

-rm|+rm - не удалять|удалять промежуточные .c или .il файлы

-w - запретить все предупреждающие сообщения

-Wall - разрешить все предупреждающие сообщения, в том числе предуреждения о возможных несоответствиях типов

-mklib - скомпилировать библиотечный модуль

-LICENSE - добавить информацию о лицензии Bigloo в генерируемые C-файлы

Кроме описанных выше имеются солидные наборы ключей для конфигурирования, оптимизации, отладки и профилирования, трассировки, а также специализированные комплекты ключей для управления режимами native (создание объектных файлов), JVM и .NET.

3.3. Подробнее о модулях

Модули являются "строительными блоками, кирпичиками", из которых компонуется итоговый выполняемый файл (программа). Модуль может быть размещён в нескольких отдельных файлах, но один файл может содержать только один модуль, не более.

Имя модуля никак не связано с именем содержащего его файла. Просто зачастую удобнее давать файлам имена модулей, хранящихся в них. Но это не является обязательным требованием.

Как уже было отмечено ранее, модуль состоит из объявления и тела. Объявление (declaration) обязательно должно быть самым первым выражением, записанным в начале файла, содержащего данный модуль (если файлов несколько, то в начале стартового файла модуля). Все последующие выражения формируют тело модуля.

3.3.1. Объявление модуля

Объявление модуля записывается в формате

(module имя [директива ...])

Имена различных модулей не должны быть одинаковыми - обнаружив совпадающие имена двух различных модулей, Bigloo выдаст сообщение об ошибке.

Вот пример простейшего модуля:

(module mod01)
(display "Минимальный модуль")

Первая строка содержит корректное объявление модуля. Вторая строка представляет тело модуля. Если сохранить эти две строки в файле с именем mod01.scm, то мы получим исходный код полноценной Bigloo-программы. Убедиться в этом нетрудно - см.рисунок 1.1.

Рис.1.1. Компиляция и выполнение простейшей Bigloo-программы
Рис.1.1. Компиляция и выполнение простейшей Bigloo-программы
Рис.1.1. Компиляция и выполнение простейшей Bigloo-программы

3.3.2. Директивы в объявлении модуля

Кроме ключевого слова module и собственно имени модуля в объявлении могут содержаться необязательные директивы.

Директива

(main имя)

определяет точку входа в программу - процедуру с заданным именем. После компиляции именно с этой процедуры будет начинаться выполнение программы и в эту процедуру будут переданы аргументы командной строки в форме списка строк.

На практике это будет выглядеть приблизительно так:

(module mod02
  (main start))
(define (start argv)
  (display argv)
  (newline))

Сохраним этот код в файле mod02.scm, а при компиляции воспользуемся ключом -o, позволяющим задать имя итогового выполняемого файла вместо "a.out" - см.рисунок 1.2.

Рис.1.2. Определение точки входа и передача аргументов командной строки
Рис.1.2. Определение точки входа и передача аргументов командной строки
Рис.1.2. Определение точки входа и передача аргументов командной строки

Разумеется, имя самого выполняемого файла также входит в список принятых аргументов командной строки, как первый элемент этого списка.

Директива

include имя_файла ...

позволяет включить файл или несколько файлов с заданными именами в текущий исходный файл. Включаемые файлы не являются модулями - в определённой степени их можно считать аналогами h-файлов в C-программах - и в некоторых случаях могут содержать специальные синтаксические конструкции. В самом простом случае эти файлы можно использовать для включения не зависящих от конкретной реализации Scheme-выражений и определений в исходный код модуля. Пример включаемого файла:

; pt-str.sch - включаемый файл
(define-struct point x y)

и модуля, который содержит директиву включения этого файла:

; mod03.scm - использует включаемый файл
(module mod03
  (include "pt-str.sch"))
(print (point 11 16))

Результат выполнения можно наблюдать на рисунке 1.3.

Рис.1.3. Использование включаемого файла в модуле
Рис.1.3. Использование включаемого файла в модуле
Рис.1.3. Использование включаемого файла в модуле

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

Конечно, список директив не ограничивается рассмотренными выше main и include. Но все прочие директивы лучше изучать в контексте их реального практического использования. А мы, пожалуй, на этом завершим наше краткое теоретическое знакомство с компилятором Bigloo.

4. Заключение

При первом взгляде на компилятор Bigloo становится очевидной одна из основных целей его применения - подготовка и генерация файлов-модулей, которые не являются законченными программами, а представляют собой элементы, используемые при сборке C, Java или .NET-приложений.

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


Ресурсы для скачивания


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=505275
ArticleTitle=Bigloo — компилируемая модификация языка Scheme: Часть 1. Общий обзор
publish-date=08052010