Д.А. Швец, А.И. Легалов © 2005
Исходные тексты используемого примера программы ~1.5 Кб
Язык программирования О2М расширяет своего предшественника (Оберон-2) методами процедурно-параметрического программирования. Он реализует большинство возможностей языка Оберон-2 [1], что позволяет использовать ранее написанные модули. В большинстве систем программирования, существующих для языков Оберон и Оберон-2, используется раздельная компиляция модулей в динамически подгружаемые компоненты. Система программирования на языке О2М также осуществляет раздельную компиляцию модулей, но затем делает их статическую компоновку. Подобное различие обуславливается тем, что одной из основных задач выполняемого проекта является исследование методов связывания эволюционно расширяемых программных объектов на ранних стадиях сборки программы. Не существует принципиальных сложностей в замене статической компоновки на динамическую. Принятое решение определяет специфику создания исполняемого файла, являющегося монолитом, собранным из всех модулей, включенных в проект. Свои особенности накладывает и реализация генератора кода, порождающего исходный текст на языке C++.
Для практической апробации процедурно-параметрической парадигмы разработаны транслятор O2M, компоновщик Link2M, утилита Make2M [2].
В среде MS Windows дополнительно реализована оболочка пользователя Pro2M, облегчающая создание многомодульных проектов и их трансляцию. Однако в представленном материале использование этой оболочки не рассматривается. Показано, как осуществить запуск всех утилит из командной строки, что позволяет единообразно работать как в среде MS Windows, так и Linux.
Представленные утилиты обычно располагаются в специально выделенном каталоге, имя которого, в общем случае, может выбираться произвольно. Желательно также прописать путь по умолчанию к этому каталогу.
Например, под ОС MS Windows мы размещаем систему программирования в каталоге o2m. При этом дополнительно используются следующие подкаталоги:
-
каталог «bin» с транслятором, многофункциональной графической оболочкой и обработчиком проекта;
-
каталог «Import» с библиотеками, используемыми при разработке программ (ввода-вывода, математической, обработки строк символов и другими).
Так как доступ к каталогу Import задается в файле проекта разрабатываемой программы, его размещение возможно в любом месте. Каталог с примерами программ на O2M тоже можно размещать в произвольном месте.
При работе с ОС Linux транслятор, компоновщик и обработчик проекта можно разместить в пользовательском или системном каталоге bin, путь к которому обычно прописан в начальных настройках.
Структура проекта программы
Для того, чтобы трансляция прошла успешно, необходимо организовать определенную иерархию каталогов проекта и соответствующим образом разместить исходные файлы.
Для построения исполняемой программы необходимо сформировать проект, который может быть размещен в любом каталоге. Он содержит модули на писанные на О2М, файл проекта, содержащий необходимые настройки и ряд подкаталогов, используемых для хранения промежуточной и конечной информации, содержимое которых заполняется используемыми инструментальными средствами. Проект должен включать один главный модуль, который может импортировать другие модули. Эти модули могут располагаться как в каталоге проекта, так и в других доступных каталогах, полные пути к которым должны быть указаны в файле настройки.
Внутри каталога проекта необходимо создать ряд дополнительных подкаталогов заполняемых используемыми инструментальными средствами.
Каталог «DFN» содержит файлы определений, создаваемые во время компиляции исходных модулей, написанных на О2М. Эти файлы используются для импорта разрешенных программных объектов другим модулям.
В каталоге «CPP» размещаются файлы программы на языке C++, генерируемые в результате трансляции модулей. Там же создается файл проекта, используемый для компиляции программы с языка C++, а также файлы, дополнительно порождаемые при трансляции объектов, поддерживающих процедурно-параметрический полиморфизм (с расширением fpp).
Каталог «Make» используется для выходных данных, порождаемых в ходе трансляции программы на C++. Эта трансляция осуществляется используемым компилятором с языка C++ (мы используем MS VC++ 6.0 и MinGW C++ в среде MS Windows, а также GNU С++ под Linux). В каталоге также хранятся объектные файлы и сгенерированный исполняемый модуль.
Например, построим проект для решения задачи о ханойской башне. Разместим проект внутри каталога HanoyTower. Непосредственно в этом каталоге разместим два модуля программы HanoyTower.o2m и HanoyTowerTest.o2m, а также файл настроек проекта HanoyTower.pro. Создадим в каталоге проекта три пустых подкаталога: CPP, DFN и Make. В первом утилиты системы программирования будут размещать порождаемые исходные тексты на языке C++ и вспомогательные промежуточные файлы. В каталоге DFN будут содержаться модули определений, полученные после компиляции исходных модулей. Каталог Make используется для хранения результатов работы компилятора с языка C++. В нем же будет храниться исполняемый файл, полученный в результате трансляции.
Следует отметить, что оболочка пользователя Pro2M обеспечивает автоматическое порождение требуемой структуры каталога проекта.
Особенности компиляции модулей на O2M
Транслятор реализован в виде отдельной программы (в Windows – o2m.exe), осуществляющей раздельную компиляцию модулей. Трансляция заключается в переводе с языка О2М в файлы программы на C++. Подобная схема перевода с одного языка высокого уровня в другой широко используется в экспериментальных разработках и позволяет апробировать необходимые идеи без дополнительных усилий по созданию генераторов кода.
Помимо текстов программы на языке C++ транслятор порождает модули определений (с расширением dfn), необходимые другим модулями для организации раздельной трансляции. Запуск компилятора из командной строки осуществляется в следующем формате:
o2m.exe имя_транслируемого_файла имя_файла_проекта
Транслятор можно использовать для раздельной компиляции модулей с последующей сборкой проекта вручную. Однако дополнительные утилиты позволяют автоматизировать этот процесс.
Компоновщик Link2M
Компоновщик Link2M входит в состав пакета программ для работы с языком O2M.
Результатом компиляции исходных текстов на языке О2М является набор файлов на языке С++, которые требуется оттранслировать при помощи ANSI С++ совместимого компилятора для получения исполняемого модуля. Но перед этим нужно выполнить компоновку проекта О2М для организации дополнительных программных связей, необходимых для реализации процедурно-параметрического полиморфизма.
После обработки главного файла проекта (специально отмеченного в файле настроек проекта) в целевом каталоге (\CPP) транслятор создает файл "_O2M_make.2mk", содержащий список всех файлов C++, необходимых для создания исполняемого модуля. Список файлов получается в результате обработки транслятором конструкций IMPORT, найденных в теле транслируемого модуля и в dfn-модулях, импортированных транслируемым модулем. Кроме этого, при компиляции О2М-модуля создается файл с названием, соответствующим названию модуля и расширением .2ml. Эти файлы содержат информацию, на основании которой компоновщик Link2M организует межмодульные связи и генерирует дополнительные файлы на языке C++, необходимые для сборки исполняемого файла.
Запуск Link2M осуществляется через командную строку. В качестве параметров указывается путь к файлу _O2M_Make.2mk, создаваемому компилятором O2M. В общем случае вызов компоновщика Link2M выглядит следующим образом:
Link2M CPP/_O2M_Make.2mk
Предполагается, что файл _O2M_make.2mk располагается в подкаталоге /CPP каталога, в котором располагается файл проекта. По умолчанию Link2M сканирует каталог, в котором располагается файл _O2M_Make.2mk, на предмет наличия файлов с именами, перечисленными в _O2M_Make.2mk и расширениями .2ml. Если подобные файлы обнаружены, осуществляется их обработка. Сформированные файлы _O2M_ppp.cpp и _O2M_ppp.h записываются в тот же каталог. Работу Link2M можно настроить при помощи параметров командной строки.
Утилита Make2M для создания проекта на C++
Утилита Make2M предназначена для создания make-файлов, позволяющих упростить работу с внешним компилятором языка C++. Она использует файл "_O2M_make.2mk", содержащий список всех файлов C++, и формирует скрипт для запуска внешнего компилятора с языка С++, передавая ему всее параметры, необходимые для генерации исполняемого модуля. Подобный механизм введен для отделения транслятора O2M от особенностей конкретных компиляторов с языка С++.
В текущей версии Make2M создает скрипты в формате makefile для Microsoft Visual C++ 6.0 и GNU C++. Скрипт может быть использован для генерации как консольного приложения, так и для генерации приложения, использующего графический интерфейс Windows. Вид исполняемого приложения определяется тем, какой из модулей (Console, Win и т.д.) был импортирован в главном файле проекта. В текущей версии поддерживается генерация консольного приложения со стандартными потоками (совместимо с операционными системами семейств Linux и Windows), консольного приложения Windows (поддерживаются возможности работы с устройствами ввода-вывода, предоставляемые консолью Windows), приложения, использующего графический интерфейс Windows.
Запуск Make2M осуществляется через командную строку. В качестве параметров указывается путь к файлу _O2M_Make.2mk, создаваемому компилятором O2M, и путь к файлу, в который будет записан скрипт для запуска компилятора C++. В общем случае вызов утилиты Make2M выглядит следующим образом:
Make2M CPP/_O2M_Make.2mk CPP/Makefile.mak
В данном случае предполагается, что файл _O2M_make.2mk располагается в подкаталоге /CPP каталога, в котором располагается файл проекта. По умолчанию Make2M генерирует скрипт для запуска компилятора Microsoft Visual C++ 6.0 в режиме создания консольного приложения Windows.
После этого остается запустить программу make, используемую с выбранным компилятором языка C++
Файл настроек проекта
Описание используемых программных модулей, задается в специальном конфигурационном файле проекта. Для его обозначения используется расширение pro. Файл содержит описания используемых модулей в формате, аналогичному ini-файлам MS Windows. Для описания подключаемых модулей с исходным текстом на Обероне-2М используется строка следующего формата:
FILE=имя_файла_с модулем
Подключаемые файлы располагаются в каталоге проекта. Порядок размещения описаний модулей определяет порядок последующей компиляции и сборки проекта. Поэтому модули, используемые в других модулях, должны быть описаны раньше. Модуль, являющийся главным, обычно описан после всех остальных. Помимо этого он идентифицируется дополнительно специальным описателем:
MAIN=имя_главного_модуля_программы
Разрабатываемая программа может импортировать библиотечные модули, размещаемые в различных каталогах. Путь к этим каталогам можно задавать, используя описатель:
IMPORT=полный_путь_к_модулю
Если указано несколько каталогов, то поиск импортируемых модулей будет вестись в порядке перечисления путей в файле проекта. В дополнение к указанным параметрам можно указать имя исполняемого файла, которое задается в описателе
EXEC= имя_исполняемого_файла
Дополнительные модули
В каталоге Import содержатся дополнительные библиотечные модули, которые могут быть использованы для написания программ на языке О2М. Каждый модуль представлен тремя файлами с расширениями .dfn .cpp и .h, для использования модуля в собственной программе необходимо указать путь к подключаемым модулям в файле проекта или поместить файлы в подкаталог DFN каталога проекта (что не рекомендуется). После задания пути модуль можно использовать в программе, поместив его название в список импортируемых модулей, например, для подключения модуля стандартного ввода данных In, необходимо в программе на О2М указать:
IMPORT In;
В файлах с расширением .dfn обычно содержится описание назначения экспортируемых модулем программных объектов. Модули из каталога Import не нуждаются в явном включении в список файлов проекта.
Для создания запускаемого консольного приложения необходимо импортировать модуль Console в главный модуль и откомпилировать программу. При компиляции проекта, состоящего из нескольких модулей, только один из модулей должен быть скомпилирован как главный модуль проекта (используется соответствующая опция в файле проекта).
При использовании оболочки пользователя Pro2M (под Microsoft Windows 95/98/NT/2000/XP) все необходимые ключи подставляются автоматически.
Описание демонстрационного примера
Пример использования разработанных инструментов можно рассмотреть на решении задачи о ханойской башне, в которой происходит перенос башни со стержня A на стержень B с использованием промежуточного стержня C. Основной модуль программы (HanoyTower.o2m), непосредственно решающий поставленную задачу, выглядит следующим образом:
MODULE HanoyTower;
IMPORT Out, In;
PROCEDURE Hanoy( n : INTEGER; x, y, z : CHAR );
BEGIN
IF n>0 THEN
Hanoy( n-1, x, z, y );
Out.String("From "); Out.Char(x);
Out.String(" to "); Out.Char(y);
Out.Ln;
Hanoy( n-1, z, y, x );
END
END Hanoy;
PROCEDURE Run*;
VAR
n : INTEGER;
BEGIN
In.Open; Out.Open;
Out.String("Disk number "); In.Int(n);
IF (n>0) THEN Hanoy(n, 'A', 'B', 'C' ) END
END Run;
END HanoyTower.
Модуль HanoyTowerTest.o2m, осуществляющий тестирование, использует следующий код:
MODULE TestHanoy;
IMPORT Console, HanoyTower;
BEGIN
HanoyTower.Run
END TestHanoy.
Файл проекта HanoyTower.pro, используемый для описания проекта, в ОС Windows имеет следующий вид:
IMPORT=C:\Prog\O2M\Import\
MAIN=HanoyTowerTest.o2m
EXEC=hanoy.exe
TARGET=0
FILE=HanoyTower.o2m
FILE=HanoyTowerTest.o2m
В качестве примера ниже приводится аналогичный файл, используемый в ОС Linux. В данном случае исполняемые файлы системы размещены в каталоге bin пользователя lamer (/home/lamer/bin). Библиотечные модули размещены в каталоге /home/lamer/bin/Import.
IMPORT=/home/bin/Import/
MAIN=HanoyTowerTest.o2m
EXEC=hanoy
TARGET=0
FILE=HanoyTower.o2m
FILE=HanoyTowerTest.o2m
Предполагается, что проект размещен в некотором каталоге, например, HanoyTower. В нем же созданы подкаталоги DFN, CPP и Make.
Для трансляции приведенного демонстрационного примера под ОС Windows необходимо осуществить следующую последовательность действий:
-
Откомпилировать модуль HanoyTower.o2m, содержащий основную часть программы:
o2m HanoyTower.o2m HanoyTower.pro
-
Осуществить компиляцию главного модуля HanoyTowerTest.o2m, содержащего тестовую часть программы:
o2m HanoyTowerTest.o2m HanoyTower.pro
-
Осуществить запуск компоновщика Link2M:
Link2M CPP/_O2M_make.2mk
-
Создать файл Makefile.mak, необходимый для сборки проекта программы на С++, полученной после компиляции модулей на языке О2М:
Make2M CPP/_O2M_make.2mk CPP/Makefile.mak
-
Перейти в каталог CPP и запустить утилиту сборки проекта nmake из комплекта утилит MS Visual C++ 6.0:
cd CPP
nmake Makefile.mak
-
Перейти в каталог Make и запустить программу hanoy.exe:
cd ../make
hanoy
Пример работы программы для случая, когда пользователь задал 3 диска:
Disk number 3
From A to B
From A to C
From B to C
From A to B
From C to A
From C to B
From A to B
Примечание. Ввод числа дисков пользователем выделен подчеркиванием.
Использование языков сценариев
Использование языков сценариев позволяет написать небольшую программу, автоматизирующую действия пользователя. В качестве языка, используемого для написания сценариев (скриптов) можно применить язык командных файлов [3]. В этом случает соответствующая программа, для рассматриваемого демонстрационного примера, может выглядеть следующим образом.
o2m HanoyTower.o2m HanoyTower.pro
o2m HanoyTowerTest.o2m HanoyTower.pro
Link2M CPP/_O2M_make.2mk
Make2M CPP/_O2M_make.2mk CPP/Makefile.mak
cd cpp
nmake Makefile.mak
cd ../make
hanoy
Использование командного файла позволяет легко осуществлять повторную сборку всего проекта при модификации модулей. Достаточно лишь осуществить его перезапуск. В принципе, для организации более эффективной компиляции из командной строки можно прописать свой makefile и для проекта на O2M.
Список использованных источников
-
Moessenboeck H., Wirth N. The Programming Language Oberon-2. Institut fur Computersysteme, ETH Zurich July 1996.
-
56. Легалов А.И. Швец Д.А. Процедурный язык с поддержкой эволюционного проектирования. – Научный вестник НГТУ, № 2 (15), 2003. С. 25-38.
-
Богумирский Б.С. MS-DOS 6.2. Новые возможности для пользователя. – СП-б.: Питер, 1004. – 425 с.
|