Тело подпрограммы в качестве компилируемого модуля рассматрива­ется как вторичный модуль в том случае, если программная библиотека уже содержит библиотечный модуль, который является подпрограммой с тем же именем. В противном случае оно рассматривается одновременно и как библиотечный модуль, и как соответствующее этому библиотечному модулю тело (т. е. как вторичный модуль).

Компилируемые модули одной компиляции транслируются в заданном порядке. Относящаяся ко всей компиляции прагма должна помещаться пе­ред первым компилируемым модулем компиляции.

Подпрограмма, являющаяся библиотечным модулем, может использо­ваться в качестве главной программы в традиционном смысле. Главная программа выполняется так, как будто она вызвана некоторой внешней за­дачей; средства инициализации этого выполнения в языке не предписаны. Реализация может предъявить определенные требования к параметрам и ре­зультату (если он есть) главной программы (эти требования должны быть приведены в руководствах в соответствии с обязательным приложением 4). Каждая реализация должна разрешать задание в качестве главной програм­мы процедуры без параметров. Любая главная программа должна быть под­программой — библиотечным модулем.

Примечание. Простая программа может состоять из одного компилируемого мо­дуля. Компиляция может не содержать ни одного компилируемого модуля, например, ее текст может состоять из одних прагм.

Обозначение библиотечной функции не может быть знаком операции, но для пере­именования библиотечной функции в операцию допускается использовать описание переименования. Две библиотечные подпрограммы должны иметь различные простые имена, и потому не могут быть совмещены друг с другом. Однако описания переиме­нования могут определить совмещенные имена для таких подпрограмм; кроме того, с библиотечной подпрограммой можно совмещать локально описанную подпрограмму. Так как библиотечные модули рассматриваются как описания, приведенные непосред­ственно в пакете STANDARD, то для библиотечного модуля М может быть использова­но расширенное имя STANDARD.M (если только имя STANDARD не скрыто).

  1. Спецификаторы контекста. Спецификаторы совместности

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

спецификатор., контекста : : =

{спецификатор.совместности {спецификатор.. использования}} спецификатор_совместности : : =

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 КВАДРАТНОЕ-УРАВНЕНИЕ;

Примечание к примеру. В спецификаторах совместности компилируемого модуля надо упоминать имена только тех библиотечных подпрограмм или пакетов, видимость которых действительно необходима внутри модуля. Нет необходимости (и не следу­ет) упоминать имена других библиотечных модулей, используемых внутри модулей, перечисленных в этих спецификаторах совместности, кроме тех, которые используют­ся непосредственно в данном компилируемом модуле. Например, в теле пакета ВЕЩЕСТВ_ОПЕРАЦИИ могут потребоваться некоторые элементарные операции, опре­деленные в других пакетах. Но эти пакеты не надо упоминать в спецификаторе сов­местности процедуры КВАДРАТНОЕ УРАВНЕНИЕ, так как в ее теле элементарные операции не вызываются непосредственно.

  1. Примеры компилируемых модулей

Компилируемый модуль может быть расчленен на несколько компили­руемых модулей. Например, рассмотрим следующую программу.

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 ПРОЦЕССОР;

Заметим, что в последней версии примера в пакете ФОНД не видимы внешние идентификаторы, отличные от предопределенных (в пакете STAN­DARD) . В частности, в нем не используются идентификаторы МАЛОЕ и ИТОГ, описанные в процедуре ПРОЦЕССОР; в противном случае пакет ФОНД нельзя выделить из процедуры ПРОЦЕССОР, как это сделано выше. С другой стороны, процедура ПРОЦЕССОР зависит от пакета ФОНД и упо­минает его в спецификаторе совместности. Поэтому пакет ФОНД можно ис­пользовать в расширенном имени и в спецификаторе использования.

Эти три компилируемых модуля могут быть организованы как одна или несколько компиляций. НаПример, возможно объединение в одной компиляции спецификации и тела пакета в указанном порядке.

  1. Субмодули компилируемых модулей

Субмодули используются для раздельной компиляции соответствующе­го тела программного модуля, описанного в другом компилируемом моду­ле. Этот метод разделения программы позволяет разрабатывать программу иерархически.

след_тела : : =

спецификация_подпрограммы is separate;

(package body простое_имя_пакета is separate;

I task body простое_имя_задачм is separate;

субмодуль : : =

separate (имя^родительского „модуля) соответствующее_тело

Использование следа тела в качестве тела программного модуля (под­программы, пакета, заданного модуля или настраиваемого модуля) допус­кается, только если след тела помещен непосредственно в теле библиотечно­го пакету или в разделе описаний некоторого компилируемого модуля.

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

Для каждого субмодуля задается имя родительского модуля, т. е. ком­пилируемого модуля, содержащего соответствующий след тела. Если роди­тельский модуль — библиотечный модуль, то он называется предком. Если родительский модуль сам является субмодулем, то его имя должно быть представлено расширенным именем, начинающимся простым именем биб­лиотечного модуля-предка. Простые имена всех субмодулей, которые име­ют одинакового предка, должны задаваться различными идентификаторами.

Видимость в соответствующем теле субмодуля — это видимость, кото­рая была бы получена в месте задания следа тела (в родительском модуле) , если бы спецификаторы совместности и использования субмодуля были добавлены к спецификатору контекста родительского модуля. Если роди­тельский модуль сам является субмодулем, то это же правило используется для определения видимости в соответствующем теле родительского мо­дуля.

Результатом предвыполнения следа тела является предвыполнение со­ответствующего тела субмодуля.

Примечание. Два субмодуля различных библиотечных модулей в одной и той же программной библиотеке могут иметь совпадающие идентификаторы. В этом случае их расширенные имена различны, так как различны простые имена библиотечных мо­дулей и простые имена всех субмодулей одного предка-данного библиотечного моду­ля. Средствами описаний переименования могут быть введены для (различных) суб­модулей совмещенные имена подпрограмм.

Библиотечный модуль, упомянутый в спецификаторе совместности субмодуля, может быть скрыт описанием (с тем же идентификатором), данным в соответствующем теле субмодуля. Более того, такой библиотечный модуль может быть скрыт описа­нием, данным в родительском модуле, так как библиотечный модуль рассматривается как описанный в пакете STANDARD; это, однако, не влияет на интерпретацию специ­фикаторов совместности, ибо в них могут быть упомянуты имена только библиотеч­ных модулей.

  1. П р и м е р ы субмодулей

В первом примере процедура ВЕРШИНА оформлена в виде компилиру­емого модуля без субмодулей.

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