Тело подпрограммы в качестве компилируемого модуля рассматривается как вторичный модуль в том случае, если программная библиотека уже содержит библиотечный модуль, который является подпрограммой с тем же именем. В противном случае оно рассматривается одновременно и как библиотечный модуль, и как соответствующее этому библиотечному модулю тело (т. е. как вторичный модуль).
Компилируемые модули одной компиляции транслируются в заданном порядке. Относящаяся ко всей компиляции прагма должна помещаться перед первым компилируемым модулем компиляции.
Подпрограмма, являющаяся библиотечным модулем, может использоваться в качестве главной программы в традиционном смысле. Главная программа выполняется так, как будто она вызвана некоторой внешней задачей; средства инициализации этого выполнения в языке не предписаны. Реализация может предъявить определенные требования к параметрам и результату (если он есть) главной программы (эти требования должны быть приведены в руководствах в соответствии с обязательным приложением 4). Каждая реализация должна разрешать задание в качестве главной программы процедуры без параметров. Любая главная программа должна быть подпрограммой — библиотечным модулем.
Примечание. Простая программа может состоять из одного компилируемого модуля. Компиляция может не содержать ни одного компилируемого модуля, например, ее текст может состоять из одних прагм.
Обозначение библиотечной функции не может быть знаком операции, но для переименования библиотечной функции в операцию допускается использовать описание переименования. Две библиотечные подпрограммы должны иметь различные простые имена, и потому не могут быть совмещены друг с другом. Однако описания переименования могут определить совмещенные имена для таких подпрограмм; кроме того, с библиотечной подпрограммой можно совмещать локально описанную подпрограмму. Так как библиотечные модули рассматриваются как описания, приведенные непосредственно в пакете STANDARD, то для библиотечного модуля М может быть использовано расширенное имя STANDARD.M (если только имя STANDARD не скрыто).
Спецификаторы контекста. Спецификаторы совместности
Для указания библиотечных модулей, имена которых используются в компилируемом модуле, служит спецификатор контекста.
спецификатор., контекста : : =
{спецификатор.совместности {спецификатор.. использования}} спецификатор_совместности : : =
wiht простое..имя...лтодуля { простое_имя_.мо<)уля};
Имена в спецификаторе контекста должны быть простыми именами библиотечных модулей. В спецификаторе совместности допустимы простые имена любых библиотечных модулей. В спецификаторе использования допустимы простые имена только тех библиотечных пакетов, которые указаны в предшествующих спецификаторах совместности данного спецификатора контекста. В спецификаторе контекста недопустимы простые имена, введенные описанием переименования.
Спецификаторы совместности и использования в спецификаторе контекста библиотечного модуля применяются к этому библиотечному модулю и ко вторичному модулю, который определяет соответствующее' тело (независимо от того, повторен ли такой спецификатор для вторичного модуля или нет). Аналогично, для компилируемого модуля спецификаторы совместности и использования в спецификаторе контекста применяются к этому модулю и к его субмодулям (если они есть).
Библиотечный модуль, упомянутый в спецификаторе совместности, примененном к компилируемому модулю, видим непосредственно внутри этого компилируемого модуля, исключая случаи его скрытия; этот библиотечный модуль видим как описанный непосредственно в пакете STANDARD (см. 8.6).
Спецификаторы совместности задают зависимости между компилируемыми модулями, т. е. компилируемый модуль зависит от других библиотечных модулей, упомянутых в спецификаторе контекста. Зависимости между модулями учитываются при определении допустимого порядка компиляции (и перекомпиляции) компилируемых модулей (см. разд. 10.3),а также при определении допустимого порядка предвыполнения компилируемых модулей (см. разд. 10.5).
Примечание. Внутри компилируемого модуля видимы библиотечные модули, упомянутые в спецификаторе совместности (исключая случаи их скрытия), следовательно, они могут использоваться как соответствующие программные модули. Так, в компилируемом модуле имя библиотечного пакета может быть дано в спецификаторе использования и служит для формирования расширенных имен; библиотечные подпрограммы можно вызывать; можно описать конкретизации библиотечного настраиваемого модуля.
Правила для спецификаторов совместности дают одинаковый результат как при упоминании имени библиотечного модуля один или несколько раз в различных спецификаторах совместности, так и внутри заданного спецификатора совместности.
Пример 1. Главная программа. Ниже приведен пример главной программы, состоящей из одного компилируемого модуля — процедуры печати вещественных корней квадратного уравнения. Предполагается, что в программной библиотеке уже содержится предопределенный пакет ТЕХТ—ІО и заданный пользователем пакет ВЕЩЕСТВ—ОПЕРАЦИИ (содержащий определения типа ВЕЩЕСТВ и пакетов ВЕЩЕСТВ—ВВ и ВЕЩЕСТВ-ФУНКЦИИ).
Такие пакеты могут быть использованы и другими главными программами.
with ТЕХТ_ Ю,ВЕЩЕСТВ_ОПЕРАЦИИ;
use ВЕЩЕСТВ,ОПЕРАЦИИ;
procedure КВАДРАТНОЕ_УРАВНЕНИЕ is
А, В, С, Д: ВЕЩЕСТВ;
use ВЕЩЕСТВ_ВВ - - обеспечивает прямую видимость GET и PUT для ВЕЩЕСТВ ТЕХТ_1О, - - обеспечивает прямую видимость NEW LINE и PUT для строк ВЕЩЕСТВ-ФУНКЦИИ; - - обеспечивает прямую видимость функции SQRT
begin
GET (A); GET (В); GET (С);
Д: = В ** 2 — 4.0 * А * С;
if Д < 0.0 then
PUT (’’МНИМЫЕ КОРНИ”);
else
PUT (’’ВЕЩЕСТВЕННЫЕ КОРНИ; XI =”) ;
PUT((-B - SQRT (Д))/(2.0 * A)); PUT(”X2 =”) ;
PUT ((-В +SQRT(fl)) / (2.0 * А));
end if;
NEW-LINE;
end КВАДРАТНОЕ-УРАВНЕНИЕ;
Примечание к примеру. В спецификаторах совместности компилируемого модуля надо упоминать имена только тех библиотечных подпрограмм или пакетов, видимость которых действительно необходима внутри модуля. Нет необходимости (и не следует) упоминать имена других библиотечных модулей, используемых внутри модулей, перечисленных в этих спецификаторах совместности, кроме тех, которые используются непосредственно в данном компилируемом модуле. Например, в теле пакета ВЕЩЕСТВ_ОПЕРАЦИИ могут потребоваться некоторые элементарные операции, определенные в других пакетах. Но эти пакеты не надо упоминать в спецификаторе совместности процедуры КВАДРАТНОЕ УРАВНЕНИЕ, так как в ее теле элементарные операции не вызываются непосредственно.
Примеры компилируемых модулей
Компилируемый модуль может быть расчленен на несколько компилируемых модулей. Например, рассмотрим следующую программу.
procedure ПРОЦЕССОР is
МАЛОЕ; constant: = 20;
ИТОГ: INTEGER: = 0;
package ФОНД is
ПРЕДЕЛ: constant: = 1000;
ТАБЛИЦА: array (1. .ПРЕДЕЛ) of INTEGER;
procedure ПЕРЕЗАПУСК;
end ФОНД;
package body ФОНД is
procedure ПЕРЕЗАПУСК is begin
for К in 1. .ПРЕДЕЛ loop
ТАБЛИЦА (К): = К;
end loop;
end;
begin
ПЕРЕЗАПУСК;
end ФОНД;
procedure ИЗМЕНЕНИЕ (X: INTEGER) is
use ФОНД;
- - некоторые описания
begin
ТАБЛИЦА (X) : = ТАБЛИЦА (X) + МАЛОЕ;
end ИЗМЕНЕНИЕ;
begin
ФОНД.ПЕРЕЗАПУСК; -- пёреинициализация массива ТАБЛИЦА
end ПРОЦЕССОР;
Приведенные ниже три компилируемых модуля определяют программу с результатом, эквивалентным результату предыдущего примера (пунктирные линии между модулями напоминают, что они не обязаны составлять единый текст).
Пример 2. Несколько компилируемых модулей:
package ФОНД is
ПРЕДЕЛ: constant: = 1000;
ТАБЛИЦА: array (1. .ПРЕДЕЛ) of INTEGER;
procedure ПЕРЕЗАПУСК;
end ФОНД;
package body ФОНД is procedure ПЕРЕЗАПУСК is begin
for К in 1. .ПРЕДЕЛ loop ТАБЛИЦА (К) : = К;
end loop;
end;
begin
ПЕРЕЗАПУСК;
end ФОНД;
With ФОНД;
procedure ПРОЦЕССОР is
МАЛОЕ: constant: = 20;
ИТОГ: INTEGER: = 0;
procedure ИЗМЕНЕНИЕ (X; INTEGER) is use ФОНД;
begin
ТАБЛИЦА (X): = ТАБЛИЦА(X) + МАЛОЕ;
end ИЗМЕНЕНИЕ;
begin
ФОНД.ПЕРЕЗАПУСК; - - переинициализация ТАБЛИЦА
end ПРОЦЕССОР;
Заметим, что в последней версии примера в пакете ФОНД не видимы внешние идентификаторы, отличные от предопределенных (в пакете STANDARD) . В частности, в нем не используются идентификаторы МАЛОЕ и ИТОГ, описанные в процедуре ПРОЦЕССОР; в противном случае пакет ФОНД нельзя выделить из процедуры ПРОЦЕССОР, как это сделано выше. С другой стороны, процедура ПРОЦЕССОР зависит от пакета ФОНД и упоминает его в спецификаторе совместности. Поэтому пакет ФОНД можно использовать в расширенном имени и в спецификаторе использования.
Эти три компилируемых модуля могут быть организованы как одна или несколько компиляций. НаПример, возможно объединение в одной компиляции спецификации и тела пакета в указанном порядке.
Субмодули компилируемых модулей
Субмодули используются для раздельной компиляции соответствующего тела программного модуля, описанного в другом компилируемом модуле. Этот метод разделения программы позволяет разрабатывать программу иерархически.
след_тела : : =
спецификация_подпрограммы is separate;
(package body простое_имя_пакета is separate;
I task body простое_имя_задачм is separate;
субмодуль : : =
separate (имя^родительского „модуля) соответствующее_тело
Использование следа тела в качестве тела программного модуля (подпрограммы, пакета, заданного модуля или настраиваемого модуля) допускается, только если след тела помещен непосредственно в теле библиотечного пакету или в разделе описаний некоторого компилируемого модуля.
В случае задания тела программного модуля следом тела требуется, чтобы субмодуль, содержащий соответствующее тело, был откомпилирован раздельно. Для подпрограммы спецификации подпрограммы, данные в соответствующем теле и в следе тела, должны быть согласованы (см. 6.3.1).
Для каждого субмодуля задается имя родительского модуля, т. е. компилируемого модуля, содержащего соответствующий след тела. Если родительский модуль — библиотечный модуль, то он называется предком. Если родительский модуль сам является субмодулем, то его имя должно быть представлено расширенным именем, начинающимся простым именем библиотечного модуля-предка. Простые имена всех субмодулей, которые имеют одинакового предка, должны задаваться различными идентификаторами.
Видимость в соответствующем теле субмодуля — это видимость, которая была бы получена в месте задания следа тела (в родительском модуле) , если бы спецификаторы совместности и использования субмодуля были добавлены к спецификатору контекста родительского модуля. Если родительский модуль сам является субмодулем, то это же правило используется для определения видимости в соответствующем теле родительского модуля.
Результатом предвыполнения следа тела является предвыполнение соответствующего тела субмодуля.
Примечание. Два субмодуля различных библиотечных модулей в одной и той же программной библиотеке могут иметь совпадающие идентификаторы. В этом случае их расширенные имена различны, так как различны простые имена библиотечных модулей и простые имена всех субмодулей одного предка-данного библиотечного модуля. Средствами описаний переименования могут быть введены для (различных) субмодулей совмещенные имена подпрограмм.
Библиотечный модуль, упомянутый в спецификаторе совместности субмодуля, может быть скрыт описанием (с тем же идентификатором), данным в соответствующем теле субмодуля. Более того, такой библиотечный модуль может быть скрыт описанием, данным в родительском модуле, так как библиотечный модуль рассматривается как описанный в пакете STANDARD; это, однако, не влияет на интерпретацию спецификаторов совместности, ибо в них могут быть упомянуты имена только библиотечных модулей.
П р и м е р ы субмодулей
В первом примере процедура ВЕРШИНА оформлена в виде компилируемого модуля без субмодулей.
with ТЕХТ-1О;
procedure ВЕРШИНА is
type ВЕЩЕСТВ is digits 10;
P, С: ВЕЩЕСТВ: = 1.0;
package СЕРВИС is
ПИ: constant: = 3.14159_26536;
function F(X: ВЕЩЕСТВ) return ВЕЩЕСТВ;
procedure G(Y, H: ВЕЩЕСТВ);
end СЕРВИС;
package body СЕРВИС is
- предшествуют некоторые локальные описания
function F (X: ВЕЩЕСТВ) return ВЕЩЕСТВ is begin
- последовательность операторов функции F
end F;
procedure G(Y, H: ВЕЩЕСТВ) is
- использующие пакет TEXT_ IO локальные процедуры
begin
- последовательность операторов процедуры G
end G;
end СЕРВИС;
procedure ПРЕОБРАЗОВАНИЕ (Ф: in out ВЕЩЕСТВ) is
use СЕРВИС;
begin
Ф: = F (Ф) ;
end ПРЕОБРАЗОВАНИЕ;
begin - - ВЕРШИНА
ПРЕОБРАЗОВАНИЕ (Р);
CEPBHC.G (Р, С);
end ВЕРШИНА;
Тело пакета СЕРВИС и процедуру ПРЕОБРАЗОВАНИЕ можно представить в виде раздельно компилируемых субмодулей модуля ВЕРШИНА. Тело процедуры G также может быть представлено как субмодуль модуля СЕРВИС.
Пример 3:
procedure ВЕРШИНА is
type ВЕЩЕСТВ is digits 10;
Р, С: ВЕЩЕСТВ: = 1.0;
package СЕРВИС is
ПИ: constant: = 3.14159_26536;
function F(X: ВЕЩЕСТВ) return ВЕЩЕСТВ;
procedure G(Y, Н: ВЕЩЕСТВ);
end СЕРВИС;
package body СЕРВИС is separate; - - след тела СЕРВИС
procedure ПРЕОБРАЗОВАНИЕ (Ф: in out ВЕЩЕСТВ) is separate
begin - - ВЕРШИНА
ПРЕОБРАЗОВАНИЕ (Р);
CEPBHC.G (Р, С);
end ВЕРШИНА;
separate (ВЕРШИНА)
procedure ПРЕОБРАЗОВАНИЕ (Ф: in out ВЕЩЕСТВ) is use СЕРВИС;
begin
Ф: = F (Ф) ;
end ПРЕОБРАЗОВАНИЕ;
separate (ВЕРШИНА)
package body СЕРВИС is
- предшествуют некоторые локальные описания function F (X: ВЕЩЕСТВ) return ВЕЩЕСТВ is
begin
- последовательность операторов функции F
end;
procedure G(Y, Н: ВЕЩЕСТВ) is separate; - - след тела G end СЕРВИС;
with TEXT_IO;
separate (ВЕРШИНА, СЕРВИС) - - полное имя пакета СЕРВИС procedure G(Y, Н: ВЕЩЕСТВ) is