Это старая версия документа!
В этом уроке вы узнаете: как выглядит строительный блок компонентного каркаса, что происходит при компиляции и посмотрите, как делается вывод информации в бортовой журнал.
Весь каркас Блэкбокса строится из модулей. Модуль, это что-то вроде строительного кирпича, наподобие всем известных кирпичиков конструктора Лего:
Модули бывают разные - простые, сложные. А ещё у модулей есть интерфейс, благодаря которому их можно соединять друг с другом и так возводить очень сложные компонентные конструкции:
Кстати, компонент это более общее понятие, чем модуль. Компонентом можно назвать и модуль, и целый комплект модулей. Главное, что компонент - это часть расширяемой компонентной системы (расширяется она за счёт добавления новых компонентов). А модуль в Блэкбоксе это единица проектирования, разработки, компиляции и распространения, то есть, программирование в Блэкбоксе ведётся по-модульно. Вы строите архитектуру вашей системы из модулей, пишете исходный текст программы-модуля, компилируете в исполняемый модуль и его же распространяете.
Текст пустого программного модуля выглядит так:
MODULE MyModule; END MyModule.
В Компонентном Паскале операторы разделяются точкой с запятой и только в конце модуля ставится точка.
Откройте новый документ <Ctrl+N>, наберите в нём текст пустого модуля и скомпилируйте нажатием <Ctrl+K>/ (или меню Dev, Compile):
Как видите, Блэкбокс запрашивает разрешения на создание подкаталога My\Sym. Далее он точно так же спросит про подкаталог My\Code. И этот момент надо рассмотреть подробнее.
Имя нашего модуля MyModule
. Это двойное имя, которое содержит название подсистемы My и название модуля в ней, Module. Внутри этой подсистемы Блэкбокс создаст ещё две папки, одна из которых Sym (для символьных файлов), а другая Code (для кодовых). Подробнее о подсистемах вы можете узнать в учебнике.
Сохранять документы с исходными текстами следует в папке Mod вашей подсистемы, эту папку придётся создать вручную.
Символьные файлы нужны только для совместной компиляции разных модулей. Кодовые, они же исполняемые файлы, нужны только для загрузки и выполнения. После создания символьного и кодового файлов нашего модуля, компилятор завершит работу и выведет сообщение в журнал.
Если компилятор обнаружит ошибку в исходном тексте, то он просигнализирует об этом. Там, где найдена ошибка, появится маркер и в строке состояния (внизу главного окна) появится сообщение об ошибке. Можно дважды кликнуть по маркеру, чтобы его развернуть и прочитать сообщение.
Например, если в теле нашего пустого модуля написать что-то, непонятное компилятору, то он сгенерирует сразу два маркера.
На картинке первый из них развёрнут (его текст продублирован внизу экрана, в строке статуса) и означает, что после имени модуля и точки запятой компилятор ожидает только объявления раздела констант CONST
, или раздела переменных VAR
, или объявление процедуры PROCEDURE
или же конец модуля END
. Ничего из этого он не видит и поэтому сразу же выдаёт ошибку.
А второй маркер стоит после непонятного слова. Компилятор не понимает, что это слово означает, потому что его словарь не содержит этого слова. Компилятор понимает только специальные символы и особые зарезервированные слова (всё, что понимает компилятор, перечислено в Сообщении об Языке, см. меню Help, Contents, раздел Component Pascal, Language Report, пункт 3. Vocabulary and Representation)
Попробуем теперь написать небольшую программу, выводящую в журнал приветствие «Hello, world!».
MODULE MyModule; IMPORT Log; PROCEDURE Do*; BEGIN Log.String('Hello, world!'); Log.Ln END Do; END MyModule.
Итак, что же тут написано?
Со словом MODULE
в первой строчке мы уже знакомы.
На следующей строчке слово IMPORT
объявляет блок импорта других модулей, а слово Log
означает, что мы будем использовать возможности модуля Log
. Это то самое место, где кирпичики Лего соединяются, чтобы работать вместе.
Дальше идёт объявление процедуры. Звёздочка после имени Do
означает, что эта процедура будет видна другим модулям. Между словами-скобками BEGIN
и END
находится тело процедуры (отметьте, что после END
продублировано имя процедуры, это нужно для чёткой границы между скобками процедуры и скобками других операторов).
Ну а внутри процедуры мы видим последовательные вызовы процедур String
и Ln
модуля Log
. Обратите внимание, что перед именем каждой процедуры стоит квалификатор модуля Log
, это жёсткое правило языка Компонентный Паскаль (и, в общем, всех Оберонов). Благодаря обязательному квалификатору вы никогда не запутаетесь, откуда вызвана та или иная процедура или переменная.
В нашем модуле объявлена процедура Do
. Она ещё и доступна для других модулей, а это значит, что мы можем вызвать эту процедуру, - как будто отдать команду Блэкбоксу, - в любой момент.
В любом месте любого текстового документа (хоть в журнале, хоть в исходнике нашего модуля) поставьте коммандер с помощью кнопок <Ctrl+Q> или меню Tools, Insert Commander. После коммандера (он выглядит как чёрный кружок с восклицательным знаком внутри) напишите команду
MyModule.Do
Далее, надо откомпилировать наш модуль (в журнале появится новая запись об обнаруженной процедуре Do
. В дальнейшем, компилируйте модуль с выгрузкой (меню Dev, Compile and Unload), потому что Блэкбокс не выгружает просто так запущенные модули.
После компиляции и выгрузки, кликаем по коммандеру. Блэкбокс загрузит наш модуль и выполнит его процедуру Do
. А она выведет в журнал приветствие.
В заключение стоит отметить, что возможности модуля Log
всегда можно изучить, открыв его интерфейс. Для этого выделите слово Log
и скомандуйте в меню Info, Client Interface или правой кнопкой мыши (ПКМ) и во всплывшем меню выберите Interface.