Приложение A. АТРИБУТЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ
Пред. След.

Приложение A. АТРИБУТЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ

P'ADDRESS | Префикс Р обозначает объект, программный модуль, метку или вход. Вырабатывает адрес первого кванта памяти, отведенной под Р. Для подпрограммы, пакета, задачи или метки это значение ссылается на машинный код, связанный с соответствующим телом или оператором. Для входа, для которого задан спецификатор адреса, это значение ссылается на соответствующее аппаратное прерывание. Значение этого атрибута имеет предопределенный в пакете SYSTEM тип ADDRESS (см. 13.7.2).
P'AFT | Префикс Р обозначает фиксированный подтип. Вырабатывает число десятичных цифр после точки, необходимых для обеспечения точности подтипа Р, если только атрибут DELTA подтипа Р не превышает 0.1, в этом случае атрибут вырабатывает значение единицы. (P'AFT — это наименьшее положительное число N, для которого (10 ** N)*P' DELTA больше или равно 1.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.10).
P'BASE | Префикс Р обозначает тип или подтип. Этот атрибут обозначает базовый тип Р и может быть только префиксом имени другого атрибута, например P'BASE'FIRST (см. 3.3.3).
P'CALLABLE | Префикс Р — это объект задачного типа. Вырабатывает значение FALSE, когда выполнение задачи Р либо закончено, либо завершено, либо задача находится в аварийном состоянии. В остальных случаях вырабатывает значение TRUE. Значение этого атрибута имеет предопределенный тип BOOLEAN (см. 9.9).
P'CONSTRAINED | Префикс Р обозначает объект некоторого типа с дискриминантами. Вырабатывает значение TRUE, если ограничение дискриминантов наложено на объект Р или если объект — константа (включая формальный параметр или формальный параметр настройки вида in). В остальных случаях вырабатывает значение FALSE. Если Р — формальный параметр настройки вида in out или если Р — формальный параметр вида in out или out, а обозначение типа, заданное в соответствующей спецификации параметра, обозначает неограниченный тип с дискриминантами, то значение этого атрибута получается из значения атрибута соответствующего фактического параметра. Значение атрибута имеет предопределенный тип BOOLEAN (см. 3.7.4).
P'CONSTRAINED | Префикс Р обозначает личный тип или подтип. Вырабатывает значение FALSE, если Р обозначает неограниченный неформальный личный тип с дискриминантами; вырабатывает это же значение, если Р обозначает настраиваемый формальный личный тип, а соответствующий фактический подтип — это либо неограниченный тип с дискриминантами, либо неограниченный индексируемый тип. В остальных случаях вырабатывается значение TRUE. Значение этого атрибута имеет предопределенный тип BOOLEAN (см. 7.4.2).
P'COUNT | Префикс Р обозначает вход задачи. Вырабатывает число вызовов входа, присутствующих в очереди этого входа, (если атрибут вычисляется внутри оператора принятия входа Р, то в это число не входит вызывающая задача). Значение этого атрибута имеет универсальный-целый тип (см. 9.9).
Р'DELTA | Префикс Р обозначает фиксированный подтип. Вырабатывает значение дельты, заданной в определении точности фиксированного типа для подтипа Р. Значение этого атрибута имеет универсальный-вещественный тип (см. 3.5.10)
P'DIGITS | Префикс Р обозначает плавающий подтип. Вырабатывает число десятичных цифр в десятичной мантиссе модельных чисел подтипа Р. (Этот атрибут вырабатывает число D, определенное в разд. 3.5.7.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.8).
P'EMAX | Префикс Р обозначает плавающий подтип. Вырабатывает наибольшее значение порядка двоичной канонической формы модельных чисел подтипа Р. (Этот атрибут вырабатывает произведение 4*В.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.8).
P'EPSILON | Префикс Р обозначает плавающий подтип. Вырабатывает абсолютное значение разности между модельным числом 1.0 и следующим модельным числом подтипа Р. Значение этого атрибута имеет универсальный-вещественный тип (см. 3.5.8).
P'FIRST | Префикс Р обозначает скалярный тип или подтип скалярного типа. Вырабатывает значение нижней границы Р. Значение этого атрибута имеет тип Р (см. 3.5).
P'FIRST | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает значение нижней границы диапазона первого индекса. Значение этого атрибута имеет тот же тип, что и тип значения нижней границы (см. 3.6.2 и 3.8.2).
P'FIRST(N) | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает значение нижней границы диапазона N-го индекса. Значение этого атрибута имеет тот же тип, что и указанная нижняя граница. Аргумент N должен быть статическим выражением типа универсальный-целый. Значение N должно быть положительным (ненулевым) и не превосходить размерности массива (см. 3.6.2 и 3.8.2).
P'FIRST_BIT | Префикс Р обозначает компоненту записи. Вырабатывает величину смещения первого бита относительно начала первого кванта памяти, занимаемой этой компонентой. Величина смещения измеряется числом битов. Значение этого атрибута имеет тип универсальный-целый (см. 13.7.2).
P'FORE | Префикс Р обозначает фиксированный подтип. Вырабатывает минимальное число символов, необходимых для десятичного представления целой части любого значения подтипа Р в предположении, что это представление не включает порядок, но включает односимвольный префикс, который является либо знаком минус, либо пробелом. (Это минимальное число не учитывает предшествующие нули и символы подчеркивания и по меньшей мере равно двум.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.10).
P'IMAGE(X) | Префикс Р обозначает дискретный тип или подтип. Этот атрибут представляет собой функцию с одним параметром. Фактический параметр Х должен быть значением базового типа Р. Тип результата — предопределенный тип STRING. Результат представляет собой образ значения X, т. е. последовательность символов, представляющих изображение значения. Образу целого значения соответствуют десятичный литерал без символов подчеркивания, предшествующих нулей, порядка и последующих пробелов, но с одним символом слева, который представляет собой либо минус, либо пробел. Образом литерала перечисления является либо соответствующий идентификатор из прописных букв, либо соответствующий символьный литерал (включая два апострофа) без предшествующих и последующих пробелов. Образ символа, отличного от графического, определяется реализацией (см. 3.5.5).
P'LARGE | Префикс Р обозначает вещественный подтип. Вырабатывает наибольшее положительное модельное число подтипа Р. Значение этого атрибута имеет универсальный-вещественный тип (см. 3.5.8 и 3.5.10).
P'LAST | Префикс Р обозначает скалярный тип или подтип скалярного типа. Вырабатывает значение верхней границы Р. Значение этого атрибута имеет тип Р (см. 3.5).
P'LAST | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает значение верхней границы диапазона первого индекса. Значение атрибута имеет тип верхней границы (см. 3.6.2 и 3.8.2).
P'LAST(N) | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает значение верхней границы диапазона N-го индекса. Значение этого атрибута имеет тот же тип, что и верхняя граница. Аргумент N должен быть статическим выражением типа универсальный-целый. Значение N должно быть положительным (ненулевым) и не превышать размерности массива (см. 3.6.2 и 3.8.2).
P'LAST_BIT | Префикс Р обозначает компоненту записи. Вырабатывает величину смещения последнего бита относительно первого кванта памяти, занимаемой этой компонентой. Величина смещения измеряется числом битов. Значение атрибута имеет тип универсальный-целый (см. 13.7.2).
P'LENGTH | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает число значений диапазона первого индекса (нуль для пустого диапазона). Значение этого атрибута имеет универсальный-целый тип (см. 3.6.2).
P'LENGTH(N) | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает число значений в диапазоне N-го индекса (нуль для пустого диапазона). Значение этого атрибута имеет универсальный-целый тип. Аргумент N должен быть статическим выражением типа универсальный-целый. Значение N должно быть положительным (ненулевым) и не должно превышать размерности массива (см. 3.6.2 и 3.8.2).
P'MACHINE_EMAX | Префикс Р обозначает плавающий тип или подтип. Вырабатывает наибольшее значение порядка машинного представления базового типа Р. Значение этого атрибута имеет универсальный-целый тип (см. 13.7.3).
P'MACHINE_EMIN | Префикс Р обозначает плавающий тип или подтип. Вырабатывает наименьшее (наибольшее по модулю отрицательное) значение порядка машинного представления базового типа Р. Значение этого атрибута имеет универсальный-целый тип (см. 13.7.3).
P'MACHINE_MANTISSA | Префикс Р обозначает плавающий тип или подтип. Вырабатывает число цифр в мантиссе машинного представления базового типа Р (цифры являются расширенными цифрами из диапазона 0 . . P'MACHINE_RADIX - 1). Значение этого атрибута имеет универсальный-целый тип (см. 13.7.3).
P'MACHINE_OVERFLOWS | Префикс Р обозначает вещественный тип или подтип. Вырабатывает значение TRUE, если каждая предопределенная операция над значениями базового типа Р либо возвращает точный результат, либо возбуждение исключения NUMERIC_ERROR при переполнении. В противном случае вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN (см. 13.7.3).
P'MACHINE_RADIX | Префикс Р обозначает плавающий тип или подтип. Вырабатывает значение основания, используемое в машинном представлении базового типа Р. Значение этого атрибута имеет тип универсальный-целый (см. 13.7.3).
P'MACHINE_ROUNDS | Префикс Р обозначает вещественный тип или подтип. Вырабатывает значение TRUE, если каждая предопределенная арифметическая операция над значениями базового типа Р либо возвращает точный результат, либо осуществляет округление. В противном случае вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN (см. 13.7.3).
P'MANTISSA | Префикс Р обозначает вещественный подтип. Вырабатывает число двоичных цифр мантиссы модельных чисел подтипа Р. (Этот атрибут вырабатывает число В, введенное в разд. 3.5.7 для плавающего типа и в разд. 3.5.9 для фиксированного типа.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.8 и 3.5.10).
P'POS(X) | Префикс Р обозначает дискретный тип или подтип. Этот атрибут является функцией с одним параметром. Фактический параметр Х должен быть значением базового типа Р. Тип результата — универсальный-целый. Результатом является порядковый номер позиции для значения фактического параметра (см. 3.5.5),
P'POSITION | Префикс Р обозначает компоненту записи. Вырабатывает величину смещения первого кванта памяти, занятого этой компонентой, относительно первого кванта памяти, занимаемого записью. Величина смещения измеряется числом квантов. Значение этого атрибута имеет универсальный-целый тип (см. 13.7.2).
P'PRED(X) | Префикс Р обозначает дискретный тип или подтип. Этот атрибут является функцией с одним параметром. Фактический параметр Х должен быть значением базового типа Р. Тип результата — базовый тип Р. Результатом является значение с номером позиции, на единицу меньшим номера позиции для значения X. Если Х равен P'BASE'FIRST, то возбуждается исключение CONSTRAINT_ERROR (см. 3.5.5).
P'RANGE | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает диапазон первого индекса Р, т. е. диапазон Р'FIRST . . P'LAST. (см.3.6.2).
P'RANGE(N) | Префикс Р соответствует индексируемому типу или обозначает ограниченный индексируемый подтип. Вырабатывает диапазон N-го индекса Р, т. е. диапазон P'FIRST (N) . . P'LAST (N) (см. 3.6.2).
P'SAFE_EMAX | Префикс Р обозначает плавающий тип или подтип. Вырабатывает наибольшее значение порядка двоичной канонической формы хранимых чисел базового типа Р. (Этот атрибут вырабатывает число Е, определенное в разд. 3.5.7.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.8).
P'SAFE_LARGE | Префикс Р обозначает вещественный тип или подтип. Вырабатывает наибольшее положительное хранимое число базового типа Р. Значение этого атрибута имеет универсальный-вещественный тип (см. 3.5.8 и 3.5.10).
P'SAFE_SMALL | Префикс Р обозначает вещественный тип или подтип. Вырабатывает наименьшее положительное (ненулевое) хранимое число базового типа Р. Значение этого атрибута имеет универсальный-вещественный тип (см. 3.5.8 и 3.5.10).
P'SIZE | Префикс Р обозначает тип или подтип. Вырабатывает минимальное число битов, необходимое реализации для представления любого возможного значения объекта типа или подтипа Р. Значение этого атрибута имеет универсальный-целый тип (см. 13.7.2).
P'SIZE | Префикс Р обозначает объект. Вырабатывает число битов, отведенных для размещения объекта. Значение этого атрибута имеет универсальный-целый тип (см.13.7.2).
P'SMALL | Префикс Р обозначает вещественный подтип. Вырабатывает наименьшее положительное (ненулевое) число подтипа Р. Значение этого атрибута имеет универсальный-вещественный тип (см. 3.5.8 и 3.5.10).
P'STORAGE_SIZE | Префикс Р обозначает ссылочный тип или подтип. Вырабатывает общее число квантов памяти, резервируемых для соответствующего базовому типу Р набора. Значение этого атрибута имеет универсальный-целый тип (см.13.7.2).
P'STORAGE_SIZE | Префикс обозначает задачный тип или задачу. Вырабатывает общее число квантов памяти, резервируемых для каждой активизации задачи типа Р или объекта Р задачного типа. Значение этого атрибута имеет универсальный-целый тип (см. 13.7.2).
P'SUCC(X) | Префикс Р обозначает дискретный тип или подтип. Этот атрибут является функцией с одним параметром. Фактический параметр Х должен быть значением базового типа Р. Тип результата является базовым типом Р. Результат представляет собой значение с номером позиции, на единицу большим номера позиции для значения X. Если Х равен P'BASE'LAST, то возбуждается исключение CONSTRAINT_ERROR (см. 3.5.5).
P'TERMINATED | Префикс Р соответствует задачному типу [] . Вырабатывает значение TRUE, если задача Р завершена, иначе вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN (см. 9.9).
P'VAL(X) | Префикс Р обозначает дискретный тип или подтип. Этот атрибут является специальной функцией с одним параметром X, который может быть любого целого типа. Тип результата является базовым типом Р. Результат представляет собой значение, чьим номером позиции является значение типа универсальный-целый, и это значение соответствует X. Если соответствующее Х универсальное-целое значение не принадлежит диапазону P'POS (P'BASE'FIRST). .P'POS (P'BASE'LAST), то возбуждается исключение CONSTRAINT_ERROR (см. 3.5.5).
P'VALUE(X) | Префикс Р обозначает дискретный тип или подтип. Этот атрибут является функцией с одним параметром. Фактический параметр Х должен быть значением предопределенного типа STRING. Тип результата — базовый тип Р. Любые предшествующие и последующие пробелы последовательности символов, соответствующей X, игнорируются. Если для перечислимого типа последовательность символов имеет синтаксис литерала перечисления и если этот литерал существует для базового типа Р, то результатом является соответствующее значение перечислимого типа. Если для целого типа последовательность символов имеет синтаксис целого литерала, возможно с дополнительным символом плюс или минус, и если соответствующее значение принадлежит базовому типу Р, то результатом является именно это значение. Во всех остальных случаях возбуждается исключение CONSTRAINT_ERROR (CM. 3.5.5).
Р'WIDTH | Префикс Р обозначает дискретный подтип. Вырабатывает максимальную длину образа по всем значениям подтипа Р. (Образ — это последовательность символов, вырабатываемых атрибутом IMAGE.) Значение этого атрибута имеет универсальный-целый тип (см. 3.5.5).
[] Или задаче. - Прим. ред.

Пред. | Уровень выше | След.
14.7. ПРИМЕР ВВОДА-ВЫВОДА | Начало | Приложение B. ПРАГМЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ


Приложение B. ПРАГМЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ
Пред. След.

Приложение B. ПРАГМЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ

Ниже определяются прагмы LIST, PAGE и OPTIMIZE и остальные предопределенные прагмы, которые рассматривались в описании языка.

Прагма | Смысл
CONTROLLED | Единственным аргументом является простое имя ссылочного типа. Эта прагма допустима только непосредственно в разделе описаний или в спецификации пакета, содержащих описание этого ссылочного типа, причем описание должно помещаться перед прагмой. Не допускается использование этой прагмы для производного типа. Прагма указывает, что для объектов, указанных значениями соответствующего ссылочного типа, не должно выполняться автоматическое освобождение памяти, исключая выход из самого вложенного оператора блока, тела подпрограммы или тела задачи, охватывающих описание ссылочного типа либо выход из главной программы (см. 4.8)
ELABORATE | В качестве аргументов используются одно или несколько простых имен, обозначающих библиотечные модули. Эта прагма допустима только непосредственно после спецификатора контекста компилируемого модуля (перед библиотечным или вторичным модулем). Каждый агрумент прагмы должен быть простым именем библиотечного модуля, упомянутого в спецификаторе контекста. Эта прагма указывает, что тело соответствующего библиотечного модуля должно быть предвыполнено до предвыполнения данного компилируемого модуля. Если данный компилируемый модуль является субмодулем, то тело библиотечного модуля должно быть предвыполнено до предвыполнения тела родительского (по отношению к этому субмодулю) библиотечного модуля (см. 10.5).
INLINE | В качестве аргументов используется одно или несколько имен; каждое имя является либо именем подпрограммы, либо именем настраиваемой подпрограммы. Эта прагма допустима только на месте элемента описания в разделе описаний или в спецификации пакета либо же после библиотечного модуля в компиляции, но до любого следующего компилируемого модуля. Прагма указывает на возможную подстановку тела подпрограммы вместо каждого их вызова; в случае настраиваемой подпрограммы эта прагма относится к вызовам ее конкретизации (см. 6.3.2).
INTERFACE | В качестве аргументов используются имя языка и имя подпрограммы. Эта прагма допустима на месте элемента описания и должна применяться к подпрограмме, описанной ранее в виде элемента описания того же самого раздела описаний или спецификации пакета. Эта прагма допустима также для библиотечного модуля; в этом случае прагма должна помещаться после описания подпрограммы и перед любым следующим компилируемым модулем. Эта прагма указывает другой язык (и тем самым соглашения по вызову) и информирует компилятор о том, что для соответствующей подпрограммы будет представлен объектный модуль (см. 13.9).
LIST | В качестве единственного аргумента используется один из идентификаторов ON или OFF. Эта прагма допустима в любом месте, где допустимы прагмы. Прагма указывает, что необходимо продолжить или прекратить вывод листинга компиляции до тех пор, пока в той же компиляции не встретится прагма LIST с другим аргументом. Текст самой прагмы печатается всегда, если компилятор выводит листинг.
MEMORY_SIZE | В качестве единственного аргумента используется числовой литерал. Эта прагма допустима только в начале компиляции, до ее первого компилируемого модуля (если он есть). Применение этой прагмы приводит к использованию указанного числового литерала для определения именованного числа MEMORY_SIZE (см. 13.7).
OPTIMIZE | В качестве единственного аргумента используется один из идентификаторов TIME или SPACE. Эта прагма допустима только внутри раздела описаний и относится к блоку или телу, охватывающему этот раздел описаний. Она указывает главный критерий оптимизации — время выполнения или занимаемую память.
PACK | В качестве единственного аргумента используется простое имя именуемого или индексируемого типа. Допустимое положение этой прагмы в программе и ограничения, относящиеся к именуемому типу, определяются теми же правилами, что и для спецификатора представления. Прагма указывает, что при выборе представления значений данного типа главным критерием оптимизации обязан быть минимум занимаемой памяти (см. 13.1).
PAGE | Эта прагма не имеет аргументов и допустима везде, где допустимы прагмы. Она указывает, что текст программы, следующий за прагмой, должен начинаться с новой страницы (если компилятор параллельно выводит листинг).
PRIORITY | Единственным аргументом этой прагмы является статическое выражение предопределенного целого подтипа PRIORITY. Эта прагма допустима только в спецификации задачи или непосредственно внутри самого внешнего раздела описаний главной программы. Она указывает приоритет этой задачи (или задач этого задачного типа) или приоритет главной программы (см. 9.8).
SHARED | В качестве единственного аргумента этой прагмы используется простое имя переменной. Эта прагма допустима только для переменной, описанной посредством описания объекта скалярного или ссылочного типа. И описание переменной, и прагма должны находиться (в указанном порядке) в одном и том же разделе описаний или в спецификации пакета. Эта прагма указывает, что каждое чтение или изменение значения этой переменной является ее точкой синхронизации. Реализация должна ограничивать круг объектов, для которых допустимо использование этой прагмы, теми объектами, прямое чтение или прямое изменение значения которых реализуются как неделимые операции (см. 9.11).
STORAGE_UNIT | В качестве единственного аргумента используется числовой литерал. Эта прагма допустима только в начале компиляции, до первого ее компилируемого модуля (если он есть). Применение этой прагмы приводит к использованию для определения именованного числа STORAGE_UNIT значения заданного числового литерала (см. 13.7).
SUPPRESS | В качестве аргументов используются идентификатор проверки, а также имя объекта, типа или подтипа, подпрограммы, задачного модуля или настраиваемого модуля. Эта прагма допустима только непосредственно либо в разделе описаний, либо в спецификации пакета. В последнем случае единственным допустимым вариантом является использование имени, обозначающего понятие (или несколько совмещенных подпрограмм), описанное непосредственно внутри этой спецификации. Разрешение подавить указанную проверку действует от прагмы до конца области действия описаний, соответствующей самому вложенному оператору блока или программному модулю. Для
 | прагмы, используемой в спецификации пакета, это разрешение действительно до конца области действия описания, заданного своим именем понятия. Если в качестве аргумента прагмы используется имя, то разрешение на подавление указанной проверки ограничивается следующими правилами: это разрешение распространяется только на операции над указанными объектами базового типа указанного типа или подтипа, на вызовы указанной подпрограммы, на активизацию задач указанного задачного типа, на конкретизацию указанного настраиваемого модуля (см. 11.7).
SYSTEM_NAME | Единственным аргументом прагмы является литерал перечисления. Эта прагма допустима только в начале компиляции, до первого ее компилируемого модуля (если он есть). Применение прагмы приводит к использованию литерала перечисления, заданного идентификатором, для определения константы SYSTEM_NAME. Прагма допустима только в том случае, если указанный в ней идентификатор соответствует одному из литералов перечисления типа NAME, описанного в пакете SYSTEM (см. 13.7).

Пред. | Уровень выше | След.
Приложение A. АТРИБУТЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ | Начало | Приложение C. ПРЕДОПРЕДЕЛЕННОЕ ОКРУЖЕНИЕ ЯЗЫКА


Приложение C. ПРЕДОПРЕДЕЛЕННОЕ ОКРУЖЕНИЕ ЯЗЫКА
Пред. След.

Приложение C. ПРЕДОПРЕДЕЛЕННОЕ ОКРУЖЕНИЕ ЯЗЫКА

Ниже дана спецификация пакета STANDARD, содержащая все предопределенные в языке идентификаторы. Соответствующее тело пакета определено реализацией и не показано.

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

package STANDARD is

   type BOOLEAN is (FALSE, TRUE);

   -- Предопределенными операциями отношения
   -- для этого типа являются следующие:

   -- function "="   (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function "/="  (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function "<"   (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function "<="  (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function ">"   (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function ">="  (LEFT, RIGHT : BOOLEAN) return BOOLEAN;

   -- Предопределенными логическими операциями
   -- для этого типа являются следующие:

   -- function "and" (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function "or"  (LEFT, RIGHT : BOOLEAN) return BOOLEAN;
   -- function "xor" (LEFT, RIGHT : BOOLEAN) return BOOLEAN;

   -- function "not" (RIGHT : BOOLEAN) return BOOLEAN;

   -- Предопределен универсальный тип универсальный, целый.

   type INTEGER is определен-реализацией;

   -- Для этого типа предопределены следующие операции:

   -- function "="  (LEFT, RIGHT : INTEGER) return BOOLEAN;
   -- function "/=" (LEFT, RIGHT : INTEGER) return BOOLEAN;
   -- function "<"  (LEFT, RIGHT : INTEGER) return BOOLEAN;
   -- function "<=" (LEFT, RIGHT : INTEGER) return BOOLEAN;
   -- function ">"  (LEFT, RIGHT : INTEGER) return BOOLEAN;
   -- function ">=" (LEFT, RIGHT : INTEGER) return BOOLEAN;

   -- function "+"   (RIGHT : INTEGER) return INTEGER;
   -- function "-"   (RIGHT : INTEGER) return INTEGER;
   -- function "abs" (RIGHT : INTEGER) return INTEGER;

   -- function "+"   (LEFT, RIGHT : INTEGER) return INTEGER;
   -- function "-"   (LEFT, RIGHT : INTEGER) return INTEGER;
   -- function "*"   (LEFT, RIGHT : INTEGER) return INTEGER;
   -- function "/"   (LEFT, RIGHT : INTEGER) return INTEGER;
   -- function "rem" (LEFT, RIGHT : INTEGER) return INTEGER;
   -- function "mod" (LEFT, RIGHT : INTEGER) return INTEGER;

   -- function "**"  (LEFT : INTEGER; RIGHT : INTEGER) return INTEGER;

   -- Реализация может обеспечить другие предопределенные целые типы. Рекомендуется, чтобы
   -- имена этих дополнительных типов оканчивались на INTEGER, например, SHORT_INTEGER или
   -- LONG_INTEGER. Спецификация каждой операции для типа универсальный-целый или для
   -- любого дополнительного предопределенного целого типа может быть получена заменой
   -- идентификатора INTEGER на имя этого типа в спецификации соответствующей операции для
   -- типа INTEGER исключая правый операнд операции возведения в степень.

   -- Универсальный тип универсальный-вещественный предопределен.

   type FLOAT is определен-реализацией;

   -- Для этого типа предопределены следующие операции:

   -- function "="   (LEFT, RIGHT : FLOAT) return BOOLEAN;
   -- function "/="  (LEFT, RIGHT : FLOAT) return BOOLEAN;
   -- function "<"   (LEFT, RIGHT : FLOAT) return BOOLEAN;
   -- function "<="  (LEFT, RIGHT : FLOAT) return BOOLEAN;
   -- function ">"   (LEFT, RIGHT : FLOAT) return BOOLEAN;
   -- function ">="  (LEFT, RIGHT : FLOAT) return BOOLEAN;

   -- function "+"   (RIGHT : FLOAT) return FLOAT;
   -- function "-"   (RIGHT : FLOAT) return FLOAT;
   -- function "abs" (RIGHT : FLOAT) return FLOAT;

   -- function "+"   (LEFT, RIGHT : FLOAT) return FLOAT;
   -- function "-"   (LEFT, RIGHT : FLOAT) return FLOAT;
   -- function "*"   (LEFT, RIGHT : FLOAT) return FLOAT;
   -- function "/"   (LEFT, RIGHT : FLOAT) return FLOAT;

   -- function "**"  (LEFT : FLOAT; RIGHT : INTEGER) return FLOAT;

   -- Реализация может обеспечить дополнительные предопределенные плавающие типы.
   -- Рекомендуется, чтобы имена таких дополнительных типов оканчивались на FLOAT,
   -- например SHORT_FLOAT  или  LONG_FLOAT.  Спецификация  каждой  операции  для
   -- типа универсальный-вещественный или для любого дополнительного
   -- предопределенного плавающего типа может быть получена заменой идентификатора FLOAT
   -- на имя этого типа в спецификации соответствующей операции для типа FLOAT.
   -- Кроме того, для универсальных типов предопределены следующие операции:

   -- function "*" (LEFT : универсальный целый;; RIGHT : универсальный-вещественный)
      return универсальный-вещественный;

   -- function "*" (LEFT : универсальный-вещественный;    RIGHT : универсальный целый;)
      return универсальный-вещественный;

   -- function "/" (LEFT : универсальный-вещественный;    RIGHT : универсальный целый;)
      return универсальный-вещественный;

   -- Тип универсальный-фиксированный предопределен. Единственными операциями, описанными
   -- для этого типа, являются

   -- function "*" (LEFT : любой-фиксированный-тип; RIGHT : любой-фиксированный-тип)
      return universal_fixed;

   -- function "/" (LEFT : любой-фиксированный-тип; RIGHT : любой-фиксированный-тип)
      return universal_fixed;

   -- Следующие символы образуют стандартный набор символов
   -- ASCII. Символьные литералы, соответствующие управляющим символам, идентификаторами не
   -- являются. В этом определении они выделены курсивом.

   type CHARACTER is

          (nul,  soh,  stx,  etx,     eot,  enq,  ack,  bel,
           bs,   ht,   lf,   vt,      ff,   cr,   so,   si,
           dle,  dc1,  dc2,  dc3,     dc4,  nak,  syn,  etb,
           can,  em,   sub,  esc,     fs,   gs,   rs,   us,

           ' ',  '!',  '"',  '#',     '$',  '%',  '&',  ''',
           '(',  ')',  '*',  '+',     ',',  '-',  '.',  '/',
           '0',  '1',  '2',  '3',     '4',  '5',  '6',  '7',
           '8',  '9',  ':',  ';',     '<',  '=',  '>',  '?',

           '@',  'A',  'B',  'C',     'D',  'E',  'F',  'G',
           'H',  'I',  'J',  'K',     'L',  'M',  'N',  'O',
           'P',  'Q',  'R',  'S',     'T',  'U',  'V',  'W',
           'X',  'Y',  'Z',  '[',     '\',  ']',  '~',  '_',

           '`',  'a',  'b',  'c',     'd',  'e',  'f',  'g',
           'h',  'i',  'j',  'k',     'l',  'm',  'n',  'o',
           'p',  'q',  'r',  's',     't',  'u',  'v',  'w',
           'x',  'y',  'z',  '{',     '|',  '}',  '~',  del);

  for CHARACTER use  --  128 ASCII character set without holes
       (0, 1, 2, 3, 4, 5, ..., 125, 126, 127);

  -- Предопределенные операции для типа CHARACTER те же самые, что и для любого перечислимого типа.

  package ASCII is

      --  Управляющие символы:

      NUL   : constant CHARACTER := nul;     SOH   : constant CHARACTER := soh:
      STX   : constant CHARACTER := stx;     ETX   : constant CHARACTER := etx;
      EOT   : constant CHARACTER := eot;     ENQ   : constant CHARACTER := enq:
      ACK   : constant CHARACTER := ack;     BEL   : constant CHARACTER := bel;
      BS    : constant CHARACTER := bs;      HT    : constant CHARACTER := ht;
      LF    : constant CHARACTER := lf;      VT    : constant CHARACTER := vt;
      FF    : constant CHARACTER := ff;      CR    : constant CHARACTER := cr;
      SO    : constant CHARACTER := so;      SI    : constant CHARACTER := si;
      DLE   : constant CHARACTER := dle;     DC1   : constant CHARACTER := dc1;
      DC2   : constant CHARACTER := dc2;     DC3   : constant CHARACTER := dc3;
      DC4   : constant CHARACTER := dc4;     NAK   : constant CHARACTER := nak;
      SYN   : constant CHARACTER := syn;     ETB   : constant CHARACTER := etb;
      CAN   : constant CHARACTER := can;     EM    : constant CHARACTER := em:
      SUB   : constant CHARACTER := sub;     ESC   : constant CHARACTER := esc;
      FS    : constant CHARACTER := fs;      GS    : constant CHARACTER := gs;
      RS    : constant CHARACTER := rs;      US    : constant CHARACTER := us;
      DEL   : constant CHARACTER := del;

      -- Другие символы:

      EXCLAM   : constant CHARACTER := '!';  QUOTATION : constant CHARACTER := '"';
      SHARP    : constant CHARACTER := '#';  DOLLAR    : constant CHARACTER := '$';
      PERCENT  : constant CHARACTER := '%';  AMPERSAND : constant CHARACTER := '&';
      COLON    : constant CHARACTER := ':';  SEMICOLON : constant CHARACTER := ';';
      QUERY    : constant CHARACTER := '?';  AT_SIGN   : constant CHARACTER := '@';
      L_BRACKET: constant CHARACTER := '[';  BACK_SLASH: constant CHARACTER := '\';
      R_BRACKET: constant CHARACTER := ']';  CIRCUMFLEX: constant CHARACTER := '~';
      UNDERLINE: constant CHARACTER := '_';  GRAVE     : constant CHARACTER := '`';
      L_BRACE  : constant CHARACTER := '{';  BAR       : constant CHARACTER := '|';
      R_BRACE  : constant CHARACTER := '}';  TILDE     : constant CHARACTER := '~';

      -- Строчные буквы:

      LC_A : constant CHARACTER := 'a';
      ...
      LC_Z : constant CHARACTER := 'z';

   end ASCII;

       -- Предопределенные подтипы:

       subtype NATURAL  is INTEGER range 0 .. INTEGER'LAST;
       subtype POSITIVE is INTEGER range 1 .. INTEGER'LAST;

       -- Предопределенный строковой тип:

       type STRING is array(POSITIVE range <>) of CHARACTER;

       pragma PACK(STRING);

       -- Следующие операции для этого типа предопределены:

       -- function "="  (LEFT, RIGHT : STRING) return BOOLEAN;
       -- function "/=" (LEFT, RIGHT : STRING) return BOOLEAN;
       -- function "<"  (LEFT, RIGHT : STRING) return BOOLEAN;
       -- function "<=" (LEFT, RIGHT : STRING) return BOOLEAN;
       -- function ">"  (LEFT, RIGHT : STRING) return BOOLEAN;
       -- function ">=" (LEFT, RIGHT : STRING) return BOOLEAN;

       -- function "&" (LEFT : STRING;    RIGHT : STRING)    return STRING;
       -- function "&" (LEFT : CHARACTER; RIGHT : STRING)    return STRING;
       -- function "&" (LEFT : STRING;    RIGHT : CHARACTER) return STRING;
       -- function "&" (LEFT : CHARACTER; RIGHT : CHARACTER) return STRING;

  type DURATION is delta определен-реализацией range определен-реализацией;

    -- Для типа DURATION предопределены все те операции,
    -- что и для любого фиксированного типа

    -- Предопределены следующие исключения:

   CONSTRAINT_ERROR : exception;
   NUMERIC_ERROR    : exception;
   PROGRAM_ERROR    : exception;
   STORAGE_ERROR    : exception;
   TASKING_ERROR    : exception;

end STANDARD;

Некоторые аспекты предопределенных понятий не могут быть выражены в терминах самого языка. Хотя, например, перечислимый тип BOOLEAN может быть записан посредством двух литералов перечисления FALSE и TRUE, формы управления промежуточной проверкой в самом языке выражены быть не могут.

Примечание. Определением языка предопределены следующие библиотечные модули:

  • пакет CALENDAR

  • пакет SYSTEM

  • пакет MACHINE_CODE(ecnu он предусмотрен)

  • настраиваемая процедура UNCHECKED_DEALLOCATION

  • настраиваемая функция UNCHECKED_CONVERSION

  • настраиваемый пакет SEQUENTIAL_IO

  • настраиваемый пакет DIRECT_IO

  • пакет TEXT_IO

  • пакет IO_EXCEPTIONS

  • пакет LOW_LEVEL_IO

Пред. | Уровень выше | След.
Приложение B. ПРАГМЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ | Начало | Приложение D. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ


Приложение D. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ
Пред. След.

Приложение D. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ

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

Агрегат (aggregate) — базовая операция над типом, которая объединяет значения компонент в составное значение индексируемого типа (агрегат массива) или именуемого типа (агрегат записи), являющихся разновидностями составного типа. Компоненты агрегата могут быть позиционными (координатными) и/или именованными (ключевыми).

Атрибут (attribute) — базовая операция над типом, которая вырабатывает предопределенную характеристику поименованного понятия, указанного префиксом; некоторые атрибуты являются функциями, типом или диапазоном.

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

Вид (mode), см. параметр.

Видимость (visibility) — доступность характеристик описанного понятия при его применении в данной точке текста программы. Описание понятия, вводящее идентификатор, называется видимым в данной точке текста программы, если это понятие осмысленно при появлении его идентификатора в этой точке программы. Прямая видимость подразумевает одно описание понятия с характеристиками, уникальными в области действия, и некоторое число использовании этого понятия. При именовании описание видимо на месте постфикса в именуемой компоненте или на месте имени в именованном сопоставлении. Иначе, описание видимо непосредственно всякий раз, когда единственный идентификатор имеет этот смысл.

Видимый раздел (visible part), см. пакет.

Возбуждение исключения (raising an exception), см. исключение.

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

Вычисление (evaluation) — процесс получения значения (например, выражения}. Этот процесс происходит во время выполнения программы.

Выражение (expression) — формула, определяющая процесс получения значения.

Генератор (allocator) — базовая операция над типом, создающая объект и вырабатывающая ссылочное значение, которое указывает на этот объект. Созданный объект должен сохраняться до тех пор, пока существует обозначение объекта некоторым именем.

Диапазон (range) — упорядоченный набор последовательных значений скалярного типа. Диапазон задается нижней и верхней границами этого набора значений. Значение из диапазона называется принадлежащим этому диапазону.

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

Дискриминант (discriminant) — специальный компонент объекта или значение именуемого типа. Подтипы других компонентов и даже их присутствие или отсутствие могут зависеть от значения дискриминанта.

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

Именованное сопоставление (named association) — способ задания связи элемента составного значения с одной или несколькими позициями с помощью их именования.

Именуемая компонента (selected component) — имя, состоящее из префикса и идентификатора, называемого постфиксом. Именуемые компоненты используются для обозначения компонент записей, входов и объектов, указанных ссылочными значениями; они также используются как расширенные имена.

Именуемый тип (record type) — составной тип из именованных различными идентификаторами компонент, которые обычно бывают различных типов или подтипов. Для каждой компоненты значения записи или объекта-записи в определении именуемого типа задается идентификатор, который однозначно определяет компоненту записи.

Имя (name) — средство представления понятия. Говорят, что имя обозначает понятие и что понятие является смыслом имени. См. также описание, префикс.

Индекс (index), см. индексируемый тип.

Индексируемая компонента (indexed component) — форма имени, содержащая выражения, которые задают значения индексов компоненты массива. Индексируемая компонента обозначает компоненту массива. Индексируемая компонента может также обозначать вход в семействе входов.

Индексируемый тип (array type) — составной тип из компонент одного и того же подтипа (и следовательно, одного и того же типа). Каждая компонента однозначно идентифицируется индексом (для одномерного массива) или последовательностью индексов (для многомерного массива). Каждый индекс должен быть значением дискретного типа и принадлежать требуемому диапазону индексов.

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

Квалифицированное выражение (qualified expression) — выражение, перед которым указан его тип или подтип. Используется для разрешения неоднозначности выражения (например, из-за совмещения).

Компилируемый модуль (compilation unit) — описание или тело программного модуля, предназначенные для компиляции в качестве самостоятельного текста. Перед ним может быть задан спецификатор контекста, включающего другие компилируемые модули, от которых зависит данный и имена которых указаны в спецификаторах совместимости.

Компонента (component) — значение, которое является частью более сложного значения, или объект, который является частью более сложного объекта.

Константа (constant), см. объект.

Лексема (lexical element) — лексический элемент, который может быть идентификатором, литералом, ограничителем или комментарием.

Лимитируемый тип (limited type) — тип, для которого не определены неявно описанные операции присваивания и предопределенного сравнения на равенство. Все заданные типы — лимитируемые. Личный тип может быть определен как лимитируемый. Для лимитируемого типа может быть явно описана операция сравнения на равенство.

Литерал (literal) — значение, явно выраженное буквами, цифрами или другими символами. Литерал — это одно из четырех: числовой литерал, литерал перечисления, символьный литерал или строковый литерал.

Личный раздел (private part), см. пакет.

Личный тип (private type) — тип, структура и набор значений которого явно определены, но непосредственно недоступны для пользователя. О личном типе известны только его дискриминанты (если они есть) и набор операций, определенных над его значениями. Личный тип и соответствующие операции определяются в видимом разделе пакета или в разделе формальных параметров настройки. Для личных типов, не являющихся лимитируемыми, определены также операции присваивания, сравнения на равенство и неравенство.

Модельное число (model number) — точно представляемое значение вещественного типа. Операции над вещественными типами определяются в терминах операций над модельными числами этих типов. Свойства модельных чисел и операции над ними являются минимальными свойствами, предписанными для всех реализации вещественных чисел.

Набор (collection) — вся совокупность объектов, создаваемых вычислением генераторов для некоторого ссылочного типа.

Настраиваемый модуль (generic unit) — шаблон для множества подпрограмм или пакетов. Создаваемые с использованием этого шаблона подпрограмма или пакет называются экземплярами данного настраиваемого модуля. Конкретизация настройки является видом описания, которое создает экземпляр. Настраиваемый модуль пишется в виде подпрограммы или пакета с предшествующим спецификации разделом формальных параметров настройки. Формальным параметром настройки является либо тип, либо подпрограмма, либо объект. Настраиваемый модуль — это один из видов программных модулей. Область действия (scope), см. описание. Обозначить (denote), см. описание. Обработчик (handler), см. исключение.

Объект (object) — понятие, которое обладает значением некоторого типа. Программа создает объект либо при предвыполнении описания объекта, либо при вычислении генератора. Описание или генератор задают тип объекта, объект может обладать значением только этого типа.

Офаничение (constraint) — средство выделения подмножества значений типа. Принадлежащее этому подмножеству значение удовлетворяет ограничению.

Ограничение диапазона (range constraint) — способ определения диапазона типа, т. е. подмножества значений этого типа, принадлежащих диапазону.

Ограничение дискриминанта (discriminant constraint) — способ определения дискриминанта для именуемого типа или личного типа.

Ограничение индекса (index constraint) — определение ограничения в задании нижней и верхней границ для каждого индекса индексируемого типа.

Оператор (statement) — синтаксическая конструкция, определяющая одно или несколько действий, реализуемых во время выполнения программы.

Оператор блока (block statement) — составной оператор, который может содержать последовательность операторов. Он может также содержать раздел описаний и обработчики исключений, которые являются локальными в данном операторе блока.

Оператор принятия (accept statement), см. вход.

Операция (operator) — ограничитель или зарезервированное слово, используемое для указания алгоритма преобразования значений одного или двух операндов в результат заданного типа. Унарную операцию записывают перед операндом; бинарную операцию — между двумя операндами. Операция — это специальный вид вызова функции. Операция может быть описана как функция. Многие операции неявно описываются описанием типа (например, большинство описаний типа подразумевает описание операции сравнения на равенство для значений этого типа).

Операция типа (operation) — элементарное действие, связанное с одним или несколькими типами. Операция типа [8] неявно описывается при описании этого типа либо является подпрограммой, которая имеет параметр или результат заданного типа.

Описание (declaration) — синтаксическая конструкция, которая связывает идентификатор (или другие' обозначения) с понятием. Это сопоставление внутри области текста, называемой областью действия описания. Внутри области действия описания существуют места использования идентификатора для ссылки на связанное с ним понятие. Идентификатор, употребляемый в таких местах, называется простым именем понятия; говорят, что имя обозначает связанное с ним понятие.

Описание переименования (renaming declaration) — описание другого имени понятия. Пакет (package) — программный модуль, который определяет группу логически связанных понятий, таких как типы, объекты этих типов и подпрограммы с параметрами этих типов. Пакет состоит из описания пакета и тела пакета. Описание пакета имеет видимый раздел, содержащий описания всех понятий, которые могут быть явно использованы вне пакета. Он может содержать также личный раздел с деталями реализации, которые заканчивают спецификацию видимых понятий, но которые недоступны для пользователя пакета. Тело пакета содержит реализации подпрограмм (и, возможно, задач), которые заданы в описании пакета. Пакет — это один из видов программного модуля.

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

Переменная (variable), см. объект.

Перечислимый тип (enumeration type) — дискретный тип, значения которого представляются литералами перечисления, заданными явно в описании типа. Эти литералы перечисления являются либо идентификаторами, либо символьными литералами.

Плавающий тип (floating point type), см. вещественный тип.

Подкомпонента (subcomponent) — компонента либо компонента другой компоненты или подкомпоненты.

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

Подтип (subtype) — набор значений данного типа, определяемый ограничением типа. Каждое значение из множества значений подтипа принадлежит этому подтипу и удовлетворяет ограничению, определяющему подтип.

Позиционное сопоставление (positional association) — способ задания связи элемента с позицией, использующий позицию размещения элемента для определения этого элемента.

Постфикс (selector), см. именуемая компонента.

Прагма (pragma) — языковая конструкция для передачи информации компилятору.

Предвыполнение (elaboration) — процесс, применяемый к описанию, в результате которого описание выполняет свое назначение (например, создается объект). Этот процесс происходит при выполнении программы.

Префикс (prefix) — начальная часть некоторых видов имени. Префикс — это либо вызов функции, либо имя.

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

Программа (program) — совокупность из нескольких компилируемых модулей, один из которых является подпрограммой, называемой главной программой. Выполнение программы состоит из выполнения главной программы, которая может вызвать подпрограммы, описанные в других компилируемых модулях программы.

Программный модуль (program unit) — либо настраиваемый модуль, либо пакет, либо подпрограмма, либо задачный модуль.

Производный тип (derived type) — тип, значения и операции которого есть копии значений и операций существующего типа. Существующий тип называется родительским типом производного типа.

Простое имя (simple name), см. описание, имя.

Процедура (procedure), см. подпрограмма.

Прямая видимость (direct visibility), см. видимость.

Раздел вариантов (variant part) — определяет альтернативные компоненты записи в зависимости от значения дискриминанта записи. Каждое значение дискриминанта устанавливает одну из альтернатив раздела вариантов.

Раздел описаний (declarative part) — последовательность описаний. Он может также содержать логически связанную информацию, например тела подпрограмм и спецификаторы представления.

Рандеву (rendezvous) — взаимодействие между двумя параллельно выполняемыми задачами, когда одна задача вызвала вход другой задачи, и в вызванной задаче для этого вызова выполняется соответствующий оператор принятия.

Расширенное имя (expanded name) — способ обозначения понятия, которое описано непосредственно внутри некоторой конструкции. Расширенное имя имеет форму именуемой компоненты: префикс обозначает конструкцию {программный модуль или блок, цикл или оператор принятия}, постфикс — это простое имя понятия.

Родительский тип (parent type), см. производный тип.

Скалярный тип (scalar type) — упорядоченный набор значений с операциями отношения. К скалярному типу относится дискретный или вещественный тип. Объект или значение скалярного типа не имеет компонент.

Совмещение (overloading) — свойство понятия иметь несколько альтернатвпыл паопачо-ний в данной точке программного текста. Например, совмещенным литералом перечисления может быть идентификатор, который появляется в определениях нескольких перечислимых типов. Реальный смысл совмещенного идентификатора определяется по контексту. Совмещенными могут быть также подпрограммы, агрегаты, генераторы и строковые литералы.

Составной тип (composite type) — тип, значения которого имеют компоненты. Существуют две разновидности составного типа: индексируемые типы и именуемые типы.

Спецификатор использования (use clause) — средство, обеспечивающее прямую видимость описаний, которые находятся в видимых разделах именованных пакетов. Спецификатор контекста (context clause), см. компилируемый модуль. Спецификатор представления (representation clause) — средство указания компилятору отображения типа, объекта или задачи на архитектуру объектной машины, на которой выполняется программа. В некоторых случаях спецификаторы представления полностью определяют отображение, в других случаях они задают критерии выбора отображения. Спецификатор совместности (with clause), см. компилируемый модуль. Ссылочный тип (access type) — набор значений (ссылочные значения}, которые могут быть либо пустым значением, либо значением, указывающим объект, созданный генератором. Значение указанного объекта может быть прочитано или изменено через ссылочное значение. Определение ссылочного типа задает тип объектов, на которые указывают значения ссылочного типа. См. также набор.

Субмодуль (subunit), см. тело.

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

Тип (type) — набор значений и набор операций типа, применимых к этим значениям. Определение типа — это языковая конструкция, которой вводится тип. Конкретный тип — это ссылочный тип, индексируемый тип, личный тип, именуемый тип, скалярный тип или задачный тип.

Удовлетворять (satisfy), см. ограничение, подтип. Указывать (designate), см. ссылочный тип, задача. Фактический параметр (actual parameter), см. параметр. Фиксированный тип (fixed point type), см. вещественный тип. Формальный параметр (formal parameter), см. параметр. Функция (function), см. подпрограмма.

Целый тип (integer type) — дискретный тип, значения которого представляют все целые числа в заданном диапазоне.

Экземпляр (instance), см. настраиваемый мрдуль.

[8] Вместо термина "операция типа" в стандарте используется термин "операция", который не вызывает неоднозначности при его использовании в контексте. -- Прим. ред.

Пред. | Уровень выше | След.
Приложение C. ПРЕДОПРЕДЕЛЕННОЕ ОКРУЖЕНИЕ ЯЗЫКА | Начало | Приложение E. СВОДКА СИНТАКСИСА


Приложение E. СВОДКА СИНТАКСИСА
Пред. След.

Приложение E. СВОДКА СИНТАКСИСА

Пред. | Уровень выше | След.
Приложение D. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ | Начало | Приложение F. ХАРАКТЕРИСТИКИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ


Приложение F. ХАРАКТЕРИСТИКИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ
Пред.

Приложение F. ХАРАКТЕРИСТИКИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ

Определение языка Ада допускает машинную зависимость в контролируемых пределах. Не допускаются машинно-зависимые расширения, ограничения синтаксиса и семантики. Машинная зависимость допускается только в определенных реализацией прагмах и атрибутах, в машинно-зависимых соглашениях, перечисленных в гл. 13, а также в ограничениях на использование спецификаторов представления.

Справочное руководство по каждой реализации языка программирования Ада должно включать в себя такое приложение (называемое приложением F), которое описывает все характеристики, зависящие от реализации. В таком приложении для данной реализации должны быть перечислены:

1. Форма, допустимые места расположения и результат каждой зависящей от реализации прагмы.

2. Имя и тип каждого атрибута, зависящего от реализации.

3. Спецификация пакета SYSTEM (см. 13.7).

4. Список всех ограничений на спецификаторы представления (см. 13.1).

5. Соглашения об использовании генерируемых реализацией имен, обозначающих компоненты, зависящие от реализации (см. 13.4).

6. Интерпретация выражений, появляющихся в спецификаторах адреса, включая связанные с прерываниями (см. 13.5).

7. Любое ограничение на неконтролируемые преобразования (см. 13.10.2).

8. Любые зависящие от реализации особенности для пакетов ввода-вывода (см. 14).

Пред. | Уровень выше
Приложение E. СВОДКА СИНТАКСИСА | Начало


Глава 1. ВВЕДЕНИЕ
Пред. След.

Глава 1. ВВЕДЕНИЕ

Содержание

1.1. ОБЛАСТЬ ДЕЙСТВИЯ СТАНДАРТА
1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА
1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ
1.4. ОБЗОР СВОЙСТВ ЯЗЫКА
1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ
1.6. КЛАССИФИКАЦИЯ ОШИБОК

Ада — это язык программирования, разработанный в соответствии с так называемыми стилмановскими требованиями, определенными МО США. Более того, эти требования определили язык с мощными выразительными возможностями, пригодный для широкого класса задач. Вследствие этого языку Ада присущи как свойства классических языков, подобных языку Паскаль, так и свойства, характерные для специализированных языков. Таким образом, этот язык является современным алгоритмическим языком с традиционными управляющими структурами и средствами определения типов и подпрограмм. Он также удовлетворяет требованию модульности; данные, типы и подпрограммы могут образовывать пакеты. Модульность понимается и в физическом смысле, что обеспечивается раздельной компиляцией модулей.

В дополнение к указанному язык обеспечивает программирование задач реального времени с возможностями моделирования параллельных задач и обработки исключений. Он пригоден также для системного программирования; это требует прецизионного управления представлением данных и доступа к зависимым от системы параметрам. Наконец, в языке определены пользовательский и машинный уровни ввода-вывода.

1.1. ОБЛАСТЬ ДЕЙСТВИЯ СТАНДАРТА

В данном стандарте описаны форма представления и семантика программных модулей, написанных на языке Ада. Цель стандарта — повысить переносимость Ада-программ.

1.1.1. СОДЕРЖАНИЕ СТАНДАРТА

Данный стандарт определяет:

а) форму представления программного модуля, написанного на языке Ада;

б) результаты трансляции и выполнения такого программного модуля;

в) способ получения Ада-программ из набора программных модулей;

г) предопределенные программные модули, которые должна обеспечивать согласованная со стандартом реализация (далее в тексте — согласованная реализация);

д) допустимые в рамках стандарта изменения и способы их задания;

е) те нарушения стандарта, которые обязана обнаруживать согласованная реализация, а также результат попытки транслировать или выполнить программный модуль, содержащий такие нарушения;

ж) те нарушения стандарта, которые согласованная реализация не обязана обнаруживать.

Этот стандарт не определяет:

з) средства преобразования программного модуля, написанного на языке Ада, в объектный код, выполняемый процессором;

и) средства запуска трансляции, выполнения программных модулей и управления ими;

к) размер и скорость выполнения объектного кода, а также относительную скорость выполнения различных языковых конструкций;

л) форму и содержание любых листингов, создаваемых реализациями, в частности форму и содержание сообщений об ошибках или предупреждающих сообщений;

м) результат выполнения программного модуля, содержащего любое нарушение стандарта, которое согласованная реализация не обязана обнаруживать;

н) предельный размер программы или программного модуля для конкретной согласованной реализации.

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

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

• порядок выполнения операторов в различных параллельных задачах при отсутствии явной синхронизации.

1.1.2. СОГЛАСОВАННОСТЬ РЕАЛИЗАЦИИ СО СТАНДАРТОМ

Согласованная реализация должна:

а) корректно транслировать и выполнять правильные программные модули, написанные на языке Ада, если только их объем находится в допустимых для реализации пределах;

б) отвергать все программные модули, объем которых больше допускаемого реализацией;

в) отвергать все программные модули, содержащие ошибки, обнаружение которых предусмотрено стандартом;

г) обеспечивать всеми предопределенными программными модулями, предусмотренными стандартом;

д) содержать только те изменения, которые допускает стандарт;

е) описывать допустимые изменения способом, разрешенным стандартом.

Пред. | Уровень выше | След.
ПРЕДИСЛОВИЕ | Начало | 1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА


1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА
Пред. Глава 1. ВВЕДЕНИЕ След.

1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА

Это справочное руководство содержит четырнадцать глав, три дополнения, три приложения, указатель терминов и синтаксис.

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

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

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

• 1.3. Цели и источники разработки

• 1.4. Обзор свойств языка

• Примеры, примечания и ссылки, приведенные в конце любого раздела

• Каждый подраздел, заголовок которого начинается со слов «Пример» или «Примеры»

Пред. | Уровень выше | След.
Глава 1. ВВЕДЕНИЕ | Начало | 1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ


1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ
Пред. Глава 1. ВВЕДЕНИЕ След.

1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ

Язык был разработан, исходя из трех противоречивых требований:

• обеспечить надежность и сопровождение программ;

• поддерживать программирование как вид человеческой деятельности;

• обеспечить эффективность программ.

Необходимость в языках, повышающих надежность и упрощающих сопровождение, является установленным фактом. В языке Ада предпочтение было отдано удобочитаемости программы по сравнению с легкостью ее написания. Например, правила языка требуют, чтобы все переменные и их типы были явно описаны в программе. Далее, тип переменной неизменен, и компилятор может гарантировать совместимость операций над переменными со свойствами, присущими объектам этого типа. Более того, чтобы избежать обозначений, которые могут привести к ошибкам, в синтаксисе языка было отдано предпочтение конструкциям, которые ближе к естественному языку, чем к каким-то кодированным формам. Наконец, язык поддерживает раздельную компиляцию программных модулей способом, облегчающим разработку и сопровождение программ и обеспечивающим один и тот же уровень контроля для межмодульных и внутримодульных связей.

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

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

При создании любого языка нельзя избежать проблемы эффективности. Языки, которые требуют сверхсложных компиляторов или приводят к неэффективному использованию памяти и времени выполнения программы, дают неэффективные результаты на всех машинах и для всех программ. При создании языка Ада каждая его конструкция оценивалась с точки зрения современных методов реализации. Отвергались все те конструкции, которые были недостаточно ясными или требовали чрезмерных машинных ресурсов.

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

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

Другое обстоятельство, существенно упростившее разработку, было следствием приобретенного ранее опыта реализации удачных проектов с целями, подобными указанным выше, на базе языка Паскаль. Такими языками являются языки Евклид, Лис, Меса, Модула и Сью. Многие из ключевых идей и синтаксических форм этих языков имеют аналоги в языке Ада. Некоторые существующие языки, такие как Алгол-68 и Симула, а также современные проекты языков Альфард и Клу, также повлияли на разработку языка, хотя и в меньшей степени, чем языки семейства Паскаль.

Наконец, большое значение для определения стандарта языка имели его начальная разработка (язык «Зеленый»), проекты языков «Красный», «Голубой» и «Желтый», рассмотрение различных стадий проекта и тысячи замечаний, полученных из 15 стран на предварительных этапах разработки и в процессе голосования при стандартизации, — все это оказало значительное влияние на определение стандарта языка.

Пред. | Уровень выше | След.
1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА | Начало | 1.4. ОБЗОР СВОЙСТВ ЯЗЫКА


1.4. ОБЗОР СВОЙСТВ ЯЗЫКА
Пред. Глава 1. ВВЕДЕНИЕ След.

1.4. ОБЗОР СВОЙСТВ ЯЗЫКА

Ада-программа представляет собой один или несколько программных модулей, которые могут компилироваться раздельно. Программные модули — это подпрограммы (определяющие выполняемый алгоритм), пакеты (определяющие наборы понятий), модули-задачи (определяющие параллельные вычисления) или настраиваемые модули (определяющие параметризованные пакеты и подпрограммы). Каждый модуль обычно состоит из двух частей: спецификации, содержащей видимую для других модулей информацию, и тела, содержащего детали реализации, о которых другие модули не обязаны знать.

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

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

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

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

Функция — это средство вызова действий по вычислению значения. Она подобна процедуре, но в результате выполнения еще и возвращает значение.

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

Задачный модуль — это основной модуль для определения задачи, последовательность действий которой может выполняться параллельно с выполнением других задач. Такие задачи могут быть реализованы на многомашинной или многопроцессорной системе либо чередованием выполнения задач на одном процессоре. Задачный модуль может определить или одну выполняемую задачу, или задачный тип, позволяющий создать любое количество подобных задач.

Описания и операторы . Тело программного модуля, как правило, содержит две части: раздел описаний, который определяет логические понятия, используемые в программном модуле, и последовательность операторов, определяющую выполнение этого программного модуля.

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

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

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

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

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

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

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

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

Типы данных . Каждый объект языка имеет тип, характеризующий множество значений и множество применимых к ним операций. Основные классы типов — это скалярные типы (включающие перечислимые и числовые типы), составные, ссылочные и личные типы.

Перечислимый тип определяет упорядоченное множество различных литералов перечисления, например список состояний или перечень символов. Перечислимые типы BOOLEAN и CHARACTER предопределены.

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

Составные типы допускают определения структурных объектов из сгруппированных компонент. Составные типы в языке представлены массивами и записями. Массив — это объект с индексируемыми компонентами одного и того же типа. Запись — это объект с именованными компонентами, возможно, различных типов. Индексируемый тип STRING предопределен.

Запись может иметь специальные компоненты, называемые дискриминантами. В записях можно определить альтернативные структуры, зависящие от значений дискриминантов.

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

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

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

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

Ввод-вывод в языке определен средствами предопределенных библиотечных пакетов. Предоставляются средства для ввода-вывода значений типов, определенных пользователем, а также значений предопределенных типов; обеспечивается представление изображений значений в стандартной форме.

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

Пред. | Уровень выше | След.
1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ | Начало | 1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ


1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ
Пред. Глава 1. ВВЕДЕНИЕ След.

1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ

Контекстно-свободный синтаксис программных модулей языка Ада вместе с контекстно-зависимыми требованиями выражается правилами в повествовательной форме.

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

Все другие понятия имеют свое естественное значение, определенное в словаре русского языка Ушакова [2] .

Контекстно-свободный синтаксис языка описывается с помощью простого варианта форм Бэкуса-Наура. В частности:

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

аддитивная - операция

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

б) Полужирным шрифтом выделены зарезервированные слова, например:

array

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

оператор-возврата ::= return [выражение];

оператор-возврата ::= return; | return выражение;

г) Повторяющиеся элементы заключаются в фигурные скобки. Этот элемент может встретиться нуль или более раз; повторение осуществляется слева направо в соответствии с правилом левой рекурсии. Таким образом, два следующих правила эквивалентны:

слагаемое ::= множитель (операция-умножения множитель)

слагаемое ::= множитель 1 слагаемое операция-умножения множитель

д) Вертикальная черта разделяет альтернативные элементы, кроме тех случаев, когда черта встречается непосредственно за открывающейся фигурной скобкой, тогда она обозначает знак вертикальной черты:

буква-или-цифра ::= буква 1 цифра

сопоставление-компонента ::= [выбор (I выбор) =>] выражение

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

Примечание. Описывающие структурные конструкции синтаксические правила представлены в форме, соответствующей рекомендованному делению на абзацы. Например, условный оператор определяется так:

условный-оператор ::=
   if условие then
      последовательность - операторов
   {elsif условие then
      последовательность - операторов}
   [else
      последовательность - операторов]
   end if;

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

[2] В оригинале: третий новый международный словарь английского языка Уэбстера. - Прим. перев. стр.360

Пред. | Уровень выше | След.
1.4. ОБЗОР СВОЙСТВ ЯЗЫКА | Начало | 1.6. КЛАССИФИКАЦИЯ ОШИБОК


1.6. КЛАССИФИКАЦИЯ ОШИБОК
Пред. Глава 1. ВВЕДЕНИЕ След.

1.6. КЛАССИФИКАЦИЯ ОШИБОК

Определение языка делит ошибки на несколько различных категорий:

а) Ошибки, которые должны быть обнаружены во время компиляции любым компилятором с языка Ада.

Эти ошибки соответствуют любому нарушению правил, данных в этом стандарте, кроме нарушений, соответствующим пунктам б) и в). В частности, к этой категории относятся нарушения правил, в которых использованы слова должно, допустимо, правильный или неправильный. Любая содержащая такую ошибку Ада-программа не является правильной; с другой стороны, тот факт, что программа правильна в этом смысле, не означает, что в ней нет других ошибок.

б) Ошибки, которые должны быть обнаружены во время выполнения Ада-программы.

Соответствующим ошибочным ситуациям сопоставлены имена предопределенных исключений. Каждый компилятор с языка Ада должен генерировать код, возбуждающий соответствующее исключение, если такая ошибочная ситуация встретится во время выполнения программы. Если исключение обязательно будет возбуждаться при выполнении данной программы, то компиляторы могут (но не обязательно) сообщить об этом во время компиляции.

в) Ошибочное выполнение.

В языке определен ряд правил, которым должна подчиняться Ада-программа, хотя от компилятора и не требуется обнаружение нарушений этих правил ни во время компиляции, ни во время выполнения программы. Слово ошибочный квалифицирует выполнение конструкций, содержащих ошибки этой категории. Результат выполнения ошибочной конструкции непредсказуем.

г) Некорректная зависимость от порядка.

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

Если компилятор способен распознать во время компиляции, что конструкция ошибочна или содержит некорректную зависимость от порядка, то допускается, чтобы компилятор генерировал код, заменяющий конструкцию кодом, возбуждающим предопределенное исключение PROGRAM-ERROR. Компилятор также может сгенерировать код, который во время выполнения проверяет ошибочность конструкции, некорректную зависимость от порядка или и то и другое. Предопределенное исключение PROGRAM-ERROR возбуждается, если проверка покажет наличие такой ошибки.

Пред. | Уровень выше | След.
1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ | Начало | Глава 2. ЛЕКСИКА


Глава 2. ЛЕКСИКА
Пред. След.

Глава 2. ЛЕКСИКА

Содержание

2.1. НАБОР СИМВОЛОВ
2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ
2.3. ИДЕНТИФИКАТОРЫ
2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ
2.5. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ
2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ
2.7. КОММЕНТАРИИ
2.8. ПРАГМЫ
2.9. ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА
2.10. ДОПУСТИМЫЕ ЗАМЕНЫ СИМВОЛОВ

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

Ссылки: компиляция 10.1, лексема 2.2, прагма 2.8, символ 2.1.

2.1. НАБОР СИМВОЛОВ

Символами в тексте программы должны быть только графические символы и символы управления форматом. Каждый графический символ соответствует единственному коду из набора символов ISO, кодируемых семью разрядами (стандарт ISO 646), и представляется (визуально) графическим знаком. Некоторые графические символы представляются различными графическими знаками в национальных представлениях набора символов ISO. При описании определения языка в данном справочном руководстве используются графические знаки ASCII, представляющие собой национальное представление ANSI набора символов ISO.

графический-символ ::= основной-графический-символ
   | строчная-буква | дополнительный-специальный-символ

основной-графический-символ ::= прописная-буква
   | цифра | специальный-символ | символ-пробела

основной-символ ::= основной-графический-символ
   | символ-управления-форматом

Набор основных символов достаточен для написания любой программы. Основные графические символы подразделяются на следующие категории:

а) прописные буквы [3]

ABCDEFGHIJKLMNOPQRSTUVWXYZ

б) цифры

0123456789

в) специальные символы

" # &'()*+, -./:;<=>- |

г) символ пробела.

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

Остальные категории графических символов определяются следующим образом:

д) строчные буквы [4]

abcdefghijklmnopqrstuvwxyz

е) дополнительные специальные символы

! $ % ? @ [ \ ] " ' | ) -

В разд. 2.10 определены допустимые замены для специальных символов вертикальной черты (|), номера (#) и кавычки (").

Примечание. Графическому символу номера в представлении ASCII соответствует символ фунта стерлингов в представлении национальных стандартов Франции, Германии и Великобритании. Шрифтовые выделения графических символов (например, курсив или полужирный шрифт) не являются частью стандарта ISO.

Под использованными в этом разделе акронимами понимают следующее: ANSI — Американский национальный институт стандартов, ASCII — Американский стандартный код для обмена информацией, ISO — Международная организация по стандартизации.

Для ссылок на специальные и дополнительные специальные символы используются следующие их наименования:

Знак | Наименование | Знак | Наименование
" | кавычки | > | больше
# | номер (решетка) |  | подчеркивание
& | коммерческое И (амперсанд) | 1 | вертикальная черта
' | апостроф | ! | восклицательный знак
( | круглая скобка (левая) | $ | доллар
) | круглая скобка (правая) | % | процент
* | звездочка, умножение | ? | вопросительный знак
+ | плюс | @ | коммерческое эт
, | запятая | [ | квадратная скобка (левая)
- | дефис, минус | \ | обратная дробная черта
 | точка, период | ] | квадратная скобка (правая)
/ | дробная черта, деление | * | сиркюмфлекс
 | двоеточие |  | слабое ударение
; | точка с запятой | ! | фигурная скобка (левая)
< | меньше | 1 | фигурная скобка (правая)
= | равно | - | тильда

[3] В тексте перевода для идентификаторов наряду с латинским используется алфавит прописных русских букв. - Прим. ред.

[4] В тексте перевода наряду с латинским используется алфавит строчных русских букв. - Прим. ред.

Пред. | Уровень выше | След.
1.6. КЛАССИФИКАЦИЯ ОШИБОК | Начало | 2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ


2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ
Пред. Глава 2. ЛЕКСИКА След.

2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ

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

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

Конец строчки всегда является разделителем. Язык не определяет, что является концом строчки. Если в данной реализации конец строчки обозначается одним или несколькими символами, то эти символы должны быть символами управления форматом, отличными от символа горизонтальной табуляции. Во всяком случае, последовательность из одного или нескольких символов управления форматом, отличных от символа горизонтальной табуляции, должна заменить по крайней мере один конец строчки.

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

Ограничитель — это один из следующих специальных символов из набора основных символов:

&'()*+,-./:;<=>!

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

=> .. ** := /= >= <= << >> <>

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

Остальные формы лексем описаны в других разделах данной главы.

Примечание. Каждая лексема должна располагаться в одной строчке, поскольку конец строчки — разделитель. Символы кавычки, решетки, подчеркивания и два соседних дефиса не являются ограничителями, но могут входить в лексемы в качестве ее частей.

Наименования составных ограничителей даны ниже:

Ограничитель | Наименование
= > | стрелка
.. | двойная точка
** | двойная звездочка, возведение в степень
:= | присваивание (читается: «Становится равным»)
/= | неравенство (читается: «Не равно»)
> = | больше или равно
< = | меньше или равно
<< | левая скобка метки
>> | правая скобка метки
< > | бокс (или коробка)

Ссылки: зарезервированное слово 2.9, идентификатор 2.3, комментарий 2.7, компиляция 10.1, символ пробела 2.1, символ управления 2.1, символьный литерал 2.5, специальный символ 2.1, строковый литерал 2.6, числовой литерал 2.4.

Пред. | Уровень выше | След.
Глава 2. ЛЕКСИКА | Начало | 2.3. ИДЕНТИФИКАТОРЫ


2.3. ИДЕНТИФИКАТОРЫ
Пред. Глава 2. ЛЕКСИКА След.

2.3. ИДЕНТИФИКАТОРЫ

Идентификаторы используются в качестве имен и зарезервированных слов.

идентификатор ::= буква {[подчеркивание] буква-или-цифра}

буква-или-цифра ::= буква | цифра

буква ::= прописная буква | строчная буква

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

Примеры:

СЧЕТЧИК | Х | дай-символ | Эвелина | Марион
СНОБОЛ-4 | Х1 | СчетчикСтраниц | ЗАПАСТИ_СЛЕДУЮЩИЙ_ЭЛЕМЕНТ |

Примечание. Пробел внутри идентификатора недопустим, поскольку он является разделителем.

Ссылки: зарезервированное слово 2.9, имя 4.1, прописная буква 2.1, разделитель 2.2, символ пробела 2.1, строчная буква 2.1, цифра 2.1.

Пред. | Уровень выше | След.
2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ | Начало | 2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ


2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ
Пред. Глава 2. ЛЕКСИКА След.

2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ

Числовые литералы подразделяются на два класса: вещественные литералы и целые литералы. Вещественный литерал — это числовой литерал, который включает точку; целый литерал — это числовой литерал без точки. Вещественные литералы являются литералами типа универсальный-вещественный. Целые литералы — литералы типа универсальный-целый.

числовой-литерал ::= десятичный-литерал | литерал-с-основанием

Ссыпки: литерал 4.2, универсальный-вещественный тип 3.5.6, универсальный-целый тип 3.5.4.

2.4.1. ДЕСЯТИЧНЫЕ ЛИТЕРАЛЫ

Десятичный литерал — это числовой литерал, выраженный в общепринятой десятичной системе (основание по умолчанию равно десяти).

десятичный-литерал ::= целое [.целое] [порядок]

целое   ::= цифра {[подчеркивание] цифра}

порядок ::= Е [+] целое | E - целое

Символ подчеркивания между соседними цифрами десятичного литерала не влияет на значение числового литерала. Буква Е в порядке может быть строчной или прописной буквой с одним и тем же назначением.

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

Примеры:

12 | 0 | 1Е6 | 123_456 | -- целые литералы
12.0 | 0.0 | 0.156 | 3.14159_26 | -- вещественные литералы
1.34Е-12 |  | 1.0Е+6 |  | -- вещественные литералы с порядком

Примечание: Ведущие нули допускаются. Пробел в числовом литерале недопустим даже между составными частями порядка, поскольку пробел является разделителем. Нулевой порядок для целого литерала допустим.

Ссылки: прописная буква 2.1, разделитель 2.2, символ пробела 2.1, строчная буква 2.1, цифра 2.1, числовой литерал 2.4.

2.4.2. ЛИТЕРАЛЫ С ОСНОВАНИЕМ

Литерал с основанием — это числовой литерал, в котором явно указано основание. Основание должно принимать значение от 2 до 16.

литерал-с-основанием ::= основание # целое-с-основанием
   [.целое-с-основанием] # [порядок]

основание :: = целое

целое-с-основанием ::=
   расширенная-цифра {[подчеркивание] расширенная-цифра}

расширенная-цифра ::= цифра | буква

Символ подчеркивания, заключенный между соседними цифрами литерала с основанием, не влияет на значение этого числового литерала. Основание и порядок записываются в десятичной системе. В качестве расширенных цифр от 10 до 15 допускаются только латинские буквы от А до F. Буква в литерале с основанием (расширенная цифра или буква Е в порядке) может быть строчной или прописной с одним и тем же смыслом.

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

Примеры:

2#1111_1111# | 16#FF# | 016#0FF# | -- целые литералы со значением 255
16#Е#Е1 | 2#1110_0000# |  | -- целые литералы со значением 224
16#F.FF#E+2 | 2#1.1111_1111_111#Е11 |  | -- действительные литералы со значением 4095.0

Ссылки: буква 2.3, порядок 2.4.1, прописная буква 2.1, строчная буква 2.1, цифра 2.1, числовой литерал 2.4.

Пред. | Уровень выше | След.
2.3. ИДЕНТИФИКАТОРЫ | Начало | 2.5. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ


2.5. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ
Пред. Глава 2. ЛЕКСИКА След.

2.5. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ

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

символьный-литерал ::= 'графический-символ'
Примеры:

'А' '*' ''' ' '

Ссылки: графический символ 2.1, литерал 4.2, символ пробела 2.1, символьный тип 3.5.2.

Пред. | Уровень выше | След.
2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ | Начало | 2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ


2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ
Пред. Глава 2. ЛЕКСИКА След.

2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ

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

строковый-литерал ::= "{графический-символ}"

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

Длина строкового литерала — это количество значений символьного типа в представленной последовательности (каждые два соседних символа кавычки в строке считаются одним символом).

Примеры :

"Дневное сообщение:"

""                            -- пустой строковый литерал
" " "А"   """"                -- три строковых литерала длиной 1
"Символы, такие как $, % и ), допустимы в строковых литералах"

Примечание. Строковый литерал должен помещаться на одной строчке, поскольку он является лексемой (см. 2.2). Более длинные последовательности значений графических символов могут быть получены катенацией строковых литералов. Равным образом катенация констант, описанных в пакете ASCII, может быть использована для получения последовательности значений символьного типа, которая включает значения неграфических символов (так называемых управляющих символов). Ниже даны примеры использования катенации:

"ПЕРВАЯ ЧАСТЬ ПОСЛЕДОВАТЕЛЬНОСТИ СИМВОЛОВ," & "КОТОРАЯ ПРОДОЛЖАЕТСЯ НА СЛЕДУЮЩЕЙ СТРОЧКЕ"

"последовательность, которая включает" & ASCII.ACK & "управляющий символ"

Ссылки: графический символ 2.1, значение символа 3.5.2, конец строчки 2.2, константа 3.2.1, лексема 2.2, операция катенации 4.5.3, описание 3.1, предопределенный пакет ASCII С.

Пред. | Уровень выше | След.
2.5. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ | Начало | 2.7. КОММЕНТАРИИ


2.7. КОММЕНТАРИИ
Пред. Глава 2. ЛЕКСИКА След.

2.7. КОММЕНТАРИИ

Комментарий начинается с двух соседних дефисов и продолжается до конца строчки. Комментарий может помещаться в любой строчке программы. Присутствие или отсутствие комментария не влияет ни на правильность, ни на неправильность программы. Более того, комментарии не влияют на смысл программы; их единственное назначение — сделать программу более понятной.

Примеры:

-- последнее предложение выражает ту же мысль, что и
-- в языке Алгол-68

end; -- обработка LINE завершена

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

------- первые два дефиса начинают комментарий

Примечание. Горизонтальная табуляция может быть использована в комментариях после двух дефисов, это эквивалентно одному или нескольким пробелам (см. 2.2).

Ссылки: конец строчки 2.2, неправильный 1.6, правильный 1.6, символ пробела 2.1.

Пред. | Уровень выше | След.
2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ | Начало | 2.8. ПРАГМЫ


2.8. ПРАГМЫ
Пред. Глава 2. ЛЕКСИКА След.

2.8. ПРАГМЫ

Прагма используется для задания информации компилятору. Прагма начинается зарезервированным словом pragma, за которым следует идентификатор — имя прагмы.

прагма ::=pragma идентификатор
   [(сопоставление-аргумента {, сопоставление-аргумента })];

сопоставление-аргумента ::=
   [идентификатор-аргумента => ] имя
   [идентификатор-аргумента => ] выражение

Прагмы допустимы только в следующих местах программы:

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

• В любом месте, где синтаксические правила допускают синтаксические понятия, в названии которых содержатся слова «описание», «оператор», «спецификатор» или «альтернатива», или одно из синтаксических понятий—вариант и обработчик исключений, но не вместо соответствующих конструкций, а также в любом месте, где допустим компилируемый модуль.

На месторасположение отдельных прагм могут накладываться дополнительные ограничения.

Некоторые прагмы имеют аргументы. Сопоставления аргументов могут быть либо позиционными, либо именованными, как и при сопоставлении параметров в вызовах подпрограмм (см. 6.4). Однако именованные сопоставления возможны, если определены идентификаторы аргументов. Именем аргумента должно быть либо имя, видимое в месте употребления прагмы, либо идентификатор, специфический для этой прагмы.

Предопределенные прагмы описаны в приложении В; они должны поддерживаться в каждой реализации. Реализация может определить дополнительные прагмы. Они должны быть описаны в приложении F. Реализация не должна допускать определение прагм, наличие или отсутствие которых влияет на правильность текста программы. Следовательно, правильность программы не зависит от наличия или отсутствия прагм, определенных реализацией.

Прагма, не определенная в языке, не дает никакого результата, если ее идентификатор не распознан (данной) реализацией. Более того, прагма (как определенная в языке, так и определенная реализацией) не дает никакого результата, если ее размещение или ее аргументы не соответствуют допустимым для прагмы. Участок текста, на который распространяется действие прагмы, зависит от прагмы.

Примеры:

pragma LIST(OFF);
pragma OPTIMIZE(TIME);
pragma INLINE(SETMASK);
pragma SUPPRESS(RANGE_CHECK, ON => INDEX);

Примечание. Рекомендуется (но не требуется), чтобы реализация выдавала предупреждающие сообщения о прагмах, которые не распознаны и поэтому проигнорированы.

Ссылки: вариант 3.7.3, видимость 8.3, выражение 4.4, компилируемый модуль 10.1, зарезервированное слово 2.9, идентификатор 2.3, имя 4.1, обработчик исключения 11.2, ограничитель 2.2, оператор 5, правильный 1.6, прагма, зависящая от реализации F, прагма, зависящая от языка В, раздел дискриминантов 3.7.1, статическое выражение 4.9.

Понятие со словом «описание»: описание входа 9.5, описание компоненты 3.7, описание параметра настройки 12.1, основное описание 3.1.

Понятие со словом «спецификатор>: спецификатор выравнивания 13.4, спецификатор использования 8.4, спецификатор компоненты 13.4, спецификатор контекста 10.1.1, спецификатор представления 13.1, спецификатор совместности 10.1.1.

Понятие со словом «альтернатива»: альтернатива завершения 9.7.1, альтернатива задержки 9.7.1, альтернатива оператора выбора 5.4, альтернатива отбора 9.7.1, альтернатива отбора с ожиданием 9.7.1, альтернатива принятия 9.7.1.

Пред. | Уровень выше | След.
2.7. КОММЕНТАРИИ | Начало | 2.9. ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА


2.9. ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА
Пред. Глава 2. ЛЕКСИКА След.

2.9. ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА

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

abort | — прекращение | loop | — цикл
abs | — abs | mod | — по-мод
accept | — принятие | new | — новый
access | — ссылка-на | not | — не
all | — все | null | — пусто
and | — и | of | — из
array | — массив | or | — или
at | — положение | others | — Другие
begin | — начало | out | — вых
body | — тело | package | — пакет
case | — выбор | pragma | — прагма
constant | — константа | private | — личный
declare | — описание | procedure | — процедура
delay | — задержка | raise | — возбуждение
delta | — дельта | range | — диапазон
digits | — цифр | record | — запись
do | — выполнение | rem | — остаток
else | — иначе | renames | — синоним
elsif | — инесли | return | — возврат
end | — конец | reverse | — в-обратном-порядке
entry | — вход | select | — отбор
exception | — исключение | separate | — отдельно
exit | — выход | subtype | — подтип
for | — для | task | — задача
function | — функция | terminate | — завершение
generic | — настройка | then | — то
goto | — переход-на | type | — тип
if | — если | use | — использование
in | — из | when | — когда
in | — вх | while | — пока
is | — есть | with | — совместно-с
limited | — лимитируемый | xor | — либо

Зарезервированные слова не должны использоваться в качестве описываемого идентификатора.

Примечание. Зарезервированные слова, отличающиеся только соответствующими строчными или прописными буквами, рассматриваются как одинаковые (см. 2.3). Идентификаторы некоторых атрибутов, стоящие после апострофа, совпадают с зарезервированными словами (DELTA, DIGITS и RANGE).

Ссылки: атрибут 4.1.4, идентификатор 2.3, описание 3.1, прописная буква 2.1, строчная буква 2.1.

Пред. | Уровень выше | След.
2.8. ПРАГМЫ | Начало | 2.10. ДОПУСТИМЫЕ ЗАМЕНЫ СИМВОЛОВ


2.10. ДОПУСТИМЫЕ ЗАМЕНЫ СИМВОЛОВ
Пред. Глава 2. ЛЕКСИКА След.

2.10. ДОПУСТИМЫЕ ЗАМЕНЫ СИМВОЛОВ

Для основных символов — вертикальной черты, номера и кавычки — допустимы следующие замены:

• Символ вертикальной черты ( ) можно заменить восклицательным знаком (!) там, где он используется как ограничитель.

• Символ номера (#) в литерале с основанием можно заменить двоеточием (:) при условии, что в этом литерале заменяются оба символа номера.

• Символ кавычки ("), использованный как строковая скобка на обоих концах строкового литерала, можно заменить символом процента (%), если последовательность символов строкового литерала не содержит символа кавычки и если в этом литерале заменяются обе строковые скобки. Для представления символа процента внутри последовательности символов строкового литерала должна использоваться пара соседних символов процента, которая рассматривается как один символ процента.

Эти замены не изменяют смысла программы.

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

Правила для идентификаторов и числовых литералов таковы, что строчные и прописные буквы эквивалентны; эти лексемы могут быть записаны только символами основного набора. Если строковый литерал предопределенного типа STRING содержит символы не из основного набора, та же самая последовательность значений символов может быть получена катенацией строковых литералов, содержащих символы основного набора, и символьных констант, описанных в предопределенном пакете ASCII. Таким образом, строковый литерал "AB$CD" можно заменить на "АВ" & ASCII.DOLLAR & "CD", а строковый литерал "ABcd" со строчными буквами можно заменить на "АВ" & ASCII.LC-C & ASCII.LC-D.

Ссылки: графический знак 2.1, графический символ 2.1, значение символа 3.5.2, идентификатор 2.3, лексема 2.2, литерал с основанием 2.4.2, ограничитель 2.2, операция катенации 4.5.3, основной символ 2.1, предопределенный пакет ASCII С, прописная буква 2.1, строковая скобка 2.6, строковый литерал 2.6, строчная буква 2.1, числовой литерал 2.4.

Пред. | Уровень выше | След.
2.9. ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА | Начало | Глава 3. ОПИСАНИЯ И ТИПЫ


Глава 3. ОПИСАНИЯ И ТИПЫ
Пред. След.

Глава 3. ОПИСАНИЯ И ТИПЫ

Содержание

3.1. ОПИСАНИЯ
3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА
3.3. ТИПЫ И ПОДТИПЫ
3.4. ПРОИЗВОДНЫЕ ТИПЫ
3.5. СКАЛЯРНЫЕ ТИПЫ
3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ
3.7. ИМЕНУЕМЫЕ ТИПЫ
3.8. ССЫЛОЧНЫЕ ТИПЫ
3.9. РАЗДЕЛЫ ОПИСАНИЙ

Эта глава описывает типы и правила описания констант, переменных и именованных чисел.

3.1. ОПИСАНИЯ

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

Существует, несколько форм описаний. Основное описание — это форма описания, определенная следующим образом:

основное-описание ::=
  описание-объекта        | описание-числа
| описание-типа           | описание-подтипа
| описание-подпрограммы   | описание-пакета
| описание-задачи         | описание-настройки
| описание-исключения     | конкретизация-настройки
| описание-переименования | описание-субконстанты

Некоторые формы описания всегда являются (явно) частью основного описания, а именно: спецификация дискриминантов, описание компонент, описание входов, спецификация параметров, описание параметров настройки и спецификации литералов перечисления. Спецификация параметра цикла — это конструкция, которая входит только в некоторые формы оператора цикла.

Остальные формы описания являются неявными: имя блока, имя цикла и метка оператора. Некоторые операции описываются неявно (см. 3.3.3).

Для каждой формы описания правила языка определяют некоторый участок текста, называемый областью действия описания (см. 8.2). Несколько форм описания связывают идентификатор с описанным понятием. Внутри его области действия, и только в ней, существуют места, где возможно использование идентификатора для связи его с описанным понятием; эти места определяются правилами видимости (см. 8.3.). В таких местах идентификатор называют именем понятия (простым именем); говорят, что имя обозначает связанное с ним понятие.

Определенные формы спецификации литерала перечисления связывают символьный литерал с соответствующим описываемым понятием. Некоторые формы описаний связывают символ операции или другие обозначения с явно или неявно описанной операцией.

Процесс, в результате которого описание вступает в силу, называется предвыполнением описания; этот процесс протекает во время выполнения программы.

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

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

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

Ссылки: атрибут 4.1.4, видимость 8.3, знак операции 6.1, идентификатор 2.3, имя 4.1, имя блока 5.6, имя цикла 5.5, компонента записи 3.7, конкретизация настройки 12.3, метка 5.1, область действия 8.2, оператор блока 5.6, оператор цикла 5.5, операция типа 3.3, описание входа 9.5, описание задачи 9.1, описание исключения 11.1, описание компоненты 3.7, описание настройки 12.1, описание объекта 3.2.1, описание пакета 7.1, описание параметра настройки 12.1, описание переименования 8.5, описание подпрограммы 6.1, описание подтипа 3.3.2, описание субконстанты 7.4, 3.9, описание типа 3.3.1, описание числа 3.2.2, Предвыполнение 3.9, простое имя 4.1, раздел описаний 3.9, символьный литерал 2.5, спецификатор представления 13.1, спецификация дискриминанта 3.7.1, спецификация литерала перечисления 3.5.1, спецификация параметра 6.1, спецификация параметра цикла 5.5, тело подпрограммы 6.3, числовой литерал 2.4, элемент описания 3.9.

Пред. | Уровень выше | След.
2.10. ДОПУСТИМЫЕ ЗАМЕНЫ СИМВОЛОВ | Начало | 3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА


3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА

Объект — это понятие языка; объект имеет (содержит) значение данного типа. Объектом может быть:

• объект, объявленный в описании объекта или в описании одиночной задачи;

• формальный параметр подпрограммы, входа или настраиваемой подпрограммы;

• формальный объект настройки;

• параметр цикла;

• объект, указанный значением ссылочного типа;

• компонента или отрезок другого объекта.

Описание числа — это специальная форма описания объекта, которая связывает идентификатор со значением типа универсальный-целый или универсальный-вещественный.

описание-объекта ::=
   список-идентификаторов : [constant] указание-подтипа [:= выражение];
   список-идентификаторов : [constant]
      определение-ограниченного-индексируемого-типа [:= выражение];

описание-числа ::=
   список-идентификаторов : constant := универсальное-статическое-выражение;

   список-идентификаторов ::= идентификатор {, идентификатор}

Описание объекта называется единичным описанием объекта, если список его идентификаторов имеет единственный идентификатор; оно называется групповым описанием объектов, если его список имеет два или несколько идентификаторов. Групповое описание объектов эквивалентно последовательности соответствующего числа единичных описаний объектов. Для каждого идентификатора из списка в такой эквивалентной последовательности единичное описание объекта формируется из идентификатора, двоеточия и всего того, что стоит справа от двоеточия в групповом описании объекта; описания в эквивалентной последовательности идут в том же порядке, что и список идентификаторов.

Аналогичная эквивалентность имеет место также для списка идентификаторов описания числа, описаний компонент, спецификаций дискриминантов, спецификаций параметров и описаний параметров настройки, исключений и субконстант.

В остальной части описания языка все пояснения даны для описаний с единственным идентификатором; соответствующие пояснения для описаний с несколькими идентификаторами следуют из эквивалентности, установленной выше.

Примеры:

-- групповое описание объектов
JOHN, PAUL : PERSON_NAME := new PERSON(SEX => M); -- CM. 3.8.1
-- эквивалентно единичным описаниям объектов,
-- следующим в данном порядке
JOHN : PERSON_NAME := new PERSON(SEX => M);
PAUL : PERSON_NAME := new PERSON(SEX => M);

Ссылки: вход 9.5, выражение 4.4, идентификатор 2.3, компонента 3.3, настраиваемая подпрограмма 12.1, настраиваемый модуль 12, настраиваемый формальный объект 12.1.1, область действия 8.2, описание 3.1, описание исключения 11.1, описание одиночной задачи 9.1, описание параметра настройки 12.1, описание субконстанты 7.4, определение индексируемого типа 3.6, отрезок 4.1.2, параметр цикла 5.5, подпрограмма 6, простое имя 4.1, спецификация дискриминанта 3.7.1, спецификация параметра 6.1, ссылочный тип 3.8, статическое выражение 4.9, тип 3.3, тип универсальный вещественный 3.5.6, тип универсальный целый 3.5.4, указание подтипа 3.3.2, указывать 3.8, формальный объект настройки 12.1.1, формальный параметр 6.1, числовой тип 3.5.

3.2.1. ОПИСАНИЯ ОБЪЕКТОВ

Описание объектов вводит объект, тип которого задан либо указанием подтипа, либо определением индексируемого типа. Если описание объекта включает составной ограничитель-присваивание, за которым следует выражение, то это выражение определяет начальное значение описываемого объекта; тип выражения должен быть тем же, что и тип объекта.

Описываемый объект — константа, если в описании объекта присутствует зарезервированное слово constant. В этом случае описание должно включать явную инициализацию. Значение константы не может быть изменено после инициализации. Формальные параметры вида in подпрограмм и входов, а также формальные параметры настройки вида in являются константами; параметр цикла — константа в соответствующем цикле; подкомпонента или отрезок константы тоже константа.

Объект, не являющийся константой, называется переменной (в частности, объект, заданный описанием объекта без зарезервированного слова constant, является переменной). Для-изменения значения переменной существует только два пути: непосредственное присваивание и косвенное изменение (см. 6.2) оператором вызова процедуры или входа (это действие может быть выполнено над самой переменной, над подкомпонентой переменной либо над другой переменной, для которой данная является подкомпонентой).

Предвыполнение описания объекта происходит следующим образом:

а. Устанавливается подтип объекта посредством предвыполнения указания подтипа или определения ограниченного индексируемого типа.

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

в. Создается объект.

г. Начальное значение (заданное явно или по умолчанию) присваивается объекту или соответствующей подкомпоненте.

Неявные начальные значения определяются для объектов, заданных описанием объекта, и для компонент таких объектов в следующих случаях:

• Для объекта ссылочного типа — его неявное начальное значение равно пустому значению ссылочного типа.

• Для объекта задачного типа — неявное начальное (и единственное) значение обозначает соответствующую задачу.

• Если тип объекта является типом с дискриминантами и его подтип ограничен, то неявное начальное (и единственное) значение каждого дискриминанта определяется подтипом объекта.

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

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

Шаги от а до г выполняются в указанном порядке. Если на шаге б вычисляется выражение по умолчанию для дискриминанта, то это вычисление выполняется до вычисления выражений по умолчанию для зависимых от дискриминанта подкомпонент, а также до вычисления выражений по умолчанию, содержащих имя дискриминанта. Кроме предыдущего правила, порядок вычисления выражений по умолчанию языком не определен.

При инициализации описанного объекта или одной из его подкомпонент проверяется принадлежность начального значения подтипу объекта; для массива, описанного описанием объекта. сначала поименяется неявное преобразование подтипа, как пои выполнении оператора присваивания, если только объект не является константой с подтипом неограниченного индексируемого типа. При отрицательном результате проверки возбуждается исключение CONSTRAINT_ERROR.

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

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

COUNT, SUM  : INTEGER;
SIZE        : INTEGER range 0 .. 10_000 := 0;
SORTED      : BOOLEAN := FALSE;
COLOR TABLE : array(1 .. N) of COLOR;
OPTION      : BIT_VECTOR(1 .. 10) := (others => TRUE);

Примеры описаний констант:

LIMIT     : constant INTEGER := 10_000;
LOW LIMIT : constant INTEGER := LIMIT/10;
TOLERANCE : constant REAL := DISPERSION(1.15);

Примечание Выражение для инициализации константы не обязательно является статическим выражением (см. 4.9). В приведенных выше примерах LIMIT и LOW-LIMIT инициализированы статическими выражениями, a TOLERANCE - нет, если DISPERSION - определенная пользователем функция.

Ссылки: видимый раздел 7.2, вид в 6.1, в некотором порядке 1.6, вход 9.5, выражение 4.4, выражение по умолчанию для дискриминанта 3.7.1, вычисление 4.5, дискриминант 3.3, зависимый от дискриминанта 3.7.1, задача 9, задачный тип 9.2, зарезервированное слово 2.9, исключение ошибка ограничения 11.1, квалифицированное выражение 4.7, компонента 3.3, лимитируемый тип 7.4.4, личный тип 7.4, настраиваемый модуль 12, начальное значение по умолчанию для ссылочного типа 3.8, ограниченный подтип 3.3, описание 3.1, определение ограниченного индексируемого типа 3.6, отрезок 4.1.2, пакет 7, первичное 4.4, подкомпонента 3.3, подпрограмма 6 подтип 3.3, Предвыполнение 3.9, предопределенная операция 4.5, преобразования 4.6, присваивание 5.2, скалярный тип 3.5, составной ограничитель присваивания 5.2, составной тип 3.3, ссылочный тип 3.8, тип 3.3, указание подтипа 3.3.2, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3, указывать 3.8.

3.2.2. ОПИСАНИЕ ЧИСЛА

Описание числа — это специальная форма описания константы. Тип статического выражения, заданного для инициализации в описании числа, должен быть либо типом универсальный-целый, либо типом универсальный-вещественный. Константа, объявленная описанием числа, называется именованным числом и имеет тот же тип, что и статическое выражение.

Примечание. Относящиеся к выражениям универсального типа правила изложены в разделе 4.10. Из этих правил следует, что именованное число имеет универсальный-целый тип, если каждое содержащееся в выражении первичное имеет этот тип. Аналогично если каждое первичное имеет тип универсальный-вещественный, то именованное число имеет этот тип.

Примеры описаний чисел:

pi            : constant := 3.14159_26636; -- вещественное число
TWO_PI        : constant := 2.0*PI;        -- вещественное число
МАХ           : constant := 500;           -- целое число
POWER16       : constant := 2**16;         -- целое число 65-536
ONE, UN, EINS : constant := 1;             -- три различных имени 1

Ссылки: идентификатор 2.3, первичное 4.4, статическое выражение 4.9, тип 3.3, тип универсальный вещественный 3.5.6, тип универсальный целый 3.5.4, универсальный тип 4.10.

Пред. | Уровень выше | След.
Глава 3. ОПИСАНИЯ И ТИПЫ | Начало | 3.3. ТИПЫ И ПОДТИПЫ


3.3. ТИПЫ И ПОДТИПЫ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.3. ТИПЫ И ПОДТИПЫ

Тип характеризуется множеством значений и множеством операций.

Существует несколько классов типов. Скалярные типы — это целые и вещественные типы и типы, определенные перечислением своих значений; значения этих типов не имеют компонент. Индексируемый и именуемый типы являются составными. Значение составного типа состоит из значений компонент. Ссылочный тип — это тип, значения которого обеспечивают доступ к объектам. Личные типы — это типы, для которых полностью определяется набор возможных значений, но непосредственный доступ к ним пользователей невозможен. Наконец, существуют задачные типы. (Личные типы описаны в гл. 7, задачные — .в гл. 9, остальные — в гл. 3.)

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

Набор возможных значений данного типа может зависеть от условия, которое называется ограничением (сюда не относятся случаи без ограничения), значение удовлетворяет ограничению, если оно удовлетворяет соответствующему условию. Подтип — это тип вместе с ограничением; говорят, что значение принадлежит подтипу, если оно принадлежит типу и удовлетворяет ограничению; данный тип называется базовым типом подтипа. Тип является подтипом самого себя; такой подтип называется неограниченным; он соответствует условию, которое не налагает никаких ограничений. Базовым типом является он сам.

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

Для объектов некоторых типов определено начальное значение по умолчанию, некоторые другие типы имеют выражения по умолчанию, определенные для всех или части своих компонент. Некоторые операции над типами и подтипами называются атрибутами; эти операции обозначаются именами, описанными в разд. 4.1.4.

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

Подкомпонента значения данного типа не должна быть этого же типа.

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

Примечание. Набор значений подтипа — это подмножество значений базового типа. Это подмножество не обязано быть собственным подмножеством; оно может быть пустым.

Ссылки: атрибут 4.1.4, вещественный тип 3.5.6, задачный тип 9,1, именуемый тип 3.7, индексируемый тип 3.6, квалифицированное выражение 4.7, компонента записи 3.7, компонента массива 3.6, личный тип 7.4, объект 3.2.1, ограничение дискриминанта 3.7.2, описание подтипа 3.3.2, описание типа 3.3.1, перечислимый тип 3.5.1, присваивание 5.2, ссылочный тип 3.8, целый тип 3.5.4.

3.3.1. ОПИСАНИЯ ТИПОВ

Описание типа объявляет тип.

описание-типа ::= полное-описание-типа
    | неполное-описание-типа | описание-личного-типа

полное-описание-типа ::=
    type идентификатор [раздел-дискриминантов]
       is определение-типа;

определение-типа ::= определение-перечислимого-типа
    | определение-целого-типа
    | определение-вещественного-типа
    | определение-индексируемого-типа
    | определение-именуемого-типа
    | определение-ссылочного-типа
    | определение-производного-типа

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

Типы, созданные в результате предвыполнения различных определений, являются различными. Более того, Предвыполнение определения типа для числовых или производных типов' создает как базовый тип, так и подтип базового типа; то же самое выполняется для определения ограниченного индексируемого типа (одной из двух форм определения индексируемого типа).

Простое имя в полном описании типа обозначает описанный тип, если только описание типа не объявляет базовый тип и подтип базового типа; в этом случае простое имя обозначает подтип, а базовый тип является анонимным. Тип называется анонимным, если он не имеет простого имени. Для наглядности в этом стандарте время от времени используется псевдоимя анонимного типа, написанное курсивом, там, где обычно по синтаксису требуется идентификатор.

Примеры определений типов:

(WHITE, RED, YELLOW, GREEN, BLUE. BROWN, BLACK)

range 1 .. 72

array (1 .. 10) of INTEGER

Примеры описаний типов:

type COLOR is (WHITE, RED, YELLOW, GREEN, BLUE. BROWN, BLACK):

type COLUMN is range 1 .. 72; type TABLE is array (1 .. 10) of INTEGER;

Примечание. Два определения типа всегда определяют два различных типа, даже если они текстуально идентичны. Таким образом, данные ниже описания А и В задают различные индексируемые типы:

А : array (1 .. 10) of BOOLEAN;

В : array (1 .. 10) of BOOLEAN;

Если А и В описаны в групповом описании объектов, то их типы (анонимные) тем не менее различны, так как это групповое описание объектов эквивалентно двум приведенным выше единичным описаниям.

А, В : array (1 .. 10) of BOOLEAN;

Неполные описания типов используются для определения рекурсивных и взаимосвязанных типов (см. 3.8.1). Описания личных типов используются в спецификациях пакетов и в описаниях параметров настройки .(см. 7.4 и 12.1).

Ссыпки: базовый тип 3.3, групповое описание объектов 3.2, зарезервированное слово 2.9, идентификатор 2.3, неполное описание типа 3.8.1, ограниченный подтип 3.3, описание 3.1, описание личного типа 7.4, определение вещественного типа 3.5.6, определение индексируемого ограниченного типа 3.6, определение индексируемого типа 3.6, определение перечислимого типа 3.5.1, определение производного типа 3.4, определение ссылочного типа 3.8, определение целого типа 3.5.4, Предвыполнение 3.9, производный тип 3.4, раздел дискриминантов 3.7.1, тип 3.3, числовой тип 3.5.

3.3.2. ОПИСАНИЯ ПОДТИПОВ

Описание подтипа объявляет подтип.

описание-подтипа ::= subtype идентификатор is указание-подтипа;
указание-подтипа ::= обозначение-типа [ограничение]
обозначение-типа ::= имя -типа|имя- подтипа
ограничение ::= ограничение-диапазона
             | ограничение-плавающего-типа
             | ограничение - фиксированного - типа
             | ограничение-индекса
             | ограничение-дискриминанта

Обозначение типа обозначает тип или подтип. Если обозначение типа — имя типа, то оно обозначает этот тип, а также соответствующий неограниченный подтип. Базовым типом, соответствующим обозначению типа, является по определению базовый тип типа или подтипа, указанного обозначением типа.

Указание подтипа определяет подтип базового типа, соответствующего обозначению типа.

Если в указании подтипа после обозначения типа стоит ограничение индекса, то обозначение типа не должно обозначать подтип с уже ограниченным индексом. Аналогично для ограничения дискриминанта: обозначение типа не должно иметь ограничение дискриминанта.

Предвыполнение описания подтипа состоит из предвыполнения указания подтипа. Это предвыполнение создает подтип. Если указание подтипа не включает ограничение, то определяемый подтип тот же, что и указанный обозначением типа подтип. Предвыполнение указания подтипа, содержащего ограничение, происходит следующим образом:

а) вначале предвыполняется ограничение;

б) ограничение проверяется на совместимость с типом или подтипом, заданным обозначением типа.

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

Примеры описаний подтипов:

subtype RAINBOW is COLOR range RED .. BLUE;    -- см. 3.3.1
subtype REOBLUE is RAINBOW;
subtype INT is INTEGER;
subtype SMALUNT is INTEGER range -10 .. 10;
subtype UPTOK is COLUMN range 1 .. К;        -- см. 3.3.1
subtype SQUARE is MATRIX(1 .. 10, 1 .. 10);    -- см. 3.6
subtype MALE is PERSON(SEX => M);             -- см. 3.8

Примечание. Описание подтипа не определяет нового типа.

Ссылки: базовый тип3, выражение 4.4, вычисление 4.5, дискриминант 3.3, зарезервированное слово 2.9, имя типа 3.3.1, исключение CONSTRAINT_ERROR 11.1, неограниченный подтип 3.3, ограничение диапазона 3.5, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, ограничение плавающего типа 3.5.7, ограничение фиксированного типа 3.5.9, описание 3.1, подтип 3.3, предвыполнение 3.9, совместимость с ограничением диапазона 3.5, совместимость с ограничением дискриминанта 3.7.2, совместимость с ограничением индекса 3.6.1, совместимость с ограничением плавающего типа 3.5.7, совместимость с ограничением фиксированного типа 3.5.9, тип 3.3.

3.3.3. КЛАССИФИКАЦИЯ ОПЕРАЦИЙ

Множество операций над типом включает явно описанные подпрограммы с параметром или результатом этого типа; такие подпрограммы необходимо описывать после описания типа.

Остальные операции неявно описываются сразу после каждого описания типа. К ним относятся базовые операции, предопределенные операции (см. 4.5) и литералы перечисления. Описанием производного типа неявно задаются операции, включающие производные подпрограммы. Считается, что описания операций расположены между описанием типа и последующим описанием, если таковое имеется. Неявные описания производных подпрограмм расположены последними. Базовыми операциями являются:

• Присваивание (в операторах присваивания и инициализациях), генератор, проверка принадлежности или форма управления с промежуточной проверкой.

• Именуемая компонента, индексируемая компонента или отрезок.

• Квалификация (в квалифицированных выражениях), явное преобразование типа или неявное преобразование значения типа универсальный-целый или универсальный-вещественный в соответствующее значение другого числового типа.

• Числовой литерал (для универсального типа), литерал null (для ссылочного типа), строковый литерал, агрегат или атрибут.

Для каждого типа или подтипа Т определен следующий атрибут:

Т'BASE

Базовый тип Т. Этот атрибут допустим только в качестве префикса имени другого атрибута, например T'BASE'FIRST.

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

Ссылки: агрегат 4.3, атрибут 4.1.4, генератор 4.8, именуемая компонента 4.1.3, индексируемая компонента 4.1.1., квалифицированное выражение 4.7, литерал 4.2, литерал перечисления 3.5.1, начальное значение 3.2.1, объект 3.2.1, 3.2, описание типа 3.3.1, отрезок 4.1.2, подпрограмма 6, подтип 3.3, предопределенная операция 4.5, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, производная подпрограмма 3.4, пустой литерал 3.8, символьный литерал 2.5, составной тип 3.3, строковый литерал 2.6, тип 3.3, универсальный вещественный тип 3.5.6, универсальный тип 4.10, универсальный целый тип 3.5.4, управление с промежуточной проверкой 4.5, 4.5.1, формальный параметр 6.1, функция 6.5, числовой литерал 2.4, числовой тип 3.5.

Пред. | Уровень выше | След.
3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА | Начало | 3.4. ПРОИЗВОДНЫЕ ТИПЫ


3.4. ПРОИЗВОДНЫЕ ТИПЫ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.4. ПРОИЗВОДНЫЕ ТИПЫ

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

определение-производного-типа ::= new указание-подтипа

Указание подтипа после зарезервированного слова new определяет родительский подтип. Родительский тип является базовым для родительского подтипа. Если для родительского подтипа существует ограничение, то подобное ограничение существует и для производного подтипа; разница состоит только в том, что для ограничения диапазона и для ограничения плавающего или фиксированного типов, которое включает ограничение диапазона, значение каждой границы заменяется на соответствующее значение производного типа. Производный тип обладает следующими свойствами:

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

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

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

• Если родительский тип — задачный тип, то для каждого входа родительского типа существует соответствующий вход производного типа.

• Если выражение по умолчанию существует для компоненты объекта, имеющего родительский тип, то то же самое выражение используется для соответствующей компоненты объекта производного типа.

• Если родительский тип — ссылочный тип, то родительский и производный типы имеют один и тот же набор; существует пустое ссылочное значение для производного типа, которое по умолчанию является значением этого типа.

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

• Подпрограммы, которые являются операциями над родительским типом, называются наследуемыми. Для каждой наследуемой подпрограммы родительского типа имеется соответствующая производная подпрограмма над производным типом. Могут быть выделены два сорта наследуемых подпрограмм. Во-первых, если родительский тип описан непосредственно в видимом разделе пакета, то подпрограмма, явно описанная непосредственно в видимом разделе, становится наследуемой после конца видимого раздела (если подпрограмма — операция над родительским типом). (Явное описание — это описание подпрограммы, описание переименования подпрограммы или конкретизация настройки.) Во-вторых, если родительский тип сам является производным и не описан в видимом разделе пакета, то подпрограмма, которая стала наследуемой, и она не скрыта наследуемой подпрограммой первого сорта, является далее наследуемой.

Описание производного типа неявно описывает операции над производным типом. Неявные описания любых производных подпрограмм следуют за описанием производного типа.

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

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

Если производный или личный тип описан непосредственно в видимом разделе пакета, то в нем этот тип не должен использоваться как родительский тип в определении производного типа. (Для личных типов см. также разд. 7.4.1.)

При предвыполнении определения производного типа сначала предвыполняется указание подтипа, затем создается производный подтип.

Примеры:

type LOCAL-COORDINATE is new COORDINATE; —- Два различных типа
type MIDWEEK is new DAY range TUE .. THU; —- CM. 3.5.1
type COUNTER is new POSITIVE; -- тот же диапазон, что и у POSITIVE
type SPECIAL-KEY is new KEYMANAGER.KEY; — CM. 7.4.2
-- Производные подпрограммы имеют следующие спецификации:

--procedure GETKEY(K : out SPECIAL_KEY);
-—function "<"(X,Y : SPECIAL_KEY) return BOOLEAN;

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

Скрытие производной подпрограммы допустимо даже в одной и той же зоне описания (см. 8.3). Производная подпрограмма скрывает предопределенную операцию, имеющую тот же профиль типа параметров и результата (см. 6.6).

Описание настраиваемой подпрограммы не наследуется, поскольку оно описывает настраиваемый модуль, а не подпрограмму. С другой стороны, конкретизация настраиваемой подпрограммы является (ненастраиваемой) подпрограммой, которая является наследуемой, если она удовлетворяет требованиям наследуемости подпрограмм.

Если родительский тип является логическим, то предопределенные операции отношения над производным типом дают результаты предопределенного типа BOOLEAN (см. 4.5.2).

Если спецификатор представления дан для родительского типа и помещен за описанием производного типа, то соответствующий спецификатор представления неприменим к производному типу; следовательно, для такого производного типа допускается явный спецификатор представления.

Если параметр производной подпрограммы принадлежит производному типу, подтип это- .-, го параметра не обязан иметь значение, общее с производным подтипом.

Ссылки: агрегат 4.3, атрибут 4.1.4, базовая операция 3.3.3, базовый тип 3.3, вид 6.1, видимый раздел 7.2, вход 9.5, вызов функции 6.4, выражение по умолчанию 3.2.1, граница диапазона 3.5, дискриминант 3.3, зарезервированное слово 2.9, зона описания 8.1, класс типа 3.3, компонента 3.3, литерал 4.2, литерал перечисления 3.5.1, личный тип 7.4, логический тип 3.5.3, набор 3.8, начальное значение по умолчанию для ссылочного типа 3.8, непосредственно в 8.1, неявное описание 3.1, ограничение 3.3, ограничение диапазона 3.5, ограничение плавающего типа 3.5.7, ограничение фиксированного типа 3.5.9, оператор вызова процедуры 6.4, описание 3.1, описание настройки 12.1, определение типа 3.3.1, отрезок 4.1.2, пакет 7, подпрограмма 6, подтип 3.3, предвыполнение 3.9, предопределенная операция 4.5, преобразование 4.6, процедура б, совмещение 6.6, 8.7, сопоставление параметров 6.4, составной тип 3.3, спецификатор представления 13.1, спецификация пакета 7.1, спецификация подпрограммы 6.1, ссылочное значение 3.8, тип 3.3, указание подтипа 3.3.2, фактический параметр 6.4.1, формальный параметр 6.1.

Пред. | Уровень выше | След.
3.3. ТИПЫ И ПОДТИПЫ | Начало | 3.5. СКАЛЯРНЫЕ ТИПЫ


3.5. СКАЛЯРНЫЕ ТИПЫ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.5. СКАЛЯРНЫЕ ТИПЫ

Под скалярными типами подразумеваются перечислимые, целые и вещественные типы. Перечислимые и целые типы называются дискретными типами; каждое значение дискретного типа имеет номер позиции — целое значение. Целые и вещественные типы называются числовыми типами. Все скалярные типы упорядочены, т.е. для их значений предопределены все операции отношения.

ограничение-диапазона ::= range диапазон
диапазон ::= атрибут-диапазона
    |простое-выражение .. простое-выражение

Диапазон определяет подмножество значений скалярного типа. Диапазон L. .R определяет значения от L до R включительно, если истинно отношение L < = R. Значения L и R называются соответственно нижней границей и верхней границей диапазона. Значение V удовлетворяет ограничению диапазона, если оно принадлежит диапазону; говорят, что значение V принадлежит диапазону, если одновременно истинны отношения L<=V и V<=R. Пустой диапазон — это диапазон, для которого истинно отношение R < L; пустому диапазону не принадлежит никакое значение. Операции < = и < в вышеприведенных определениях являются предопределенными операциями над скалярными типами.

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

Предвыполнение ограничения диапазона состоит из вычисления диапазона. Вычисление диапазона определяет его нижнюю и верхнюю границы. Если границы заданы простыми выражениями, вычисление диапазона вычисляет эти выражения в порядке, который не определен в языке.

Атрибуты

Для любого скалярного типа Т или для любого подтипа Т скалярного типа определены следующие атрибуты:

Т'FIRST | Вырабатывает значение нижней границы Т. Значение этого атрибута имеет тип Т.
Т'LAST | Вырабатывает значение верхней границы Т. Значение этого атрибута имеет тип Т.

Примечание. Индексирование и правила итерации используют значения дискретных типов.

Ссылки: атрибут 4.1.4, атрибут диапазона 3.6.2, вещественный тип 3.5.6, вычисление 4.5, индекс 3.6, обозначение типа 3.3.2, ограничение 3.3, ограничение плавающего типа 3.5.7, ограничение фиксированного типа 3.5.9, оператор цикла 5.5, операция отношения 4.5, 4.5.2, ошибочный 1.6, перечислимый тип 3.5.1, простое выражение 4.4, удовлетворяет ограничению 3.3, указание подтипа 3.3.2, целый тип 3.5.4.

3.5.1. ПЕРЕЧИСЛИМЫЕ ТИПЫ

Определение перечислимого типа задает перечислимый тип

определение - перечислимого - типа:: =

(спецификация -литерала-перечисления (, спецификация - литерала - перечисления))

спецификация-литерала-перечисления ::= литерал-перечисления литерал-перечисления ::= идентификатор|символьный-литерал

Идентификаторы и символьные литералы, перечисленные в определении перечислимого типа, должны быть различными. Каждая спецификация литерала перечисления является его описанием; это описание эквивалентно описанию функции без параметров, обозначение которой — литерал перечисления, а тип результата — перечислимый тип. Предвыполнение определения перечислимого типа создает перечислимый тип; это Предвыполнение включает пред-выполнение каждой спецификации литерала перечисления.

Каждый литерал перечисления вырабатывает отличное от других перечислимое значение. Предопределенные операции отношения упорядоченности между перечислимыми значениями следуют порядку, соответствующему номерам позиций; номер позиции первого значения в списке литералов перечисления равен нулю; номер каждого следующего литерала перечисления на единицу больше номера предыдущего литерала в списке.

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

Примеры:

type DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);
type SUIT is (CLUBS, DIAMONDS, HEARTS, SPADES);
type GENDER is (M, F);
type LEVEL is (LOW, MEDIUM, URGENT);
type COLOR is (WHITE, RED, YELLOW, GREEN, BLUE, BROWN, BLACK);
type LIGHT is (RED, AMBER, GREEN); -- RED И GREEN совмещены

type HEXA is ('A', 'B', 'C', '0', 'E', 'F');
type MIXED is ('A', 'B', '*', B, NONE, '?', '%');

subtype WEEKDAY is DAY range MON .. FRI;
subtype MAJOR is SUIT range HEARTS .. SPADES:
subtype RAINBOW is COLOR range RED .. BLUE; -- цвет, НО не свет

Примечание. Если литерал перечисления встречается в контексте, недостаточном для определения типа литерала, то один из путей разрешения неоднозначности — это применение квалифицированного выражения с именем перечислимого типа (см. 4.7).

Ссылки: идентификатор 2.3, имя 4.1, квалифицированное выражение 4.7, номер позиции 3.5, обозначение 6.1, операция отношения 4.5, 4.5.2, описание 3.1, определение типа 3.3.1, пред-выполнение 3.9, 6.1, символьный литерал 2.5, совмещение 6.6, 8.7, тип 3.3, функция 6.5.

3.5.2. СИМВОЛЬНЫЕ ТИПЫ

Перечислимый тип называется символьным, если хотя бы один из его Питералов перечисления является символьным литералом. Предопределенный тип CHARACTER — символьный тип, значения которого представляют собой 128 символов стандартного набора ASCII. Каждый из 95 графических символов этого символьного набора обозначен соответствующим символьным литералом.

Пример:

type ROMAN_DIGIT is (Т, 'V. 'X', 'L', 'С', 'D', 'М');

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

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

Ссыпки: графический символ 2.1, идентификатор 2.8, константа 3.2.1, литерал 4.2, описание 3.1, основной символ 2.1, перечислимый тип 3.5.1, предопределенный пакет С, предопределенный тип С, символьный литерал 2.5, тип 3.3.

3.5.3. ЛОГИЧЕСКИЕ ТИПЫ

Существует предопределенный перечислимый тип, именуемый BOOLEAN. Он содержит два литерала FALSE и TRUE, упорядоченные соотношением FALSE < TRUE. Логический тип — это тип BOOLEAN или производный непосредственно или косвенно от логического типа.

Ссылки: литерал перечисления 3.5.1, операция отношения 4.5, 4.5.2, перечислимый тип 3.5.1, производный тип 3.4, тип 3.3.

3.5.4. ЦЕЛЫЕ ТИПЫ

Определение целого типа задает целый тип, набор значений которого включает значения заданного диапазона.

определение-целого-типа ::= ограничение-диапазона

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

type Т is range L .. R ;

по определению эквивалентно следующим описаниям:

type целый- тип is new предопределенный-целый-тип;

subtype Т is целый-тип range целый- тип (L) .. целый-тип (R);

где целый-тип — это анонимный тип, а предопределенный целый тип выбран реализацией и содержит значения от L до R включительно. Описание целого типа неправильно, если ни один из предопределенных целых типов не удовлетворяет этому требованию, за исключением типа универсальный-целый. Предвыполнение описания целого типа состоит из предвыполне-ния эквивалентных описаний типа и подтипа.

Предопределенные целые типы включают тип INTEGER. Реализация может также иметь предопределенные типы SHORT-INTEGER и LONG-INTEGER, диапазоны которых соответственно (существенно) уже и шире, чем у типа INTEGER. Диапазон этих типов должен быть симметричным относительно нуля, кроме наименьшего из отрицательных значений, которое может существовать в некоторых реализациях. Базовым для каждого из этих типов является он сам.

Целые литералы — это литералы анонимного предопределенного целого типа, который в данном руководстве называется универсальным-целым. Другие целые типы не имеют литералов. Однако для каждого целого типа существует неявное преобразование универсального-целого значения в соответствующее значение (если оно есть) целого типа. Обстоятельства, в которых применяются такие неявные преобразования, описаны в разд. 4.6.

Номер позиции целого значения — это соответствующее значение типа универсальный-цепый.

Для всех целых типов предопределены одни и те же арифметические операции (см. 4.5). Исключение NUMERIC-ERROR возбуждается при выполнении операции (в частности, неявного преобразования), которая не может передать корректный результат (т.е. значение, соответствующее математическому результату, не является значением целого типа). Однако от реализации не требуется возбуждения исключения NUMERIC_ERROR, если операция является частью большего выражения, результат которого может быть вычислен корректно, как пояснено в разд. 11.6.

Примеры:

type PAGE_NUM is range 1 .. 2_000;
type LINE_SIZE is range 1 .. MAX_LINE_SIZE;

subtype SMAL_IINT is INTEGER range -10 .. 10;
subtype COLUMN_PTR is LINESIZE range 1 .. 10:
subtype BUFFER_SIZE is INTEGER range 0 .. МАХ;

Примечание. Имя в описании целого типа — это имя подтипа. С другой стороны, предопределенные операции над целым типом определяют результат, который принадлежит диапазону, определяемому родительским предопределенным типом; такой результат не обязательно принадлежит описанному подтипу, и попытка присвоить такой результат переменной целого подтипа возбуждает исключение CONSTRAINT_ERROR. Наименьшее (наибольшее по модулю отрицательное) значение, поддержанное реализацией для предопределенных целых типов, есть именованное число SYSTEM.MIN_INT, а наибольшее (из положительных) значение — SYSTEM.MAX_INT (см. 13.7).

Ссылки: анонимный тип 3.3.1, граница диапазона 3.5, идентификатор 2.3, исключение CONSTRAINT_ERROR 11.1, исключение NUMERIC-ERROR 11.1, литерал 4.2, ограничение диапазона 3.5, описание подтипа 3.3.2, описание типа 3.3.1, определение типа 3.3.1, предопределенная операция 4.5, предопределенный пакет системы 13.7, преобразование 4.6, принадлежит подтипу 3.3, родительский тип 3.4, статическое выражение 4.9, тип 3.3, универсальный тип 4.10, целый литерал 2.4.

3.5.5. ОПЕРАЦИИ НАД ДИСКРЕТНЫМИ ТИПАМИ

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

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

Первая группа атрибутов вырабатывает характеристики подтипа Т. Эта группа включает атрибут ВАЗЕ (см. 3.3.3), атрибуты FIRST и LAST (см. 3.5), атрибут представления SIZE (см. 13.7.2) и атрибут WIDTH, определенный следующим образом:

T'WIDTH

Вырабатывает максимальную длину образа по всем значениям подтипа Т {образ — это последовательность символов, вырабатываемая атрибутом IMAGE, см. ниже). Вырабатывает нуль для пустого диапазона. Значения этого атрибута имеют тип универсальный-целый.

Все атрибуты второй группы — это функции с одним параметром. Соответствующий фактический параметр обозначен ниже идентификатором X.

Т'РОS | Параметр Х должен быть значением базового типа Т. Тип результата — универсальный-целый. Результат — номер позиции для значения параметра.
T'VAL | Параметр Х может быть любого целого типа. Тип результата — базовый тип Т. По заданному значению Х — номеру позиции — функция вырабатывает значение в этой позиции. Если соответствующее Х — универсальное-целое значение — не принадлежит диапазону T'POS(T'BASE'FIRST). .T'POS(T'BASE'LAST), то возбуждается исключение CONSTRAINT_ERROR.
T'SUCC | Параметр X должен быть значением базового типа Т. Тип результата — базовый тип Т. Результат — значение с номером позиции, на единицу большим номера позиции для значения X. Если Х равен T'BASE'LAST, то возбуждается исключениеCONSTRAINT_ERROR.
T'PRED | Параметр Х должен быть значением базового типа Т. Тип результата — базовый тип Т. Результат — значение с номером позиции, на единицу меньшим номера позиции для значения X. Если Х равно T'BASE'FIRST, то возбуждается исключение CONSTRAINT - ERROR.
T'IMAGE | Параметр Х должен быть значением базового типа Т. Тип результата — предопределенный тип STRING. Результат — образ значения X, т.е. последовательность символов, представляющих изображение значения. Образу целого значения соответствует десятичный литерал без подчеркиваний, предшествующих нулей, порядка и пробелов справа, но с одним символом минус или пробелом слева. Нижняя граница образа есть единица. Образ литерала перечисления — это либо соответствующий идентификатор из прописных букв, либо соответствующий символьный литерал (включая два апострофа); пробелы не включаются ни слева, ни справа. Образ символа С, отличного от графического символа, зависит от реализации; должно выполняться равенство СНАRАСТЕR'VАLUЕ(СНАRАСТЕR'IМАGЕ(С))=С.
T'VALUE | Параметр Х должен быть значением предопределенного типа STRING. Тип результата — базовый тип Т. Игнорируются любые пробелы слева и справа от последовательности символов, соответствующих параметру. Если для перечислимого типа последовательность символов имеет синтаксис литерала перечисления и если этот литерал существует для базового типа Т, то результат — соответствующее значение перечислимого типа. Если для целого типа последовательность символов имеет синтаксис целого литерала с возможным знаком минус или плюс слева и если существует соответствующее значение базового типа Т, то результат есть это значение. Во всех остальных случаях возбуждается исключение CONSTRAINT_ERROR.

Кроме того, для объекта А дискретного типа определены атрибуты A'SIZE и A'ADDRESS (см. 13.7.2).

Кроме базовых операции над дискретными типами включают предопределенные операции отношения. Для перечислимых типов операции включают литералы перечисления. Для логических типов операции включают предопределенную унарную логическую операцию отрицания not и предопределенные логические операции. Для целых типов операции включают предопределенные арифметические операции: унарные и бинарные аддитивные операции - и +, все мультипликативные операции, унарную операцию abs и операцию возведения в степень.

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

Примечание. Для подтипа дискретного типа переданные атрибутами SUCC, PRED, VAL и VALUE результаты не обязательно принадлежат подтипу; аналогично фактические параметры атрибутов POS, SUCC, PRED и IMAGE не обязаны принадлежать подтипу. Эти атрибуты удовлетворяют (при отсутствии исключения) следующим соотношениям:

T'POS(T'SUCC(X)) = T'POSfX) + 1
T'POS(T'PRED(X)) = T'POS(X) - 1

T'VAL(T'POS(X)) = X
T'POS(T'VAL(N)) = N

Примеры:
-- для типов и подтипов, описанных в 3.5.1

-- COLOR'FIRST = WHITE, COLOR'LAST = BLACK
-- RAINBOW'FIRST = RED, RAINBOW'LAST = BLUE

-- COLOR'SUCC(BLUE) = RAINBOW'SUCC(BLUE) = BROWN
-- COLOR'POS(BLUE) = RAINBOW'POS(BLUE) = 4
-- COLOR'VAL(O) = RAINBOW'VAL(O) = WHITE

Ссылки: атрибут 4.1.4, базовая операция 3.3.3, базовый тип 3.3, бинарная аддитивная операция 4.5, 4.5.3, граница диапазона 3.5, графический символ 2.1, дискретный тип 3.5, идентификатор 2.3, исключение CONSTRAINT_ERROR 11.1, квалифицированное выражение 4.7, литерал перечисления 3.5.1, логическая операция 4.5, 4.5.1, логический тип 3.5.3, мультипликативная операция 4.5, 4.5.5, номер позиции 3.5, объект 3.2, ограничение 3.3, операция 3.3, операция возведения в степень 4.5, 4.5.6, операция отношения 4.5, 4.5.2, операция отрицания 4.5, 4.5.6, операция управления с промежуточной проверкой 4.5, 4.5.1, подтип 3.3, предопределенная операция 4.5, предопределенный тип С, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, символьный литерал 2.5, строковый тип 3.6.3, тип 3.3, тип универсальный целый 3.5.4, унарная аддитивная операция 4.5, 4.5.4, универсальный тип 4.10, функция 6.5, целый тип 3.5.4, числовой литерал 2.4, числовой тип 3.3.

3.5.6. ВЕЩЕСТВЕННЫЕ ТИПЫ

Вещественные типы обеспечивают приближение вещественных чисел с относительной погрешностью для плавающих типов и с абсолютной погрешностью для фиксированных типов.

определение-вещественного-типа :: =

ограничение - плавающего - типа [ограничение - фиксированного - типа

С каждым вещественным типом связан набор чисел, называемых модельными числами. Границы ошибок в предопределенных операциях даны в терминах модельных чисел. Реализация типа должна включать по крайней мере эти модельные числа и представлять их точно.

С каждым вещественным типом связан зависящий от реализации набор чисел, называемых хранимыми числами. Набор хранимых чисел вещественного типа должен включать по крайней мере набор модельных чисел типа. Допустимо, чтобы диапазон хранимых чисел был больше диапазона модельных чисел, но границы ошибок предопределенных операций над хранимыми числами определены теми же правилами, что и для модельных чисел. Хранимые числа по этой причине обеспечивают гарантированные границы ошибок для операций над зависящим от реализации диапазоном чисел; напротив, диапазон модельных чисел зависит только от определения вещественного типа и поэтому не зависит от реализации.

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

Выполнение операции типа вырабатывает значение вещественного типа и может возбудить исключение NUMERIC_ERROR, как поясняется в разд. 4.5.7, если она не может вырабатывать корректный результат (т.е. соответствующее одному из возможных математических результатов значение не принадлежит диапазону хранимых чисел); в частности, это исключение может быть возбуждено неявным преобразованием. Однако от реализации не требуется возбуждать исключение NUMERIC_ERROR, если операция — часть большего выражения, которое может быть корректно вычислено (см. 11.6).

Предвыполнение определения вещественного типа включает предвыполнение ограничения плавающего или фиксированного типа и создает вещественный тип.

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

Ссылки: вещественный литерал 2.4, исключение NUMERIC_ERROR 11.1, литерал 4.2, ограничение плавающего типа 3.5.7, ограничение фиксированного типа 3.5,7, определение типа 3.3.1, предопределенная операция 3.3.3, предвыполнение 3.9, преобразование 4.6, тип 3.3, универсальный тип 4.10.

3.5.7. ПЛАВАЮЩИЕ ТИПЫ

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

ограничение-плавающего-типа ::=

определение - точности - плавающего - типа [ограничение - диапазона] определение - точности - плавающего - типа:: = digits статическое- простое - выражение

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

Для данного основания определена следующая каноническая форма отличного от нуля модельного числа плавающего типа:

знак *мантисса *(основание**порядок)

В этой форме: знак — либо +1, либо -1; мантисса выражена в системе счисления, заданной основанием; порядок — целое число (возможно, отрицательное), такое, что целая часть мантиссы равна нулю, а первая цифра ее дробной части не равна нулю.

Число D — минимальное требуемое число десятичных цифр после точки в десятичной мантиссе (т.е.' если основание равно десяти). Значение D в свою очередь определяет число В — минимальное требуемое число двоичных цифр после точки в двоичной мантиссе (т.е. если основание равно двум). Число В связано с D и равно такому минимальному значению, что относительная точность двоичной формы не меньше точности для десятичной формы. (Число В равно ближайшему целому, превышающему (D*log(10)/log(2)) +1.)

Модельные числа, заданные определением точности плавающего типа, включают нуль и все числа, у которых двоичная каноническая форма имеет точно В цифр после точки в мантиссе и порядок в диапазоне -4*В.. +4*В. Гарантированная минимальная точность операций над плавающим типом определена в терминах его модельных чисел с ограничением плавающего типа, которое формирует соответствующее определение вещественного типа (см. 4.5.7).

Предопределенные плавающие типы включают тип FLOAT. Реализация может иметь также предопределенные типы SHORT_FLOAT и LONG_FLOAT с точностью (существенно) меньшей и большей соответственно, чем у FLOAT. Базовым типом каждого предопределенного плавающего типа является он сам. Модельные числа каждого предопределенного плавающего типа определены числом D десятичных цифр, вырабатываемых атрибутом DIQITS (см. 3.5.8).

Для каждого предопределенного плавающего типа (а следовательно, и для каждого производного от него типа) набор хранимых чисел определен следующим образом. Хранимые числа имеют то же самое число цифр В мантиссы, что и модельные числа типа, а порядок — в диапазоне -Е.. +Е, где Е зависит от реализации и равно по крайней мере 4*В для модельных чисел. (Следовательно, хранимые числа включают модельные числа.) Правила определения точности операций над модельными и хранимыми числами Даны в разд. 4.5.7. Хранимые числа подтипа те же, что и для его базового типа.

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

type Т is digits D [range L .. R];

по определению эквивалентно следующим описаниям:

type плавающий - тип is new предопределенный-плавающий-тип;
subtype T is плавающий-тип digits D
[range плавающий-тип (L). .плавающий -тип (R)];

где плавающий-тип является анонимным, а предопределенный плавающий тип неявно выбран реализацией так, что его модельные числа определяются значением D; кроме того, если добавлен диапазон L.-R, то L и R должны принадлежать диапазону хранимых чисел. Описание плавающего типа неправильно, если ни один из предопределенных плавающих типов не удовлетворяет этим требованиям, кроме типа универсальный-вещественный. Максимальное число цифр, которое может быть задано определением точности плавающего типа, определяется именованным числом SYSTEM.MAX_DIGITS (см. 13.7.1).

Предвыполнение описания плавающего типа состоит из предвыполнения эквивалентных описаний типа и подтипа.

Если ограничение плавающего типа следует за обозначением типа в указании подтипа, то обозначение типа должно задавать плавающий тип или подтип. Ограничение плавающего типа совместимо с обозначением типа, только если число D в определении точности плавающего типа не больше соответствующего числа D для типа или подтипа в обозначении типа. Кроме того, если ограничение плавающего типа включает ограничение диапазона, то ограничение плавающего типа совместимо с обозначением типа, только если ограничение диапазона совместимо с обозначением типа.

Предвыполнение такого указания подтипа включает Предвыполнение ограничения диапазона, если оно есть; оно создает подтип плавающего типа, модельные числа которого определены соответствующим определением точности плавающего типа. Значение плавающего типа принадлежит плавающему подтипу тогда у только тогда, когда оно принадлежит диапазону подтипа.

Одни и те же арифметические операции предопределены для всех плавающих типов (см. 4.5).

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

Примеры:

type COEFFICIENT is digits 10 range -1.0 .. 1.0;

type REAL is digits 8;
type MASS is digits 7 range 0.0 .. 1.0Е35;

subtype SHORTCOEFF is COEFFICIENT digits 5; -- подтип с  меньшей точностью
subtype PROBABILITY is REAL range 0.0 .. 1.0; -- подтип с меньшим диапазоном

Примечание к примерам. Реализованная точность для типа COEFFICIENT — это точность предопределенного типа, имеющего по меньшей мере 10 цифр мантиссы. Следовательно, спецификация пяти цифр точности для подтипа SHORT_COEFF допустима. Наибольшее модельное число для типа MASS равно приблизительно 1.ОЕ21 и, следовательно, меньше, чем заданная верхняя граница, (1.0Е35). Следовательно, описание этого типа правильно, только если эта верхняя граница принадлежит диапазону хранимых чисел предопределенного плавающего типа, имеющего по меньшей мере 7 цифр точности.

Ссылки: анонимный тип 3.3.1, арифметическая операция 3.5.5, 4.5, вещественный тип 3.5.6, граница диапазона 3.5, граница ошибки 3.5.6, литерал с основанием 2.4.2, модельное число 3.5.6, обозначение типа 3.3.2, ограничение диапазона 3.5, операция 3.3., описание подтипа 3.3.2, описание типа 3,3.1, определение вещественного типа 3.5.6, принадлежит подтипу 3.3, подтип 3.3, порядок 2.4.1, Предвыполнение 3.1, 3.9, предопределенная операция 4.5, предопределенный тип С, производный тип 3.4, простое выражение 4.4, совместимый 3.3.2, статическое выражение 4.9, тип 3.3, указание подтипа 3.3.2, хранимое число 3.5.6, целый тип 3.5.4, цифра 2.1.

3.5.8. ОПЕРАЦИИ НАД ПЛАВАЮЩИМИ ТИПАМИ

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

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

Первая группа атрибутов вырабатывает характеристики подтипа Т. К атрибутам этой группы относятся атрибут ВАSЕ (см. 3.3.3), атрибуты FIRST и LAST (см. 3.5), атрибут представления SIZE (см. 13.7.2), а также следующие атрибуты:

T'DIGITS | Вырабатывает число десятичных цифр в десятичной мантиссе модельных чисел подтипа Т. (Этот атрибут вырабатывает число D, см. разд. 3.5.7.) Значение этого атрибута имеет тип универсальный-целый.
T'MANTISSA | Вырабатывает число двоичных цифр в двоичной мантиссе модельных чисел подтипа Т. (Этот атрибут вырабатывает число В, см. разд. 3.5.7.) Значение этого атрибута имеет тип универсальный-целый.
T'EPSILON | Вырабатывает абсолютное значение разности между модельным числом 1.0 и следующим модельным числом подтипа Т. Значение этого атрибута имеет тип универсальный-вещественный.
T'EMAX | Вырабатывает наибольшее значение порядка двоичной канонической формы модельных чисел подтипа Т. (Этот атрибут вырабатывает произведение 4*В, см. разд. 3.5.7.) Значение этого атрибута имеет тип универсальный-целый.
T'SMALL | Вырабатывает наименьшее положительное (ненулевое) модельное число подтипа Т. Значение этого атрибута имеет тип универсальный-вещественный.
T'LARGE | Вырабатывает наибольшее положительное модельное - число подтипа Т. Значение этого атрибута имеет тип универсальный- вещественный.

Атрибуты второй группы вырабатывают характеристики хранимых чисел и включают следующие атрибуты:

T'SAFE-EMAX | Вырабатывает наибольшее значение порядка двоичной канонической формы хранимых чисел базового типа Т. (Этот атрибут вырабатывает число Е, см. разд. 3.5.7.) Значение этого атрибута имеет тип универсальный-целый.
T'SAFE-SMALL | Вырабатывает наименьшее положительное (ненулевое) хранимое число базового типа Т. Значение этого атрибута имеет тип унивеосальный- вещественный.

T'SAFE_LARGE | Вырабатывает наибольшее положительное хранимое число базового типа Т. Значение этого атрибута имеет тип универсальный - вещественный.

Кроме этого, для объекта А плавающего типа определены атрибуты A'SIZE и A'ADDRESS (см. 13.7.2). Для каждого плавающего типа существуют машинно-зависимые атрибуты, которые не относятся к модельным и хранимым числам. Они соответсвуют обозначениям атрибутовMACHINE_EMAX, MACHINE_EMIN, MACHINE_RADIX, MACHINE_MANTISSA,

MACHINE_ROUNDS и MACHINE_OVERFLOWS (см. 13.7.3).

Кроме базовых операций над плавающим типом определены операции отношения и следующие предопределенные арифметические операции: унарные и бинарные аддитивные операции - и +, мультипликативные операции » и /, унарная операция abc и операция возведения в степень.

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

Примечание. Атрибуты ЕМАХ, SMALL, LARGE и EPSILON связаны с атрибутом MANTISSA следующими формулами:

Т'ЕМАХ = 4*T'MANTISSA

T'EPSILON = 2.0**(1 - T'MANTISSA)

T'SMALL = 2.0**(-Т'ЕМАХ - 1)

T'LARGE = 2.0**Т'ЕМАХ * (1.0 - 2.0**(-T'MANTISSA))

Атрибут MANTISSA, дающий число двоичных цифр в мантиссе, сам связан с атрибутом DIGITS.

Между характеристиками модельных и хранимых чисел справедливы следующие соотношения:

T'BASE_EMAX <= T'SAFE_EMAX T'BASE_SMALL >= T'SAFE_SMALL T'BASE_LARGE <= T'SAFE_LARGE

Атрибуты T'FIRST и T'LAST не обязательно вырабатывают модельные или хранимые числа. Если некоторое число цифр определено описанием типа или подтипа Т, то атрибут DIGITS вырабатывает это число.

Ссылки: арифметическая операция 3.5.5, 4.5, атрибут 4.1.4, базовая операция 3.3.3, базовый тип 3.3, бинарная аддитивная операция 4.5, 4.5.3, границы диапазона 3.5, квалифицированное выражение 4.7, модельное число 3.5.6, мультипликативная операция 4.5, 4.5.5, объект 3.2, ограничение 3.3, операция 3.3, операция возведения в степень 4.5, 4.5.6, операция отношения 4.5, 4.5.2, плавающий тип 3.5.7, подтип 3.3, предопределенная операция 4.5, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, тип 3.3, тип универсальный вещественный 3.5.6, тип универсальный целый 3.5.4, унарная аддитивная операция 4.5, 4.5.4, универсальный тип 4.10, хранимое число 3.5.6, цифра 2.1, числовой тип 3.5.

3.5.9. ФИКСИРОВАННЫЕ ТИПЫ

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

ограничение-фиксированного-типа :: =

определение - точности - фиксированного - типа [ограничение - диапазона]

определение - точности - фиксированного - типа:: = delta статическое- простое - выражение

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

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

знак*мантисса*дискрет

Для модельных чисел фиксированного типа дискрет выбран как наибольшая степень двух, которая не превышает дельту определения точности фиксированного типа. Дискрет можно также задать спецификатором длины (см. 13.2), в этом случае модельные числа кратны заданному значению. Гарантированная минимальная точность операций над фиксированным типом определена в терминах модельных чисел из ограничения для фиксированного типа, которое образует соответствующее определение вещественного типа (см. 4.5.7).

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

Реализация должна иметь по крайней мере один анонимный предопределенный фиксированный тип. Базовый тип каждого такого фиксированного типа — это сам этот тип. Модельные числа каждого предопределенного фиксированного типа включают нуль и все числа, для которых мантисса (в канонической форме) имеет число двоичных цифр, вырабатываемое атрибутом MANTISSA, и для которых дискрет имеет значение, возвращаемое атрибутом SMALL

Описание фиксированного типа в форме

type T is delta D range L .. R

по определению эквивалентно следующим описаниям:

type фиксированный-тип is new

предопределенный - фиксированный - тип;

subtype T is фиксированный-тип delta D range

фиксированный-тип (L) .. фиксированный-тип (R);

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

Описание фиксированного типа неправильно, если не существует предопределенного типа, удовлетворяющего этим требованиям. Хранимые числа фиксированного типа — это модельные числа его базового типа.

Предвыполнение описания фиксированного типа состоит из предвыполнения эквивалентных описаний типа и подтипа.

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

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

Для всех фиксированных типов предопределены одни и те же арифметические операции (см. 4.5). Умножение и деление значений фиксированного типа дают результаты анонимного предопределенного фиксированного типа, который в данном стандарте называется универсальный-фиксированный; точность этого типа произвольна. Значения этого типа должны быть явно преобразованы в значения некоторого числового типа.

Примечание. Если S — подтип фиксированного типа или подтипа Т, то набор модельных чисел S — это подмножество модельных чисел Т. Если для Т был задан спецификатор длины, то Т и S имеют одно и то же значение дискрета. В противном случае поскольку дискрет равен степени двух, то дискрет для S равен дискрету для Т, умноженному на неотрицательную степень двух.

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

Примеры:

type VOLT is delta 0.125 range 0.0 .. 255.0;
subtype ROUGH_VOLTAGE is VOLT delta 1.0; — диапазон, как у VOLT

-- Правильная дробь, требующая полного машинного слова в
-- дополнительном коде, может быть описана как тип FRACTION:

DEL : constant := 1.0/2**(WORD_LENGTH - 1);
type FRACTION is delta DEL range -1.0 .. 1.0 - DEL;

Ссылки: анонимный тип 3.3.1, арифметическая операция 3.5.5, 4.5, базовый тип 3.3, вещественный тип 3.5.6, граница диапазона 3.5, граница ошибки 3.5.6, модельное число 3.5.6, обозначение типа 3.3.2, ограничение диапазона 3.5, операция 3.3, описание подтипа 3.3.2, описание типа 3.3.1, определение вещественного типа 3.5.6, подтип 3.3, предвыполнение 3.9, предопределенная операция 4.5, преобразование 4.6, принадлежит подтипу 3.3, простое выражение 4.4, совместимо 3.3.2, спецификатор длины 13.2, статическое выражение 4.9, тип 3.3, указание подтипа 3.3.2, хранимое число 3.5.6, числовой тип 3.

3.5.10. ОПЕРАЦИИ НАД ФИКСИРОВАННЫМИ ТИПАМИ

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

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

Первая группа атрибутов вырабатывает характеристики подтипа Т. К этой группе относятся атрибуты ВАЗЕ (см. 3.3.3), FIRST и LAST (см. 3.5), атрибут представления SIZE (см. 13.7.2) и следующие атрибуты:

T'DELTA | Вырабатывает значение дельты, заданной в определении точности фиксированного типа для подтипа Т. Значение этого атрибута имеет тип универсальный-вещественный.
T'MANTISSA | Вырабатывает число двоичных цифр в мантиссе модельных чисел подтипа Т. (Этот атрибут вырабатывает число В, см. 3.5.9.) Значение этого атрибута имеет тип универсальный-целый.
T'SMALL | Вырабатывает наименьшее положительное (ненулевое) модельное число подтипа Т. Значение этого атрибута имеет тип универсальный-вещественный.
T'LARGE | Вырабатывает наибольшее модельное число подтипа Т. Значение этого атрибута имеет тип универсальный,вещественный.
T'FORE | Вырабатывает минимальное число символов, необходимых для десятичного представления целой части любого значения подтипа Т в предположении, что это представление не включает порядок, но включает один символ, который является либо знаком минус, либо пробелом. (Это минимальное число не учитывает предшествующие нули и подчеркивания и по меньшей мере равно двум.) Значение этого атрибута имеет тип универсальный-целый.
T'AFT | Вырабатывает число десятичных цифр после точки, необходимых для обеспечения точности подтипа Т, если только DELTA подтипа Т не превышает 0.1, а для этого значения атрибут вырабатывает значение единицы. (T'AFT — это самое малое положительное целое К, для которого (10«*К)*Т'ОЕ1ТА больше или равно единице.) Значение этого атрибута имеет тип универсальный_целый.

Вторая группа включает следующие атрибуты, которые вырабатывают характеристики хранимых чисел:

T'SAFE_SMALL | Вырабатывает наименьшее положительное (ненулевое) хранимое число базового типа Т. Значение этого атрибута имеет тип универсальный-вещественный.
T'SAFE_LARGE | Вырабатывает наибольшее положительное хранимое число базового типа Т. Значение этого атрибута имеет тип универсальный- вещественный.

Кроме того, для объекта А фиксированного типа определены атрибуты A'SIZE и A'ADDRESS (см. 13.7.2). Для каждого фиксированного типа или подтипа Т существуют машинно-зависимые атрибуты T'MACHINE_ROUNDS и T'MACHINE_OVERFLOWS (см. 13.7.3).

Кроме базовых в состав операций над фиксированным типом входят операции отношения и следующие предопределенные арифметические операции: унарные и бинарные аддитивные операции - и +, мультипликативные операции «и/и операция abs.

Операции над подтипом — это соответствующие операции над типом, кроме следующих: присваивания, проверки принадлежности, квалификации, явного преобразования и атрибутов первой группы; результат этих операций определен в терминах подтипа.

Примечание. Значение атрибута T'FORE зависит только от диапазона подтипа Т. Значение атрибута T'AFT зависит только от значения T'DELTA. Между атрибутами фиксированного типа существуют следующие соотношения:

T'LARGE = (2**Т'MANTISSА - 1) * T'SMALL T'SAFE_LARGE = T'BASE'LARGE T'SAFE_SMALL = T'BASE'SMALL

Ссылки: арифметическая операция 3.5.5, 4.5, базовая операция 3.3.3, базовый тип 3.3, бинарная аддитивная операция 4.5, 4.5.3, граница диапазона 3.5, дельта 3.5.9, квалифицированное выражение 4.7, модельное число 3.5.6, мультипликативная операция 4.5, 4.5.5, объект 3.2, операция 3.3, операция abs 4.5, 4.5.6, операция отношения 4.5, 4.5.2, подтип 3.3, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, унарная аддитивная операция 4.5, 4.5.4, универсальный вещественный тип 3.5.6, универсальный целый тип 3.5.4, фиксированный тип 3.5.9, хранимое число 3.5.6, числовой тип 3.5.

Пред. | Уровень выше | След.
3.4. ПРОИЗВОДНЫЕ ТИПЫ | Начало | 3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ


3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ

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

опеределение-индексируемого-типа :: =
     определение-неограниченного-индексируемого-типа
   | определение-ограниченного-индексируемого-типа

определение-неограниченного-индексируемого-типа ::=
    array (определение-подтипа-индекса {, определение-подтипа-индекса}) of
    указание-подтипа-компоненты

определение-ограниченного-индексируемого-типа:: =
    array ограничение-индекса of указание-подтипа-компоненты

определение-подтипа-индекса ::= обозначение-типа range < >
ограничение-индекса ::= (дискретный-диапазон {, дискретный-диапазон})
дискретный-диапазон :: = указание-дискретного-подтипа | диапазон

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

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

Определение неограниченного индексируемого типа определяет индексируемый тип. Для каждого объекта индексируемого типа число индексов, тип и позиция каждого индекса, а также подтип компонент будут такими, как в определении типа; значение нижней и верхней границ для каждого индекса принадлежит соответствующему подтипу индекса, кроме пустых массивов, как пояснено в разд. 3.6.1. Подтипом индекса для данной позиции индекса по определению является подтип, указанный обозначением типа соответствующего определения подтипа индекса. Составной ограничитель < > (бокс) в определении подтипа индекса помещается для неопределенного диапазона (различные объекты данного типа не обязательно имеют одни и те же границы). Предвыполнение определения неограниченного индексируемого типа создает индексируемый тип: оно включает Предвыполнение указания подтипа компонент.

Определение ограниченного индексируемого типа определяет индексируемый тип и подтип этого типа:

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

• Индексируемый подтип — это подтип, полученный наложением ограничения индекса на индексируемый тип.

Если определение ограниченного индексируемого типа дано для описания типа, то простое имя, введенное этим описанием, обозначает индексируемый подтип.

Предвыполнение определения ограниченного индексируемого типа создает соответствующий индексируемый тип и индексируемый подтип. При этом предвыполняются ограничение индекса и указание подтипа компонент. Вычисление каждого дискретного диапазона ограничения индекса и Предвыполнение указания подтипа компонент осуществляются в порядке, не определяемом языком.

Примеры описаний типа с определениями неограниченного индексируемого типа:

type VECTOR is array (INTEGER range <>) of REAL;

type MATRIX is array (INTEGER range <>, INTEGER range <>) of REAL;

type BIT_VECTOR is array (INTEGER range <>) of BOOLEAN;

type ROMAN is array (POSITIVE range 0) of ROMAN_DIGIT:

Примеры описаний типа с определениями ограниченного индексируемого типа:

type TABLE is array (1 .. 10) of INTEGER;

type SCHEDULE is array (DAY) of BOOLEAN;

type LINE is array (1 .. MAX_LINE_SIZE) of CHARACTER:

Примеры описаний объектов с определениями ограниченного индексируемого типа:

GRID : array (1 .. 80, 1 .. 100) of BOOLEAN;

MIX : array (COLOR range RED .. GREEN) of BOOLEAN;

PAGE : array (1 .. 50) of LINE; -- массив массивов

Примечание. Данное для одномерного массива правило означает, что описание с определением ограниченного индексируемого типа, например

type Т is array( POSITIVE range MIN .. MAX) of COMPONENT;

эквивалентно (при отсутствии некорректной зависимости от порядка) последовательности описаний:

subtype под тип__индекса is POSITIVE range MIN .. МАХ;

type индексируемый _ тип is array (подтип_индекса range <>) of COMPONENT;

subtype Т is индексируемый_тип (подтип _ индекса)',

где подтип - индекса и индексируемый-тип оба анонимны. Следовательно, Т — имя подтипа, и все объекты, описанные с этим обозначением типа, — массивы, имеющие одни и те же границы. Аналогичные преобразования применяются к многомерным массивам.

Подобное преобразование применяется к объекту, описание которого включает определение ограниченного индексируемого типа. Следствием этого является то, что нет двух таких объектов одного и того же типа.

Ссылки: анонимный тип 3.3.1, в некотором порядке 1.6, граница диапазона 3.5, диапазон 3.5, дискретный тип 3.5, имя 4.1, компонента 3.3, обозначение типа 3.3.2, объект 3.2, ограничение 3.3, описание типа 3.3.1, определение типа 3,3.1, подтип 3.3, Предвыполнение 3.1, 3.9, тип 3.3, указание подтипа 3.3.2.

3.6.1. ОГРАНИЧЕНИЯ ИНДЕКСА И ДИСКРЕТНЫЕ ДИАПАЗОНЫ

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

Для дискретного диапазона, использованного в определении ограниченного индексируемого типа и определенного диапазоном, неявное преобразование к предопределенному типу INTEGER производится в том случае, если каждая граница — это либо числовой литерал, либо именованное число, либо атрибут, а тип обеих границ (до неявного преобразования) является универсальным-целым. В остальных случаях обе границы должны быть одного и того же дискретного типа, отличного от типа универсальный-целый', этот тип должен определяться независимо от контекста, но с учетом того, что тип должен быть дискретным и обе границы должны иметь один и тот же тип. Эти правила применимы также к дискретному диапазону, используемому в правиле итерации (см. 5.5) или в описании семейства входов (см. 9.5).

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

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

Границы каждого массива определены следующим образом:

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

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

• Для заданной описанием объекта константы индексируемого типа границы определены начальным значением, если подтип константы не ограничен; иначе они определены подтипом (в последнем случае начальное значение — это результат неявного преобразования подтипа). То же правило применимо к формальному параметру настройки вида in.

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

• Для формального параметра подпрограммы или входа границы получены от соответствующего фактического параметра. (Формальный параметр ограничен соответствующими зна- ' чениями границ.)

• Для описания переименования и для формального параметра настройки вида in out границы берутся у переименованного объекта или у соответствующего фактического параметра настройки.

Порядок вычисления дискретных диапазонов при предвыполнении ограничения индекса в языке не определен.

Примеры описания массивов, включающих ограничения индексов:

BOARD     : MATRIX(1 .. 8,  1 .. 8); -- СМ. 3.6
RECTANGLE : MATRIX(1 .. 20, 1 .. 30);
INVERSE   : MATRIX(1 .. N,  1 .. N); -- N не обязательно статическое

FILTER : BIT_VECTOR(0 .. 31);

Пример описания массива с ограниченным индексируемым подтипом:

MY_SCHEDULE : SCHEDULE; — все массивы типа SCHEDULE! имеют одни и те же границы Пример именуемого типа с компонентой индексируемого типа:

type VARLINE(LENGTH : INTEGER) is
   record
      IMAGE : STRING(1 .. LENGTH);
   end record;

NULL_LINE : VAR_LINE(0); -- NULL_LINE.IMAGE пустой массив

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

Все компоненты массива имеют один и тот же подтип. В частности, для массива компонент, которые являются одномерными массивами, это означает, что все компоненты имеют одни и те же границы и, следовательно, одинаковую длину.

Ссылки: вид 12.1.1, вход 9.5, выражение 4.4, генератор 4.8, граница диапазона 3.5, граница массива 3.6, диапазон 3.5, дискретный диапазон 3.6, имя 4.1, индекс 3.6, индексируемый тип 3.6, компонента записи 3.7, компонента массива 3.6, константа 3.2.1, начальное значение 3.2.1, неограниченный индексируемый тип 3.6, неограниченный подтип 3.3, обозначение типа 3.3.2, объект 3.2, ограничение индекса 3.6.1, ограниченный индексируемый подтип 3.6, описание компоненты 3.7, описание объекта 3.2.1, описание переименования 8.5, описание семейства входов 9.5, определение индексируемого типа 3.6, определение ограниченного индексируемого типа 3.6, определение ссылочного типа 3.8, параметр настройки 12.1, переменная 3.2, подпрограмма 6, подтип индекса 3.6, подтип ограниченного индексируемого типа 3.6, подтип результата 6.1, правило итерации 5.5, предопределенный тип С, преобразование 4.6, преобразование подтипа 4.6, пустой диапазон 3.5, совместимый 3.3.2, ссылочное значение 3.8, ссылочный тип 3.8, тип универсальный целый 3.5, удовлетворять 3.3, указание подтипа 3.3.2, указываемый тип 3.8, указывать 3.8, универсальный тип 4.10, фактический параметр 6.4.1, фактический параметр настройки 12.3, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3, функция 6.5, целый литерал 2.4, целый тип 3.5.4.

3.6.2. ОПЕРАЦИИ НАД ИНДЕКСИРУЕМЫМИ ТИПАМИ

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

Если А — объект, являющийся массивом, значением массива или подтипом ограниченного индексируемого типа, то базовые операции включают также атрибуты, которые перечислены ниже. Эти атрибуты недопустимы для неограниченного индексируемого типа. Аргумент N, использованный в обозначении атрибута для N-ro измерения массива, должен быть положительным статическим выражением типа универсальный-целый и не больше размерности массива.

A'FIRST | Вырабатывает нижнюю границу диапазона первого индекса. Значение этого атрибута имеет тот же тип, что и эта граница.
A'FIRSTfN) | Вырабатывает значение нижней границы диапазона N-ro индекса. Значение этого атрибута имеет тот же тип, что и эта нижняя граница.
A'LAST | Вырабатывает верхнюю границу диапазона первого индекса. Значение этого атрибута имеет тот же тип, что и эта верхняя граница.
A'LAS^N) | Вырабатывает верхнюю границу диапазона М-го индекса. Значение этого атрибута имеет тот же тип, что и эта верхняя граница.
A'RANGE | Вырабатывает диапазон первого индекса, т. е. диапазон A'FIRST.. A'LAST.
A'RANGE(N) | Вырабатывает диапазон N-ro индекса, т. е. диапазон A'FIRST(N) . . A'LAST(N).
A'LENGTH | Вырабатывает количество значений в диапазоне первого индекса (нуль для пустого диапазона). Значение этого атрибута имеет тип универсальный-целый.
A'LENGTH(N) | Вырабатывает количество значений в диапазоне N-ro индекса (нуль для пустого диапазона). Значение этого атрибута имеет тип универсальный-целый.

Кроме того, для индексируемого типа или подтипа Т определены атрибуты Т'ВАSЕ и T'SIZE (см. 3.3.3), а для массива А определены атрибуты A'SIZE и A'ADDRESS (см. 13.7.2).

Кроме базовых в состав операций над индексируемым типом входят предопределенные операции сравнения на равенство или неравенство, если индексируемый тип не является лимитируемым типом. Для одномерных массивов к этим операциям относится катенация, если индексируемый тип не является лимитируемым типом; если тип компоненты — дискретный тип, то операции включают также все предопределенные операции отношения; если тип компоненты — логический тип, то операции также включают унарную логическую операцию отрицания и логические операции.

Примеры (использующие массивы, описанные в примерах раздела 3.6.1):

-- FILTER'FIRST = 0         FILTER'LAST = 31         FILTER'LENGTH == 32
-- RECTANGLE'LAST(1) = 20   RECTANGLE'LAST(2) = 30

Примечание. Атрибуты A'FIRST и A'FIRST(1) вырабатывают одно и то же значение. То же можно сказать об атрибутах A'LAST, A'RANGE и A'LENGTH. Для приведенных атрибутов удовлетворяются следующие соотношения (исключая пустой массив) если тип индекса — целый тип:

A'LENGTH = A'LAST - A'FIRST + 1 A'LENGTH(N) = A'LAST(N) - A'FIRST(N) + 1

Индексируемый тип — лимитируемый, если тип его компонент — лимитируемый (см. 7.4.4).

Ссылки: агрегат 4.3, атрибут 4.1.4, базовая операция 3.3.3, граница диапазона 3.5, индекс 3.6, индексированная компонента 4.1.1, индексируемый тип 3.6, квалифицированное выражение 4.7, лимитируемый тип 7.4.4, логическая операция 4.5, 4.5,1, неограниченный индексируемый тип 3.6, обозначение 6.1, объект 3.2, ограниченный индексируемый тип 3.6, операция кате-нации 4.5, 4.5.2, операция отношения 4.5, 4.5.2, операция отрицания 4.5, 4.5.6, отрезок 4.1.2, подкомпонента 3.3, предопределенная операция 4.5, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, пустой диапазон 3.5, размерность 3.6, символьный тип 3.5.2, статическое выражение 4.9, строковый литерал 2.6, тип 3.3, универсальный тип 4.10, универсальный целый тип 3.5.4.

3.6.3. СТРОКОВЫЙ ТИП

Значения предопределенного типа STRING — это одномерные массивы компонент предопределенного типа CHARACTER, индексируемые значениями предопределенного подтипа POSITIVE:

subtype POSITIVE is INTEGER range 1 .. INTEGER'LAST;

type STRING is array (POSITIVE range 0) of CHARACTER;

Примеры:

STARS : STRING(1 .. 120) := (1 .. 120 => '*' );
QUESTION : constant STRING := "HOW MANY CHARACTERS?";
-- QUESTION'FIRST = 1, QUESTION'LAST = 20 (число СИМВОЛОВ)

ASK_TWICE : conatant STRING := QUESTION & QUESTION;
NINETY_SIX : constant ROMAN := "XCVI"; -- см. 3.6

Примечание. Строковые литералы (см. 2.6 и 4.2) — базовые операции над типом STRING и любым другим одномерным индексируемым типом, тип компонент которого — символьный тип. Операция катенации — предопределенная операция над типом STRING и для одномерных индексируемых типов; она представляется знаком &. Операции отношения <, < =, > и > = определены для значений этих типов в соответствии с лексикографическим порядком (см. 4.5.2).

Ссылки: агрегат 4.3, индекс 3.6, лексикографический порядок 4.5.2, массив 3.6, операция катенации 4.5, 4.5.3, операция отношения 4.5, 4.5.2, подтип 3.3, позиционный агрегат 4.3, предопределенная операция 4.5, предопределенный тип С, размерность 3.6, символьный тип 3.5.2, строковый литерал 2.6, тип 3.3, тип компоненты (массива) 3.6.

Пред. | Уровень выше | След.
3.5. СКАЛЯРНЫЕ ТИПЫ | Начало | 3.7. ИМЕНУЕМЫЕ ТИПЫ


3.7. ИМЕНУЕМЫЕ ТИПЫ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.7. ИМЕНУЕМЫЕ ТИПЫ

Объект именуемого типа (запись) — это составной объект, состоящий из именованных компонент. Значение записи — составное значение, состоящее из значений своих компонент.

определение-именуемого-типа::=
    record
      список-компонент
    end record

список_компонент::=
    описание_компоненты {описание_компоненты}
     |{ описание_компоненты} раздел_вариантов | null;

описание_компоненты ::=
    список_идентификаторов : определение_подтипа_компоненты [:= выражение];
определение_подтипа_компоненты ::= указание_подтипа

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

Описание компоненты с несколькими идентификаторами эквивалентно последовательности единичных описаний компонент, как пояснено в разд. 3.2. Каждое единичное описание компоненты объявляет компоненту записи, подтип которой задан определением подтипа компоненты.

Если описание компоненты включает составной ограничитель присваивания, за которым следует выражение, то это выражение является выражением по умолчанию компоненты записи; выражение по умолчанию должно иметь тип компоненты. Выражения по умолчанию недопустимы для компонент лимитируемого типа.

Если именуемый тип не имеет раздела дискриминантов, то одни и те же компоненты присутствуют во всех значениях этого типа. Если список компонент именуемого типа определен зарезервированным словом null и раздел дискриминантов отсутствует, то именуемый тип не имеет компонент и все записи этого типа — пустые записи.

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

Для предвыполнения определения подтипа компоненты в случае, когда ограничение не зависит от дискриминанта, предвыполняется указание подтипа. Если, с другой стороны, ограничение зависит от дискриминанта, то Предвыполнение состоит из вычисления каждого входящего в ограничение выражения, которое не является дискриминантом.

Примеры описаний именуемого типа:

type DATE is
   record
      DAY   : INTEGER range 1 ..31;
      MONTH : MONTHNAME;
      YEAR  : INTEGER range 0 .. 4000;
   end record;

type COMPLEX is
   record
      RE : REAL := 0.0;
      IM : REAL := 0.0;
   end rocord;

Примеры переменных именуемого типа:

TOMORROW, YESTERDAY : DATE;
А, В, С : COMPLEX;

-- компоненты А, В и С неявно инициализированы нулем

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

В отличие от компонент массива компоненты записи не обязательно имеют один и тот же тип.

Ссыпки: выражение 4.4, дискриминант 3.3, зависит от дискриминанта 3.7.1, идентификатор 2.3, имя 4.1, компонента 3.3, лимитируемый тип 7.4.4, обозначение типа 3.2.2, объект 3.2, ограничение 3.3, описание 3.1, подтип 3.3, Предвыполнение 3.9, раздел вариантов 3.7.3, раздел дискриминантов 3.7, 3.7.1, составное значение 3.3, составной ограничитель присваивания 2.2, список идентификаторов 3.2, тип 3.3.

3.7.1. ДИСКРИМИНАНТЫ

Раздел дискриминантов специфицирует дискриминанты типа. Дискриминант записи — это компонента записи. Тип дискриминанта должен быть дискретным.

раздел-дискриминантов:: =

(спецификация-дискриминанта {; спецификация-дискриминанта})

спецификация-дискриминанта ::=

список-идентификаторов : обозначение-типа [:= выражение]

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

Спецификация дискриминанта с несколькими идентификаторами эквивалентна последовательности единичных спецификаций дискриминантов, как пояснено в разд. 3.2. Каждая единичная спецификация дискриминанта описывает дискриминант. Если спецификация дискриминанта включает составной ограничитель присваивания, за которым следует выражение, то это — выражение по умолчанию для дискриминанта; выражения по умолчанию должны быть заданы либо для всех, либо не заданы ни для одного из дискриминантов раздела дискриминантов.

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

В определении именуемого типа допустимы только следующие случаи использования имени дискриминанта: в выражениях по умолчанию для компонент записи, в разделе вариантов в качестве имени дискриминанта, а также в определении подтипа компоненты — либо как границы в ограничении индекса, либо для задания значения дискриминанта в ограничении дискриминанта. Использованное в этих определениях подтипа компоненты имя дискриминанта должно встречаться само по себе, а не как часть выражения. Такие определения подтипа компонент и такие ограничения называются зависимыми от дискриминанта.

Компонента называется зависимой от дискриминанта, если она — либо компонента записи, описанная в разделе вариантов, либо компонента записи, чье определение подтипа компоненты зависит от дискриминанта, либо, наконец, одна из подкомпонент, зависящих от дискриминанта.

Каждое значение записи включает значение каждого дискриминанта, заданного для именуемого типа; оно также включает значение для каждой компоненты записи, которая не зависит от дискриминанта. Значения дискриминантов определяют, значения каких компонент, зависящих от дискриминантов, присутствуют в значении записи.

Непосредственное присваивание дискриминанту объекта недопустимо; более того, дискриминант недопустим как фактический параметр вида in out или out либо как фактический параметр настройки вида in out. Единственным путем изменения значения дискриминанта переменной является присваивание (полного) значения самой переменной. Аналогично присваивание самой переменной является единственным путем изменения одной из ее компонент, если определение подтипа компоненты зависит от дискриминанта переменной.

Предвыполнение раздела дискриминантов не имеет другого эффекта.

Примеры:

type
 BUFFER(SIZE : BUFFER_SIZE := 100) is -- см. 3.5.4
    record
      POS : BUFFER_SIZE := 0;
      VALUE : STRING(1 .. SIZE);
    end record;

type SQUARE(SIDE : INTEGER) is
   record
      MAT : MATRIX(1 .. SIDE, 1 .. SIDE); --CM. 3.6
   end record:

type DOUBLESQUARE(NUMBER : INTEGER) is
   record
      LEFT : SQUARE (NUMBER);
      RIGHT : SQUARE (NUMBER);
   end record;

type ITEM(NUMBER : POSITIVE) is
   record
      CONTENT : INTEGER;
      --  компонента не зависит от дискриминанта
   end record;

Ссылки: выражение 4.4, границы диапазона 3.5, дискретный тип 3.5, дискриминант 3.3, идентификатор 2.3, именуемый тип 3.7, имя 4.1, компонента 3.3, компонента записи 3.7, личный тип 7.4, настраиваемый формальный тип 12.1, неполное описание типа 3.8.1, область действия 8.2, обозначение типа 3.3.2, объект 3.2, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, описание 3.1, описание компоненты 3.7, описание личного типа 7.4, описание параметра настройки 12.1, описание типа 3.3.1, подкомпонента 3.3, Предвыполнение 3.9, присваивание 5.2, простое имя 4.1, раздел вариантов 3.7.3, составной ограничитель присваивания 2.2, список идентификаторов 3.2, указание подтипа 3.3.2.

3.7.2. ОГРАНИЧЕНИЯ ДИСКРИМИНАНТОВ

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

ограничение-дискриминанта ::=
    (сопоставление-дискриминанта {, сопоставление-дискриминанта})

сопоставление-дискриминанта ::=
    [простое-имя-дискриминанта {|простое-имя-дискриминанта} =>] выражение

Каждое сопоставление дискриминанта связывает выражение с одним или несколькими дискриминантами. Сопоставление дискриминанта называется именованным, если дискриминанты заданы явно своими именами; иначе оно называется позиционным. Для позиционного сопоставления (единственный) дискриминант неявно задан позицией в текстуальном порядке. Именованные сопоставления могут быть даны в любом порядке, но если в одном и том же ограничении дискриминанта использованы позиционные и именованные сопоставления, то позиционные сопоставления должны стоять первыми, в их обычной позиции. Следовательно, если однажды было использовано именованное сопоставление, то в остальной части ограничения дискриминанта должны употребляться только именованные сопоставления.

Для именованного сопоставления дискриминанта имена дискриминантов должны обозначать дискриминанты того типа, для которого дано ограничение дискриминанта. Сопоставление дискриминанта с более чем одним именем дискриминанта допустимо, только если все дискриминанты имеют один и тот же тип. Более того, для каждого сопоставления дискриминанта (именованного или позиционного) выражение и связанные дискриминанты должны иметь один и тот же тип. Ограничение дискриминанта должно задавать точно одно значение для каждого дискриминанта типа.

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

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

Начальные значения дискриминантов объекта, имеющего тип с дискриминантами, определены следующим образом:

• Для объявленной описанием объекта переменной указание подтипа должно быть ограничено ограничением дискриминанта, если выражения по умолчанию для дискриминантов отсутствуют; значения дискриминантов определены либо ограничением, либо при отсутствии его выражением по умолчанию. То же самое требование существует для указания подтипа в описании компоненты, если тип компоненты записи имеет дискриминанты, а также для указания подтипа компоненты индексируемого типа, если тип компоненты массива — тип с дискриминантами.

• Для объявленной описанием объекта константы значения дискриминантов берутся из начального значения, если подтип константы не ограничен; иначе они определяются из этого подтипа (в последнем случае возбуждается исключение, если начальное значение не принадлежит этому подтипу). То же правило применяется к параметру настройки вида in.

• Для указанного ссылочным значением объекта значения дискриминантов должны быть определены генератором, создающим объект. (Созданный объект ограничен соответствующими значениями дискриминантов.)

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

• Для описания переименования и для формального параметра настройки вида in out дискриминанты — это дискриминанты переименованного объекта или соответствующего фактического параметра настройки.

Порядок вычислений выражений, данных в сопоставлениях дискриминантов, при предвы-полнении ограничения дискриминанта в языке не определен; выражение именованного сопоставления вычисляется по одному разу для каждого именованного дискриминанта.

Примеры {использующие типы, описанные в предыдущем разделе}:

LARGE : ВUFFЕР(200); -- всегда ограничен, 200 символов
                     -- это явное значение дискриминанта MESSAQE: BUFFER;
                     -- не ограничен, вначале 100 символов
                     -- это значение дискриминанта по
                     -- умолчанию

BASIS : 8QUАRЕ(5);   -- ограничен, всегда 5 на 5
ILLEGAL : SQUARE;    -- неправильно, SQUARE
                     -- должен быть ограничен

Примечание. Приведенные правила и правила, определяющие предвыполнение описания объекта (см. 3.2), гарантируют, что дискриминанты всегда имеют значения. В частности, если ограничение дискриминанта входит в описание объекта, то каждый дискриминант инициализирован значением, определяемым ограничением. Аналогично если подтип компоненты имеет ограничение дискриминанта, то дискриминанты этой компоненты соответственно инициализированы.

Ссылки: Вид 6.1, вид In out 6.1, вход 9.5, выражение 4.4, выражение по умолчанию для дискриминанта 3.7, вычисление 4.5, генератор 4.8, граница диапазона 3.5, дискриминант 3.3, зависит от дискриминанта 3.7.1, зарезервированное слово 2.9, имя 4.1, компонента 3.3, константа 3.2.1, обозначение типа 3.3.2, указываемый тип 3.8, объект 3.2, ограничение 3.3, ограниченный подтип 3.3, описание 3.1, описание компоненты 3.7, описание объекта 3.2.1, описание переименования 8.5, определение индексируемого типа 3.6, определение ссылочного типа 3.8, переменная 3.2.1, подкомпонента 3.3, подпрограмма 6, подтип 3.3, предвыполнение 3.9, простое имя 4.1, совместимый 3.3.2, составное значение 3.3, ссылочное значение 3.8, ссылочный тип 3.8, тип 3.3, удовлетворять 3.3, указание подтипа 3.3.2, указание подтипа компоненты 3.7, указываемый тип 3.8, указывать 3.8, фактический параметр 6.4.1, фактический параметр настройки 12.3, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3.

3.7.3. РАЗДЕЛЫ ВАРИАНТОВ

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

раздел-вариантов ::=
   case простое-имя-дискриминанта is
      вариант
      {вариант}
   end case;

вариант ::=
    when выбор {|выбор} =>
        список_компонент

выбор ::= простое-выражение
    |дискретный-диапазон | others  | простое-имя-компоненты

Каждый вариант начинается со списка выборов, которые должны быть того же типа, что и дискриминант раздела вариантов. Тип дискриминанта раздела вариантов не должен быть настраиваемым формальным типом настройки. Если подтип дискриминанта статический, то каждое значение этого подтипа должно быть представлено в наборе выборов раздела вариантов один и только один раз и другие значения недопустимы. Другими словами, каждое значение (базового) типа дискриминанта должно быть представлено один и только один раз в наборе вариантов.

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

Значение записи содержит значения компонент данного варианта тогда и только тогда, когда значение дискриминанта равно одному из значений, заданных выборами варианта. Это правило применимо в свою очередь к любому вложенному варианту, который сам включен в список компонент данного варианта. Если список компонент варианта задан как null, то вариант не имеет компонент.

Примеры именуемого типа с разделом вариантов:

type DEVICE is (PRINTER, DISK, DRUM);
type STATE is (OPEN, CLOSED);

type PERIPHERAL(UNIT : DEVICE := DISK) is
   record
   STATUS : STATE;
   case UNIT is
      whenPRINTER =>
          LINECOUNT : INTEGER range1 .. PAGESIZE;
      when others =>
          CYLINDER : CYLINDERINDEX;
          TRACK : TRACKNUMBER;
      end case;
   end record:

Примеры подтипов записей:

subtype DRUMUNIT is PERIPHERAL(DRUM);
subtype DISKUNIT is PERIPHERAL(DISK);

Примеры ограниченных переменных именуемого типа:

WRITER : PERIPHERAL(UNIT => PRINTER); ARCHIVE : DISK_UNIT;

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

Ссылки: агрегат записи 4.3.1, агрегат массива 4.3.2, базовый тип 3.3, выражение 4.4, дискретный диапазон 3.6, диапазон 3.5, дискриминант 3.3, именуемый тип 3.7, компонента 3.3, настраиваемый формальный тип 12.1.2, подтип 3.3, простое выражение 4.4, простое имя 4.1, пустой диапазон 3.5, список компонент 3.7, статическое выражение 4.9, статический дискретный диапазон 4.9, статический подтип 4.9.

3.7.4. ОПЕРАЦИИ НАД ИМЕНУЕМЫМИ ТИПАМИ

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

Для любого объекта А типа с дискриминантами базовые операции включают также следующий атрибут:

A'CONSTRAINED | Вырабатывает значение TRUE, если ограничение дискриминанта наложено на объект А или если объект — константа (включая формальный параметр или формальный параметр настройки вида in); вырабатывает значение FALSE в противном случае. Если А — формальный параметр настройки вида in oirt или если А — формальный параметр вида in out или out и данное в соответствующей спецификации параметра обозначение типа обозначает неограниченный тип с дискриминантами, то значение этого атрибута получается из значения атрибута соответствующего фактического параметра. Значение этого атрибута имеет предопределенный тип BOOLEAN.

Кроме того, атрибуты T'BASE и T'SIZE опеределены для именуемого типа или подтипа Т (см. 3.3.3); атрибуты A'SIZE и A'ADDRESS определены для записи А (см. 13.7.2).

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

Примечание. Именуемый тип ~ лимитируемый, если тип хотя бы одной из его компонент — лимитируемый (см. 7.4.4).

Ссылки: агрегат 4.3, атрибут 4.1.4, базовая операция 3.3.3, вид 6.1, дискриминант 3.3, именуемая компонента 4.1.3, именуемый тип 3.7, квалифицированное выражение 4.7, константа 3.2.1, лимитируемый тип 7.4.4, логический тип 3.5.3, объект 3.2.1, ограничение дискриминанта 3.7.2, операция 3.3, операция отношения 4.5, 4,5.2, подкомпоненТа 3.3, подтип 3.3, предопределенная операция 4.5, предопределенный тип С, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, производный тип 3.4, тип 3.3, фактический параметр 6.4.1, фактический параметр настройки 12.3, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3

Пред. | Уровень выше | След.
3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ | Начало | 3.8. ССЫЛОЧНЫЕ ТИПЫ


3.8. ССЫЛОЧНЫЕ ТИПЫ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.8. ССЫЛОЧНЫЕ ТИПЫ

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

определение-ссылочного-типа ::= access указание-подтипа

Для каждого ссылочного типа существует литерал null, имеющий пустое ссылочное значение, вообще не указывающее объект. Пустое значение ссылочного типа — начальное значение этого типа по умолчанию. Другие значения ссылочного типа получаются вычислением специальной операции над типом, называемой генератором. Каждое такое ссылочное значение указывает объект подтипа, обозначенного указанием подтипа определения ссылочного типа; этот подтип называется указываемым подтипом; базовый тип этого подтипа называется указываемым типом. Указанные значением ссылочного типа объекты образуют набор, неявно связанный с типом.

Предвыполнение определения ссылочного типа состоит из предвыполнения указания подтипа и создания ссылочного типа.

Если ссылочный объект — константа, то ссылочное значение не может быть изменено и всегда указывает один и тот же объект. С другой стороны, значение указываемого объекта не обязательно остается одним и тем же (присваивание указываемому объекту допустимо, если указываемый тип нелимитируемый).

Единственные формы ограничения, которые допустимы после имени ссылочного типа в указании подтипа, — это ограничения индексов и ограничения дискриминантов (см. разд. 3.6.1 и 3.7.2 для правил, применимых к этим указаниям подтипа). Ссылочное значение принадлежит соответствующему подтипу ссылочного типа, если либо ссылочное значение — пустое значение, либо если значение указываемого объекта удовлетворяет ограничению.

Примеры:

type FRAME is access MATRIX; -- см. 3.6
type BUFFERNAME is access BUFFER; -- см. 3.7.1

Примечание. Ссылочное значение, передаваемое генератором, может быть присвоено нескольким ссылочным объектам. Следовательно, объект, созданный генератором, может быть указан более чем одной переменной или константой ссылочного типа. Ссылочное значение может указывать только объект, созданный генератором, в частности, оно не может указывать объект, объявленный описанием объекта.

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

Ссылочные значения в некоторых других языках называются указателями или ссылками.

Ссылки: генератор 4.8, зарезервированное слово 2.9, имя 4.1, индексируемый тип 3.6, константа 3.2.1, лимитируемый тип 7.4.4, литерал 4.2, объект 3.2.1, ограничение 3.3, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, описание объекта 3.2.1, переменная 3.2.1, подкомпонента 3.3, подтип 3.3, Предвыполнение 3.9, принадлежит подтипу 3.3, присваивание 5.2, простое имя 4.1, спецификация индекса 3.6, тип 3.3, удовлетворять 3.3, указание подтипа 3.3.2.

3.8.1. НЕПОЛНЫЕ ОПИСАНИЯ ТИПОВ

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

неполное-описание-типа ::= type идентификатор [раздел-дискриминантов];

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

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

Предвыполнение неполного описания типа создает тип. Если неполное описание типа имеет раздел дискриминантов, то это Предвыполнение включает Предвыполнение раздела дискриминантов: в этом случае раздел дискриминантов полного описания типа не предвыпол-няется.

11 явно или неявно, прямо или косвенно. — Прим. ред.

Пример рекурсивного типа:

type CELL; — неполное описание типа
type LINK is access CELL;

type CELL is
   record
      VALUE : INTEGER;
      SUCC : LINK;
      PRED : LINK;
  end record;

HEAD : LINK := new CELL'(O, null, null);
NEXT : LINK := HEAD.SUCC;

Примеры взаимозависимых ссылочных типов:

type PERSON(SEX : GENOER); — неполное описание типа
type CAR; — неполное описание типа

type PERSONNAME is access PERSON;
type CARNAME is access CAR;

type CAR is
   record
      NUMBER : INTEGER;
      OWNER : PERSONNAME;
   end record;

type PERSON(SEX : GENDER) is
   record
      NAME : STRING(1 .. 20);
      BIRTH :  DATE; AGE : INTEGER range 0 .. 130;
      VEHICLE : CAR_NAME;
      casa SEX  is
         when M => WIFE : PERSON_NAME(SEX => F);
         when F => HUSBAND ; PERSON_NAME(SEX => M);
     end case:
end record;

MYCAR, YOURCAR, NEXTCAR : CARNAME; — неявно инициированы — пустым значением

Ссылки: идентификатор 2.3, имя 4.1, компонента 3.3, обозначение типа 3.3.2, ограничение 3.3, ограничение дискриминанта 3.7.2, описание 3.1, определение ссылочного типа 3.8, предвы-полнение 3.9, раздел дискриминантов 3.7.1, согласован 6.3.1, ссылочный тип 3.8, тип 3.3, указание подтипа 3.3.2, указывать 3.8, элемент описания 3.9.

3.8.2. ОПЕРАЦИИ НАД ССЫЛОЧНЫМИ ТИПАМИ

Базовые операции над ссылочным типом включают присваивание, генераторы для этого ссылочного типа, проверку принадлежности, явное преобразование, квалификацию и литерал null. Если указываемый тип — тип с дискриминантами, то базовые операции включают именование соответствующих дискриминантов; если указываемый тип — именуемый тип, то они включают именование соответствующих компонент; если указываемый тип — индексируемый тип, то они включают образование индексируемых компонент и отрезков; если указываемый тип — задачный тип, то они включают именование входов и семейств входов. Кроме того, базовые операции включают образование именуемой компоненты с зарезервированным словом аll (см. 4.1.3).

Если указываемый тип — индексируемый тип, то базовые операции включают атрибуты с обозначениями FIRST, LAST, RANGE и LENGTH (и эти же атрибуты с параметром N для номера измерения). Префикс каждого из этих атрибутов должен быть значением ссылочного типа. Эти атрибуты вырабатывают соответствующие характеристики указываемого объекта (см. 3.6.2).

Если указываемый тип — задачный тип, то базовые операции включают атрибуты с обозначениями TERMINATED и CALLABLE (см. 9.9). Префикс каждого из этих атрибутов должен быть значением ссылочного типа. Эти атрибуты вырабатывают соответствующие характеристики задачных объектов.

Кроме того, атрибут T'BASE (см. 3.3.3) и атрибуты представления T'SIZE и T'STORAGE-SIZE (см. 13.7.2) определены для ссылочного типа или подтипа Т; атрибуты A'SIZE и A'ADDRESS определены для ссылочного объекта А (см. 13.7.2).

Кроме базовых операции над ссылочным типом включают предопределенное сравнение на равенство и неравенство.

Ссылки: атрибут 4.1.4, базовая операция 3.3.3, базовый тип 3.3, генератор 4.8, дискриминант 3.3, задачный тип 9.1, именуемая компонента 4.1.3, именуемый тип 3.7, индексируемая компонента 4.1.1, индексируемый тип 3.6, квалифицированное выражение 4.7, литерал 4.2, личный тип 7.4, набор 3.8, обозначение атрибута 4.1.4, объект 3.2.1, ограниченный индексируемый подтип 3.6, операция 3.3, отрезок 4.1.2, подтип 3.3, преобразование 4.6, присваивание 5.2, проверка принадлежности 4.5, 4.5.2, ссылочный тип 3.8, тип 3.3, указываемый подтип 3.8, указываемый тип 3.8, указывать 3.8.

Пред. | Уровень выше | След.
3.7. ИМЕНУЕМЫЕ ТИПЫ | Начало | 3.9. РАЗДЕЛЫ ОПИСАНИЙ


3.9. РАЗДЕЛЫ ОПИСАНИЙ
Пред. Глава 3. ОПИСАНИЯ И ТИПЫ След.

3.9. РАЗДЕЛЫ ОПИСАНИЙ

Раздел описаний содержит элементы описания (возможно, и ни одного).

раздел-описаний ::= {основной-элемент-описания}
    {дополнительный - элемент - описания}

основной-элемент-описания ::= основное-описание
    | спецификатор-представления | спецификатор-использования

дополнительный-элемент-описания ::= тело
    | описание-подпрограммы         | описание-пакета
    | описание-задачи               | описание-настройки
    | спецификатор-использования    | конкретизация-настройки

тело ::= соответствующее-тело | след-тела

соответствующее-тело ::= тело-подпрограммы | тело-пакета | тело-задачи

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

Для нескольких форм элементов описания правила языка (в частности, правило определения области действия и правила видимости) таковы, что использование понятия до предвыполнения элемента описания, который объявляет это понятие, либо невозможно, либо является неправильным. Например, невозможно использование имени типа для описания объекта, если соответствующее описание типа еще не предвыполнено. В случае тел осуществляются следующие проверки:

• При вызове подпрограммы проверяется, предвыполнено ли уже тело подпрограммы.

• При активизации задачи проверяется, предвыполнено ли уже тело соответствующего за-дачного модуля.

• При конкретизации настраиваемого модуля, имеющего тело, проверяется, предвыполнено ли уже тело настраиваемого модуля.

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

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

Ссылки: активизация 9.3, видимость 8.3, вызов подпрограммы 6.4, исключение PROGRAM_ERROR 11.1, конкретизация 12.3, область действия 8.2, тип 3.3.

Предвыполнение описаний: 3.1, конкретизация настройки 12.3, неполное описание типа 3.8.1, описание входа 9.5, описание задачи 9.1, описание компоненты 3.7, описание личного типа 7.4.1, описание настройки 12.1, описание объекта 3.2.1, описание пакета 7.2, описание переименования 8.5, описание подпрограммы 6.1, описание подтипа 3.3.2, описание субкон-станты 7.4.3, описание типа 3.3.1, описание числа 3.2.2, спецификация дискриминанта 3.7.1, спецификация литерала перечисления 3.5.1, спецификация параметра 6.1, спецификация параметра цикла 5.5.

Предвыполнение определений типа: 3.3.1, определение вещественного типа 3.5.6, определение именуемого типа 3.7, определение индексируемого типа 3.6, определение перечислимого типа 3.5.1, определение производного типа 3.4, определение ссылочного типа 3.8, определение целого типа 3.5.4.

Предвыполнение других конструкций: библиотечный модуль 10.5, задача 9.2, компилируемый модуль 10.1, настраиваемое тело 12.2, раздел дискриминантов 3.7.1, след тела 10.2, спецификатор использования 8.4, спецификатор контекста 10.1, спецификатор представления 13.1, спецификатор совместности 10.1.1, спецификация задачи 9.1, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, формальный параметр настройки 12.1, 12.3.

Пред. | Уровень выше | След.
3.8. ССЫЛОЧНЫЕ ТИПЫ | Начало | Глава 4. ИМЕНА И ВЫРАЖЕНИЯ


Глава 4. ИМЕНА И ВЫРАЖЕНИЯ
Пред. След.

Глава 4. ИМЕНА И ВЫРАЖЕНИЯ

Содержание

4.1. ИМЕНА
4.2. ЛИТЕРАЛЫ
4.3. АГРЕГАТЫ
4.4. ВЫРАЖЕНИЯ
4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ
4.6. ПРЕОБРАЗОВАНИЕ ТИПА
4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ
4.8. ГЕНЕРАТОРЫ
4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ
4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ

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

4.1. ИМЕНА

Имена могут обозначать понятия, описанные явно или неявно (см. 3.1). Имена могут обозначать также объекты, указанные ссылочными значениями, подкомпоненты и отрезки объектов и значений, одиночные входы, семейства входов и входы семейства входов. Наконец, имена могут обозначать атрибуты этих понятий и объектов.

имя ::= простое-имя
     | символьный-литерал       | знак-операции
     | индексируемая-компонента | отрезок
     | именуемая-компонента     | атрибут
простое-имя ::= идентификатор
префикс ::= имя | вызов-функции

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

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

Если префикс имени — вызов функции, то имя обозначает компоненту, отрезок, вход или семейство входов результата вызова функции либо (если результат — ссылочное значение) объект, указанный результатом.

Говорят, что префикс соответствует некоторому типу в одном из следующих случаев:

• Тип префикса — это рассматриваемый тип.

• Тип префикса — ссылочный тип, который указывает на рассматриваемый тип. Вычисление имени определяет понятие, обозначенное этим именем. Для простого имени, символьного литерала или знака операции вычисление имени не имеет другого результата.

Вычисление имени, имеющего префикс, включает в себя вычисление префикса, т. е. соответствующего имени или вызова функции. Если тип префикса — ссылочный тип, то вычисление префикса включает в себя определение объекта, указанного соответствующим ссылочным значением; если значение префикса является пустым ссылочным значением, исключая случай префикса атрибута представления (см. 13.7.2), то возбуждается исключение CONSTRAINED-ERROR (см. 13.7.2).

Примеры простых имен:

Pl | - - простое имя числа | (см. 3.2.1)
LIMIT | - - простое имя константы | (см. 3.2.1)
COUNT | - - простое имя скалярной переменной | (см. 3.2.1)
BOARD | - - простое имя массива | (см. 3.6.1)
MATRIX | - - простое имя типа | (см. 3.6)
RANDOM | - - простое имя функции | (см. 6.1)
ERROR | - - простое имя исключения | (см. 11.1)

Ссыпки: атрибут 4.1.4, вид 6.1, возбуждение исключения 11, .вход 9.5, вызов функции o.t, вычисление 4.5, знак операции 6.1, идентификатор 2.3, именуемая компонента 4.1.3, индексируемая компонента 4.1.1, исключение CONSTRAINT-ERROR 11.1, компонента 3.3, объект 3.2.1, описание 3.1, описание переименования 8.5, отрезок 4.1.2, подкомпонента 3.3, понятие 3.1, принадлежит типу 3.3, ссылочное значение null 3.8, семейство входов 9.5, символьный литерал 2.5, ссылочное значение 3.8, ссылочный тип 3.8, тип 3.3, формальный параметр 6.1, указанный тип 3.8, указывать 3.8.

4.1.1. ИНДЕКСИРУЕМЫЕ КОМПОНЕНТЫ

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

индексируемая-компонента ::= префикс(выражение (, выражение))

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

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

Примеры индексируемых компонент:

MY-SCHEDULEtSAT) | - - компонента одномерного массива | (см. 3.6.1)
РАПЕ(10) | - - компонента одномерного массива | (см. 3.6)
BOARD(M, J + 1) | - - компонента двумерного массива | (см. 3.6.1)
PAGE(10) (20) | - - компонента компоненты | (см. 3.6)
REQUESTfMEDIUM) | -- вход семейства входов | (см. 9.5)
NEXT_FRAME(L) (M, N) | - - компонента вызова функции | (CM. 6.1)

Примечание к примеру. Для компонент многомерных массивов (таких, как BOARD) и массива массивов (таких, как PAGE) используются различные обозначения. Компонентами массива массивов являются массивы, и они могут быть индексированы. Так, РАGЕ(10) (20) задает двадцатую компоненту массива РАGЕ(10). В последнем примере NEXT_FRAME(L) — вызов функции, возвращающей ссылочное значение, указывающее двумерный массив.

Ссылки: возбуждение исключения 11, возвращаемое значение 5.8, 6.5, вход 9.5, вызов функции 6.4, выражение 4.4, вычисление 4.5, имя 4.1, индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, компонента 3.3, компонента массива 3.6, объект задачного типа 9.2, префикс 4.1, размерность 3.6, семейство входов 9.5, соответствует типу 4.1.

4.1.2. ОТРЕЗКИ

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

отрезок ::= префикс(дискретный-диапазон)

Префикс отрезка должен соответствовать одномерному индексируемому типу. Тип отрезка — это базовый тип этого индексируемого типа. Границы дискретного диапазона определяют границы отрезка и должны быть того же типа, что и тип индекса; отрезок является пустым, т. е. обозначает пустой массив, если дискретный диапазон является пустым.

Порядок вычисления префикса и дискретного диапазона при вычислении имени отрезка в языке не определяется. Если при вычислении отрезка хотя бы одна из границ дискретного диапазона не принадлежит диапазону индексов, определяемому префиксом отрезка, то (кроме случая пустого отрезка) возбуждается исключение CONSTRAINT_ERROR. (Границы пустого отрезка могут не принадлежать подтипу индекса.)

Примеры отрезков:

SТАRS(1..15) | - - отрезок из 15 символов | (см. 3.6.3)
РАGЕ(10..10 + SIZE) | - - отрезок из (1 + SIZE) компонент | (см. 3.6 и 3.2.1)
РАGЕ(L) (А..В) | - - отрезок массива РАОЕ(1) | (см. 3.6)
SТАRS(1..0) | - - пустой отрезок | (см. 3.6.3)
MY_SCHEDULE(WEEKDAY) | - - границы задаются подтипом | (см. 3.6 и 3.5.1)
SТАRS(5..15) (К) | - - аналогично SТАRS(К), если К |
 | - - в диапазоне 5..15 | (см. 3.6)

Примечание. Для одномерного массива А имя A(N..N) задает отрезок, состоящий из одной компоненты; его тип соответствует базовому типу массива А. С другой стороны, A(N) — компонента массива и имеет соответствующий тип.

Ссылки: базовый тип 3.3, возбуждение исключения 11, вычисление 4.5, граница дискретного диапазона 3.6.1, диапазон индекса 3.6, дискретный диапазон 3.6, значение массива 3.8, имя 4.1, индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, компонента 3.3, константа 3.2.1, массив 3.5, ограничение 3.3, переменная 3.2.1, префикс 4.1, принадлежит подтипу 3.3, пустой диапазон 3.5, пустой массив 3.6.1, размерность 3.6, соответствует типу 4.1, тип 3.3, тип компоненты 3.3.

4.1.3. ИМЕНУЕМЫЕ КОМПОНЕНТЫ

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

именуемая-компонента ::= префикс.постфикс
постфикс ::= простое-имя | символьный-литерал
         | знак-операции | all

Для обозначения дискриминанта, компоненты записи, входа или объекта, указанного ссылочным значением, используются следующие четыре формы именуемых компонент:

а. Дискриминант.

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

б. Компонента записи.

Постфикс должен быть простым именем, обозначающим компоненту именуемого объекта или значения. Префикс должен соответствовать типу этого объекта или значения. Для компонент варианта делается проверка: являются ли значения дискриминантов такими, что запись имеет эту компоненту. В противном случае возбуждается исключение CONSTRAINT_ERROR.

в. Одиночный вход или семейство входов задачи.

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

г. Объект, указанный ссылочным значением.

Постфикс должен быть зарезервированным словом аll. Значение префикса должно принадлежать ссылочному типу.

Именуемая компонента одной из двух нижеуказанных форм называется расширенным именем. В каждом случае постфикс должен быть либо простым именем, либо символьным литералом, либо знаком операции. Вызов функции в качестве префикса расширенного имени не допускается. Расширенное имя может обозначать:

д. Понятие, описанное в видимом разделе описания пакета.

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

е. Понятие, описание которого находится непосредственно в поименованной конструкции.

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

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

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

Вычисление имени, являющегося именуемой компонентой, включает вычисление префикса.

Примеры именованных компонент:

TOMORROW.MONTH       -- компонента записи (см. 3.7)
NEXT_CAR.OWNER       -- компонента записи (см. 3.8.1)
NEXT_CAR.OWNER.AGE   -- компонента записи (см. 3.8.1)
WRITER.UNIT          -- компонента записи (дискриминант) (см. 3.7.3)
MIN_CELL(H).VALUE    -- компонента записи результата
                     -- вызова функции (см. 6.1 и 3.8.1)
CONTROL.SEISE        -- вход задачи CONTROL (см. 9.1 и 9.2)
РOOL(К).WRIТЕ        -- вход задачи РООЦК) (см. 9.1 и 9.2)
NEXT_CAR.all         -- объект, указанный ссылочной пере-
                     -- менной NEXT-CAR (см. 3.8.1)

Примеры расширенных имен:

TABLE_MANAGER.INSERT -- процедура видимого раздела пакета (см. 7.5)
КЕY_МАNАGЕR."<"      -- операция видимого раздела пакета (см. 7.4.2)
DOT_PRODUCT.SUM      -- переменная, описанная в теле процедуры (см. 6.5)
BUFFER.POOL          -- переменная, описанная в задачном модуле (см. 9.12)
BUFFER.READ          -- вход задачного модуля (см. 9.12)
SWAP.TEMP            -- переменная оператора блока (см. 5.6)
STANDARD.BOOLEAN     -- имя предопределенного типа (см. 8.6 и приложение С)

Примечание. Для записей, компонентами которых являются другие записи, перечисленные правила означают, что простое имя должно быть дано для каждого уровня имени подкомпоненты. Например, имя NEXT_CAR.OWNER.BIRTH.MONTH не может быть укорочено (имя NEXT_CAR.OWNER.MONTH недопустимо).

Ссылки: вариант 3.7.3, видимость 8.3, видимый раздел 3.7.3, возбуждение исключений 11, вход 9.5, вызов функции 6.4, дискриминант 3.3, задача 9, задачный модуль 9, запись 3.7, зарезервированное слово 2.9, знак операции 6.1, именуемая компонента 3.7, индекс 3.6, исключениеCONSTRAINT_ERROR 11.1, компонента записи 3.7, непосредственно входит в 8.1, объект 3.2.1, объект задачного типа 9.2, оператор блока 5.6, оператор принятия 9.5, оператор цикла 5.5, операция 4.5, описание 3.1, описание переименования 8.5, пакет 7, переменная 3.7.3, подпрограмма 6, понятие 3.1, предопределенный тип С, префикс 4.1, программный модуль 6, простое имя 4.1, семейство входов 9.5, символьный литерал 2.5, совмещение 8.3, соответствует типу 4.1, субмодуль 10.2, ссылочное значение 3.8, ссылочный тип 3.8, тело программного модуля 3.9, тело процедуры 6.3, указывать 3.8.

4.1.4. АТРИБУТЫ

Атрибут обозначает базовую операцию над понятием, задаваемым префиксом.

атрибут ::= префикс'обозначение-атрибута
обозначение-атрибута :: =
          простое-имя [(универсальное_статическое_выражение)]

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

Определенные в языке атрибуты приведены в приложении А. Конкретная реализация может ввести дополнительные атрибуты, описание которых должно быть дано в приложении F. Обозначения таких атрибутов должны отличаться от обозначений атрибутов, определенных в языке.

Вычисление имени, являющегося атрибутом, состоит из вычисления префикса.

Примечание. Обозначения атрибутов DIGITS, DELTA и RANGE им&ют идентификаторы, совпадающие с зарезервированными словами. Однако неоднозначность устранится, если перед обозначением атрибута будет стоять апостроф. Единственными предопределенными обозначениями атрибутов, содержащими универсальное выражение, являются те, которые соответствуют некоторым определенным операциям типа над индексируемыми типами (см. 3.6.2).

Примеры атрибутов:

COLOR'FIRST         -- минимальное значение перечислимого типа
                    -- COLOR                                    (см. 3.3.1 и 3.5)
RAINBOW'BASE'FIRST  -- то же, что и атрибут COLOR'FIRST         (см. 3.3.2 и 3.3.3)
REAL'DIGITS         -- точность типа REAL                       (см. 3.5.7 и 3.5.8)
BOARD'LAST(2)       -- верхняя граница диапазона 2-го индекса
                    -- для BOARD                                (см. 3.6.1 и 3.6.2)
BOARD'RANGE(1)      -- диапазон первого индекса для BOARD       (см. 3.6.1 и 3.6.2)
POOL(K).TERMINATED  -- TRUE, если задача РООL(К) завершена      (см. 9.2 и 9.9)
DATA'SIZE           -- количество битов под записи типа DATA    (см. 3.7 и 13.7.2)
MESSAGE'ADDRESS     -- адрес переменной MESSAGE именуемого типа (см. 3.7.2 и 13.7.2)

Ссылки: базовая операция 3.3.3, зарезервированное слово 2.9, имя 4.1, описанное понятие 3.1, префикс 4.1, простое имя 4.1, соответствует типу 4.1, статическое выражение 4.9, тип 3.3, универсальное выражение 4.10.

Пред. | Уровень выше | След.
3.9. РАЗДЕЛЫ ОПИСАНИЙ | Начало | 4.2. ЛИТЕРАЛЫ


4.2. ЛИТЕРАЛЫ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.2. ЛИТЕРАЛЫ

Литерал — это либо числовой литерал, либо литерал перечисления, либо литерал null, либо строковый литерал, либо символьный литерал. Вычисление литерала вырабатывает соответствующее значение.

Числовые литералы — это литералы типов универсальный-целый и универсальный-вещественный. Литералы перечисления включают символьные литералы и вырабатывают значения соответствующих перечислимых типов. Литерал null вырабатывает пустое ссылочное значение, которое не указывает ни на какой объект вообще.

Строковый литерал — это базовая операция, которая преобразует последовательность символов в значение одномерного массива символьного типа; границы этого массива определяются в соответствии с правилами для позиционных агрегатов массива (см. 4.3.2). Для пустого строкового литерала верхняя граница массива совпадает с нижней границей предшествен-ника задаваемого атрибутом PRED. Вычисление пустого строкового литерала возбуждает исключение CONSTRAINT_ERROR, если нижняя граница не имеет предшественника (см. 3.5.5).

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

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

Примеры:

3.14159_26536 | - - литерал вещественного типа
1_345 | - - литерал целого типа
КЛУБЫ | - - литерал перечисления
'А' | - - символьный литерал
"НЕКОТОРЫЙ_ТЕКСТ" | - - строковый литерал

Ссылки: агрегат 4.3, видимость 8.3, граница массива 3.6, графический символ 2.1, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, литерал вещественного типа 2.4, литерал перечисления 3.5.1, литерал целого типа 2.4, массив 3.6, объект 3.2.1, ссылочное значение null 3.8, пустой литерал 3.8, размерность 3.6, символьный литерал 2.5, символьный тип 3.5.2, ссылочный тип 3.8, строковый литерал 2.6, тип 3.3, тип компоненты 3.3, указывать 3.8, универсальный вещественный тип 3.5.6, универсальный целый тип 3.5.4, числовой литерал 2.4.

Пред. | Уровень выше | След.
Глава 4. ИМЕНА И ВЫРАЖЕНИЯ | Начало | 4.3. АГРЕГАТЫ


4.3. АГРЕГАТЫ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.3. АГРЕГАТЫ

Агрегат — это базовая операция, которая объединяет значения компонент в составное значение именуемого или индексируемого типа.

агрегат ::= (сопоставление-компонент
    {, сопоставление-компонент})

сопоставление-компонент ::=
    [выбор { | выбор} = > ] выражение

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

Именованные сопоставления могут стоять в произвольном порядке (исключая выбор others), но если в агрегате одновременно используются позиционные и именованные сопоставления, то первыми должны стоять позиционные сопоставления, каждое на своем месте. Следовательно, за именованными сопоставлениями в агрегате могут следовать только именованные сопоставления. В агрегатах, содержащих единственное сопоставление, должно всегда использоваться именованное сопоставление. Правила для сопоставления компонент агрегатов именуемого типа и агрегатов индексируемого типа определены в разд. 4.3.1 и 4.3.2.

Синтаксис выборов сопоставления компонент совпадает с синтаксисом разделов вариантов (см. 3.7.3). Выбор, являющийся простым именем компоненты, допустим только в агрегатах именуемого типа. Выбор, являющийся выражением или дискретным диапазоном, допустим только в агрегатах индексируемого типа; выбор, являющийся простым выражением, задает значение индекса; дискретный диапазон задает диапазон значений индекса. Выбор others допустим только в последнем сопоставлении компонент в качестве единственного выбора и определяет все оставшиеся компоненты, если они есть.

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

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

Примечание. Приведенное выше правило означает, что для определения типа агрегата не может быть использована информация, которую несет в себе агрегат. В частности, это определение не может использовать тип выражения в сопоставлении компонент, формы или типы выборов. Агрегат с одной компонентой всегда можно отличить от выражения, заключенного в скобки, благодаря обязательному именованию компоненты такого агрегата.

Ссылки: агрегат записи 4.3.1, агрегат массива 4.3.2, базовая операция типа 3.3.3, выбор 3.7.3, выражение 4.4, дискретный диапазон 3.6, именуемый тип 3.7, индекс 3.6, индексируемый тип 3.6, компонента 3.3, лимитируемый тип 7.4.4, первичное 4.4, простое выражение 4.4, простое имя 4.1, раздел вариантов 3.7.3, составное значение 3.3, составной тип 3.3, тип 3.3.

4.3.1. АГРЕГАТЫ ЗАПИСЕЙ

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

Значение, определяющее дискриминант, должно быть задано статическим выражением (заметим, что это значение определяет, какие из зависимых компонент должны присутствовать в значении записи).

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

Пример агрегата записи с позиционным сопоставлением:

(4, JULY, 1776) -- см. 3.7
Примеры агрегатов записи с именованными сопоставлениями:

(DAY => 4, MONTH => JULY, YEAR => 1776)
(MONTH => JULY, DAY => 4, YEAR => 1776)

(DISK, CLOSED, TRACK => 5, CYLINDER => 12) -— см. 3.7.3
(UNIT => DISK, STATUS => CLOSED, CYLINDER => 9, TRACK => 1)

Примеры сопоставления компонент с несколькими выборами:

(VALUE => 0, SUCCIPRED => new CELL'IO, null, null)) —- см. 3.8.1

—- Генератор вычисляется дважды: SUCC и PRED обозначают разные ячейки

Примечание: В агрегате с позиционными сопоставлениями первыми идут значения дискриминантов, так как раздел дискриминантов идет первым в описании именуемого типа; они должны быть в том же порядке, что и в разделе дискриминантов.

Ссылки: агрегат 4.3, в некотором порядке 1.6, возбуждение исключения 11, выбор 3.7.3, выражение 4.4, вычисление 4.5, генератор 4.8, дискриминант 3.3, зависит от дискриминанта 3.7.1, именуемый тип 3.7, имя компоненты 3.7, исключение CONSTRAINT_ERROR 11.1, компонента записи 3.7, ограничение 3.3, подкомпонента 3.3, подтип 3.3.2, программа 10, раздел вариантов 3.7.3, раздел дискриминантов 3.7.1, сопоставление компонент 4.3, статическое выражение 4.9, тип 3.3, удовлетворять 3.3.

4.3.2. АГРЕГАТЫ МАССИВОВ

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

Если тип агрегата — многомерный индексируемый тип, то n-мерный агрегат записывается как одномерный, в котором выражения, задающие сопоставления компонент, сами записываются как (n - 1)-мерный агрегат, называемый подагрегатом; подтип индекса одномерного агрегата задается первой позицией индекса индексируемого типа. То же правило используется для следующей позиции индекса при записи подагрегатов, если они опять многомерные. В многомерном агрегате допустимо использование строкового литерала в качестве одномерного массива символьного типа. В дальнейшем связанные с агрегатами массивов правила формулируются в терминах одномерных агрегатов.

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

Границы агрегата массива, имеющего выбор others, определяются соответствующим ограничением индекса. Использование выбора others допускается только тогда, когда агрегат находится в одном из следующих контекстов (контекст определяет соответствующее ограничение индекса):

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

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

б) Агрегат — это операнд квалифицированного выражения, обозначение типа которого указывает ограниченный индексируемый подтип.

в) Агрегат — это выражение в сопоставлении компонент другого агрегата индексируемого или именуемого типа, и если этот объемлющий агрегат — многомерный агрегат индексируемого типа, то сам он заключен в один из этих трех видов контекста.

Границы агрегата массива без выбора otners определяются следующим образом. Для агрегата с именованными сопоставлениями границы определяются наименьшим и наибольшим из заданных выборов. Нижняя граница позиционного агрегата определяется соответствующим ограничением индекса, если агрегат помещен в один из контекстов а), б) или в); в противном случае нижняя граница задается как S'FIRST, где S — подтип индекса; в обоих случаях верхняя граница определяется числом компонент.

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

При вычислении непустого агрегата массива производится проверка того, что значения задаваемых выборами индексов принадлежат соответствующему подтипу индекса, а также того, что значение каждой подкомпоненты агрегата принадлежит подтипу этой подкомпоненты. Для n-мерного агрегата производится проверка того, что все (n - 1)-мерные подагрегаты имеют одинаковые границы. Если хотя бы одна из этих проверок дает отрицательный результат, возбуждается исключение CONSTRAINT_ERROR.

Примечание. Допустимыми константами агрегата массива с выбором others являются те, в которых границы такого агрегата всегда известны из контекста.

Примеры агрегатов массивов с позиционными сопоставлениями:

(7, 9, 5, 1, 3, 2, 4, 8, 6, 0) ТАВLЕ'(5, 8, 4,1, others => 0) -- см. 3.6

Примеры агрегатов массивов с именованными сопоставлениями:

(1 .. 5 => (1 .. 8 => 0.0)) —- двумерный
(1 .. N => new CELL) -— N новых ячеек, в частности для N = 0

ТАВLЕ'(2 | 4 | 10 => 1, others => 0)
SСHEDULE'(MON .. FRI => TRUE, others => FALSE) --см. 3.6
SCHEDULE'(WED | SUN => FALSE, others => TRUE )

Поимеоы агрегатов двумерных массивов:

-- три агрегата с одним значением типа MATRIX, см. 3.6

((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
(1 => (1.1, 1.2, 1.3), 2 => (2..1. 2.2, 2.3))
(1 ==> (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3))

Примеры агрегатов в качестве значений инициализации:

А : TABLE := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0);        -- А(1)=7, А(10)=0
В : TABLE := ТАВLЕ'(2 | 4 | 10 => 1, others => 0);  -- В(1)=0, В(10)=1
С : constant MATRIX := (1 .. 5 => (1 .. 8 => 0.0)); -- С'FIRSТ(1)=1, С'LАSТ(2)=8

D : BIT_VECTOR(M .. N) := (M .. N => TRUE); -- см. 3.6
E : BIT_VECTOR(M .. N) := (others => TRUE);
F : STRING(1 .. 1) := (1 => 'F');           --однокомпонентный агрегат:то же, что и <F>

Ссылки: агрегат 4.3, в некотором порядке 1.6, возбуждение исключений 11, выбор 3.7.3, выражение 4.4, вычислить 4.5, диапазон индекса 3.6, именованное сопоставление компонент 4.3, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, квалифицированное выражение 4.7, компонента 3.3, объект 3.2, ограничение 3.3, ограничение индекса 3.6.1, ограниченный индексируемый подтип 3.6, подкомпонента 3.3, подтип индекса 3.6, позиционное сопоставление компонент 4.3, пустой массив 3.6.1, размерность 3.6, сопоставление компонент 4.3, составной ограничитель присваивания 5.2, статическое выражение 4.9, тип 3.3, тип индекса 3.6, тип компоненты 3.3, фактический параметр 6.4.1, формальный параметр 6.1, функция 6.5.

Пред. | Уровень выше | След.
4.2. ЛИТЕРАЛЫ | Начало | 4.4. ВЫРАЖЕНИЯ


4.4. ВЫРАЖЕНИЯ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.4. ВЫРАЖЕНИЯ

Выражение — это формула, которая определяет процесс вычисления значения.

выражение ::= отношение {and отношение}
    | отношение {and then отношение} | отношение {ог отношение}
    | отношение {or else отношение}  | отношение {хог отношение}

отношение ::=
    простое-выражение [операция-отношения простое - выражение]
    | простое-выражение [not] in диапазон
    | простое-выражение [not] in обозначение-типа

простое - выражение :: =
    [унарная-аддитивная-операция] слагаемое
    {бинарная-аддитивная-операция слагаемое}

слагаемое ::=
    множитель {мультипликативная-операция множитель}

множитель ::= первичное [** первичное]
    | abs первичное | not первичное

первичное ::= числовой-литерал | null | агрегат
    | строковый-литерал | имя |генератор
    | вызов-функции | преобразование-типа
    | квалифицированное-выражение | (выражение)

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

Тип выражения зависит только от типа его составных частей и применяемых операций; для совмещенных операндов или операций определение типа операнда или идентификация операции зависят от контекста. Для каждой предопределенной операции типы операндов и результата приведены в разд. 4.5.

Примеры первичных:

4.0                     -- литерал вещественного типа
PI                      -- именованное число
(1..10 => 0)            -- агрегат массива
SUM                     -- переменная
INTEGER'LAST            -- атрибут
SINE(X)                 -- вызов функции
COLOR'(BLUE)            -- квалифицированное выражение
РЕАL(М*N)               -- преобразование типа
(LINE_COUNT+10)         -- выражение в скобках

Примеры выражений:

VOLUME                       -- первичное
not DISTROYED                -- множитель
2 * LINE_COUNT               -- слагаемое
-4.0                         -- простое выражение
-4.0 + А                     -- простое выражение
В ** 2-4.0 * А * С           -- простое выражение
PASSWORD(1..3) = "BWV"       -- отношение
COUNT in SMALL_INT           -- отношение
COUNT not in SMALL_INT       -- отношение
INDЕХ=0 ог IТЕМ_НIТ          -- выражение
(COLD and SUNNY) or WARM     -- выражение (скобки обязательны)
А ** (В ** С)                -- выражение (скобки обязательны)

Ссылки: агрегат 4.3, агрегат массива 4.3.2, атрибут 4.1.4, бинарная аддитивная операция 4.5, 4.5.3, вызов функции 6.4, генератор 4.8, диапазон 3.5, именованное число 3.2, имя 4.1, квалифицированное выражение 4.7, контекст для разрешения совмещения 8.7, литерал вещественного типа 2.4, мультипликативная операция 4.5, 4.5.5, обозначение типа 3.3.2, объект 3.2, операция 4.5, операция возведения в степень 4.5, 4.5.6, операция отношения 4.5, 4.5.2, отношение 4.5.1, переменная 3.2.1, преобразование типа 4.6, пустой литерал 3.8, совмещение 8.3, совмещение операций 6.7, строковый литерал 2.6, тип 3.2, тип результата 6.1, унарная аддитивная операция 4.5, 4.5.4, числовой литерал 2.4.

Пред. | Уровень выше | След.
4.3. АГРЕГАТЫ | Начало | 4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ


4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ

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

логическая-операция          ::= and | ог | xor
операция-отношения           ::= =  | /= | <|<=|>|>=
бинарная-аддитивная-операция ::= +  | - | &
унарная-аддитивная-операция  ::= +  | -
мультипликативная-операция   ::= *  | / | mod | геm
операция-высшего-приоритета  ::= ** | abs | лоt

Формы управления промежуточной проверкой and then и ог else имеют тот же порядок старшинства, что и логические операции. Проверки принадлежности in и not in имеют то же старшинство, что и операции отношения.

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

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

Для каждой формы описания типа некоторые из перечисленных операций являются предопределенными, т. е. неявно вводятся описанием типа. Для каждого такого неявного описания операции именами параметров являются LEFT и RIGHT для бинарных операций; для унарных аддитивных операций и унарных операций abs и not их единственный параметр именуется RIGHT. В разд. 4.5.1 — 4.5.7 поясняются результаты предопределенных операций.

Предопределенные операции над целыми типами либо вырабатывают математически корректный результат, либо возбуждают исключение NUMERIC_ERROR. Предопределенная операция, вырабатывающая результат целого типа (отличного от универсального-целого ) , может возбуждать исключение NUMERIC_ERROR, только если математический результат не является значением этого целого типа. Предопределенные операции над вещественными типами вырабатывают результаты, точность которых определяется в разд. 4.5.7. Предопределенная операция, вырабатывающая результат вещественного типа (отличного от универсального-вещественного ) , может возбуждать исключение NUMERIC_ERROR, только если ее результат не принадлежит диапазону хранимых чисел этого типа, как это поясняется в разд. 4.5.7.

Примеры старшинства:

not SUNNY or WARM     -- совпадает с (not SUNNY) or WARM
Х > 4.0 and Y > 0.0                -- совпадает с (X > 4.0) and (Y > 0.0)
-4.0 * А ** 2                           -- совпадает с -(4.0 * (А ** 2))
abs (1 + А) + В                          -- совпадает с (abs (1 + А)) + В
Y ** (-3)                               -- скобки необходимы
А/В * С                                 -- совпадает с (А/В) * С
А + (В + С)                             -- вычисляется В + С, а затем к результату
                                        -- прибавляется А

Ссылки: вещественный тип 3.5.6, в некотором порядке 1.6, возбуждение исключения 11, выражение 4.4, диапазон 3.5, имя 4.1, исключение NUMERIC-ERROR 11.1, множитель 4.4, неявное описание 3.1, обозначение 6.1, описание типа 3.3.1, отношение 4.4, проверка вхождения 4.5.2, простое выражение 4.4, слагаемое-4.4, совмещение 6.6, 8.7, тип 3.3, универсальный-вещественный тип 3.5.6, универсальный-целый тип 3.5.4, форма управления промежуточной проверкой 4.5, 4.5.1, хранимое число 3.5.6, целый тип 3.5.4.

4.5.1. ЛОГИЧЕСКИЕ ОПЕРАЦИИ И ФОРМЫ УПРАВЛЕНИЯ ПРОМЕЖУТОЧНОЙ ПРОВЕРКОЙ

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

Знак операции | Операция | Тип операнда | Тип результата
and | Конъюнкция | Любой логический тип Массив логических компонент | Тот же логический тип Тот же индексируемый тип
ог | Дизъюнкция | Любой логический тип Массив логических компонент | Тот же логический тип Тот же индексируемый тип
хог | Исключающая дизъюнкция | Любой логический ТИП Массив логических компонент | Тот же логический Тот же индексируемый тип

Операции над массивами выполняются покомпонентно, если компоненты имеются (как для равенства, см. 4.5.2). Границы массива-результата совпадают с границами левого операнда. Для каждой компоненты левого операнда проверяется наличие соответствующей компоненты правого операнда, и наоборот. При нарушении соответствия компонент возбуждается исключение CONSTRAINT_ERROR.

Формы управления промежуточной проверкой and then и or else определены для двух операндов логического типа и вырабатывают результат того же самого типа. Левый операнд формы управления промежуточной проверкой всегда вычисляется первым. Если левый операнд выражения с формой and then дает значение FALSE, то правый операнд не вычисляется и значением выражения является FALSE. Если левый операнд с формой or else дает TRUE то правый операнд не вычисляется и значением выражения является TRUE. Если вычисляют ся оба операнда, то результат and then такой же, как and, а результат or else — как ог.

Примечание. Обычный смысл логических операций задается следующей таблицей истинности:

А | В | A and B | A or B | A xor B
TRUE | TRUE | TRUE | TRUE | FALSE
TRUE | FALSE | FALSE | TRUE | TRUE
FALSE | TRUE | FALSE | TRUE | TRUE
FALSE | FALSE | FALSE | FALSE | FALSE

Примеры логических операций:

SUNNY or WARM
FILTER(1 .. 10) and FILTER(15 .. 24) -- см. 3.6.1

Примеры форм управления с промежуточной проверкой:

NEXT_CAR.OWNER /= null and then NEXT_CAR.OWNER.AGE > 25
N = 0 or else A(N) = HIT_VALUE                 -- см. 3.8.1

Ссыпки: возбуждение исключений 11, граница диапазона индекса 3.6.1, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, компонента массива 3.6, логический тип 3.5.3, логическое значение FALSE 3.5.3, логическое значение TRUE 3.5.3, операция 4.5, операция типа 3.3, подтип индекса 3.6, предопределенная операция 4.5, пустой массив 3.6.1, размерность 3.6, сопоставимые компоненты массивов 4.5.2, тип 3.3.

4.5.2. ОПЕРАЦИИ ОТНОШЕНИЯ И ПРОВЕРКИ ПРИНАДЛЕЖНОСТИ

Операции равенство и неравенство предопределены для любого типа, не являющегося лимитируемым. Остальные операции отношения являются операциями упорядочивания: < (меньше), < = (меньше или равно), > (больше), > = (больше или равно). Операции упорядочивания предопределены для любого скалярного типа и любого дискретного индексируемого типа (одномерного индексируемого типа с компонентами дискретного типа). Операнды каждой предопределенной операции отношения имеют один и тот же тип. Тип результата — предопределенный тип — BOOLEAN.

Смысл операций отношения традиционный: результат равен TRUE, если соответствующее отношение удовлетворено, результат равен FALSE в противном случае. Операция нер-зенства дает результат, противоположный результату операции равенства: FALSE, если операнды равны; TRUE — если не равны.

Знак операции | Операция | Тип операнда | Тип результата
= /= | Равенство и неравенство | Любой тип | BOOLEAN
< < = > > = | Проверка упорядоченности | Любой скалярный ТИП | BOOLEAN
 |  | Дискретный индексируемый ТИП | BOOLEAN

Равенство для дискретных типов — это равенство значений. Результаты предопределенных операций отношения для вещественных операндов, значения которых равны приблизительно, приводятся в разд. 4.5.7. Два ссылочных значения равны, когда они указывают на один и тот же объект либо когда они равны пустому значению ссылочного типа.

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

Для сравнения двух записей одинакового типа сопоставленными компонентами являются компоненты [5] с одинаковыми идентификаторами компонент.

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

Если равенство явно определено для лимитируемого типа, оно не распространяется на составные типы, имеющие подкомпоненты лимитируемого типа (допускается явное определение равенства для таких составных типов).

Операции упорядочивания <, <= , > и >=, которые определены для дискретных индексируемых типов, соответствуют лексикографическому порядку, основанному на предопределенном отношении порядка для типов компонент. Пустой массив лексикографически меньше массива, имеющего по крайней мере одну компоненту. Для непустых массивов левый операнд лексикографически меньше правого операнда, если первая компонента левого операнда меньше первой компоненты правого операнда или если их первые компоненты равны, а хвост левого операнда лексикографически меньше правого (хвост состоит из оставшихся компонент, исключая первую, и может быть пустым).

Проверки принадлежности in и not in предопределены для всех типов. Типом результата является предопределенный тип BOOLEAN. Для проверки принадлежности диапазону простое выражение и границы диапазона должны быть одного и того же скалярного типа; для проверки принадлежности с обозначением типа тип простого выражения должен быть базовым для этого обозначения. Вычисление проверок принадлежности in вырабатывает результат TRUE, если значение простого выражения принадлежит данному диапазону или это значение принадлежит подтипу, заданному обозначением типа; в противном случае вычисление вырабатывает результат FALSE (для значений вещественного типа см. 4.5.7). Проверка принадлежности not in вырабатывает результат, противоположный результату проверки принадлежности in.

Примеры:

X /= Y

"" < "А" and "А" < "АА" -- TRUE
"АА" < "В" and "А" < "А " -- TRUE

MY_CAR = null --истина, если MY_CAR пуст (см. 3.8.1)
MY_CAR = YOUR_CAR -- истина, если используется один и тот же автомобиль
MY_CAR.all = YOUR_CAR.all -- истина, если оба автомобиля идентичны

N not in 1..10 -- проверка принадлежности диапазону
TODAY in MON .. FRI -- проверка принадлежности диапазону
TODAY in WEEKOAY -- проверка принадлежности подтипу (см. 3.5.1)
ARCHIVE in DISKUNIT -- проверка принадлежности подтипу (см. 3.7.3)

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

Если именуемый тип имеет компоненты, зависящие от дискриминантов, то компоненты двух значений сопоставлены тогда и только тогда, когда равны их дискриминанты. Компоненты непустых массивов сопоставлены, если и только если значения атрибута LENGTH(N) для каждой позиции индекса одинаковы у обоих массивов.

Ссылки: базовый тип 3.3, возбуждение исключения 11, вычисление 4.5, граница диапазона 3.5, диапазон 3.5, диапазон индекса 3.6, дискретный тип 3.5, идентификатор компоненты 3.7, именуемый тип 3.7, индекс 3.6, индексируемый тип 3.6, исключение 11, компонента 3.3, лимитируемый тип 7.4.4, обозначение типа 3.3.2, объект 3.2.1, операция 4.5, операция типа 3.3, подкомпонента 3.3, предопределенная операция 4.5, предопределенный логический тип 3.5.3, принадлежать подтипу 3.3, простое выражение 4.4, пустая запись 3.7, пустой массив 3.6.1, размерность 3.6, скалярный тип 3.5, следующий 3.5.5, составной тип 3.3, ссылочное значение 3.8, ссылочное значение null 3.8, тип 3.3, тип компоненты 3.3, указывать 3.8.

4.5.3. БИНАРНЫЕ АДДИТИВНЫЕ ОПЕРАЦИИ

Бинарные аддитивные операции + и - предопределены для любого числового типа и имеют свой обычный смысл. Операция катенации & предопределена для любого одномерного нелимитируемого индексируемого типа.

Знак | Операция | Тип левого | Тип правого | Тип результата
операции |  | операнда | операнда |
+ | сложение | Любой числовой ТИП | Тот же числовой ТИП | Тот же числовой ТИП
- | вычитание | Любой числовой ТИП | Тот же числовой ТИП | Тот же числовой ТИП
& | катенация | Любой индексируемый ТИП | Тот же индексируемый ТИП | Тот же индексируемый ТИП
 |  | Любой индексируемый ТИП | Тип компоненты | Тот же индексируемый ТИП
 |  | Тип компоненты | Любой индексируемый ТИП | Тот же индексируемый ТИП
 |  | Тип компоненты | Тип компоненты | Любой индексируемый ТИП

Для вещественных типов точность результата определяется типом операндов (см. 4.5.7).

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

Если один из операндов имеет тип компоненты индексируемого типа, то результат катенации определяется по приведенным выше правилам, где вместо этого операнда используется массив, имеющий этот операнд в качестве своей единственной компоненты, и с нижней границей, совпадающей с нижней границей подтипа индекса.

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

Примеры:

Z + 0.1     -- Z должен иметь вещественный тип
"А" & "BCD" -- катенация двух строковых литералов
'А' & "BCD" -- катенация символьного и строкового
                -- литералов
'А' & 'А'   -- катенация двух символьных литералов

Ссылки: вещественный тип 3.5.6, возбуждение исключений 11, диапазон подтипа индекса 3.6.1, длина массива 3.6.2, индексируемый тип 3.6, исключение CONSTRAINT-ERROR 11.1, лимитируемый тип 7.4.4, операция 4.5, операция типа 3.3, подтип индекса 3.6, предопределенная операция 4.5, пустой массив 3.6.1, размерность 3.6, символьный литерал 2.5, строковый литерал 2.6, тип 3.3, тип компоненты 3.3, числовой тип 3.5.

4.5.4. УНАРНЫЕ АДДИТИВНЫЕ ОПЕРАЦИИ

Унарные аддитивные операции + и - предопределены для любого числового типа и имеют свой обычный смысл. Для этих операций операнд и результат имеют один и тот же тип.

Знак операции | Операция | Тип операнда | Тип результата
+ | Сохранение знака | Любой числовой тип | Тот же числовой тип
- | Изменение знака | Любой числовой тип | Тот же числовой тип

Ссылки: операция 4.5, операция типа 3.3, предопределенная операция 4.5, тип 3.3, числовой тип 3.5.

4.5.5. МУЛЬТИПЛИКАТИВНЫЕ ОПЕРАЦИИ

Операции • и / предопределены для любого целого и любого плавающего типа и понимаются в обычном смысле. Операции mod и геm предопределены для любого целого типа. Для каждой из этих операций операнды и результат имеют один и тот же базовый тип. Для плавающих типов точность результата определяется типом операндов (см. 4.5.7).

Знак операции | Операция | Тип операнда | Тип | результата
* | Умножение | Любой целый тип | Тот | же целый тип
 | - | Любой плавающий тип | Тот | же плавающий тип
/ | Деление нацело | Любой целый тип | Тот | же целый тип
 | Деление плавающих | Любой плавающий тип | Тот | же плавающий тип
mod | Вычет по модулю | Любой целый тип | Тот | же целый тип
rem | Остаток | Любой целый тип | Тот | же целый тип

Деление нацело и остаток связаны следующим соотношением:

А = (А/В)*В + (А rem В)

где (А rem В) имеет знак значения А и абсолютное значение, меньшее абсолютного значения В. Деление нацело удовлетворяет следующему тождеству:

(-А)/В = -(А/В) = А/(-В)

Результат операции вычета по модулю таков, что (А mod В) имеет знак значения В и абсолютное значение, меньшее абсолютного значения В, и существует целое значение N такое, что должно удовлетворяться следующее соотношение:

А = В . N + (А mod В)

Для каждого фиксированного типа предопределены операции умножения и деления на операнд предопределенного типа INTEGER.

Знак операции | Операция | Тип левого операнда | Тип правого операнда | Тип результата
* | Умножение | Любой фиксированный ТИП | INTEGER | Тип левого операнда
 |  | INTEGER | Любой фиксированный ТИП | Тип правого операнда
/ | Деление | Любой фиксированный ТИП | INTEGER | Тип левого операнда

Умножение значения фиксированного типа на целое эквивалентно повторению операции сложения. Деление значения фиксированного типа на целое является приближенным и не меняет типа (см. 4.5.7).

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

Знак операции | Операция * | Тип левого операнда | Тип правого операнда | Тип результата
* | Умножение | Любой фиксированный ТИП | Любой фиксированный ТИП | Универсальный- фиксированный ТИП
/ | Деление | Любой фиксированный ТИП | Любой фиксированный ТИП | Универсальный - фиксированный ТИП

Операнды умножения могут быть одного и того же или различных фиксированных типов, а тип результата — анонимный предопределенный универсальный-фиксированный тип, дельта которого произвольно мала. Результат любого такого умножения всегда должен быть явно преобразован в значение некоторого числового типа. Это обеспечивает явное управление точностью вычислений. То же относится к делению значения фиксированного типа на значение фиксированного типа. Никакие другие операции для типа универсальный-фиксированный не определены.

Исключение NUMERIC_ERROR возбуждается операциями целого деления rem и mod, если правый операнд равен нулю.

Примеры:

I : INTEGER := 1;
J : INTEGER := 2;
К : INTEGER := 3;

X : REAL diglts 6 := 1.0; — СМ. 3.5.7
Y : REAL diglts 6 := 2.0;

F : FRACTION delta 0.0001 := 0.1; — СМ. 3.5.9
G : FRACTION delta 0.0001 := 0.1;

Выражение | Значение | Тип результата
I . J | 2 | Тот же, что тип I и J, т. е. INTEGER
K/J | 1 | Тот же, что тип К и J, т.е. INTEGER
К mod J | 1 | Тот же, что тип К и J, т. е. INTEGER
X/Y | 0.5 | Тот же, что тип Х и Y, т. е. REAL
F/2 | 0.05 | Тот же, что тип F, т.е. FRACTION
3 *. F | 0.3 | Тот же, что тип F, т. е. FRACTION
F * G | 0.01 | Универсальный-фиксированный требуется
 |  | преобразование
FRACTION (F * G)0.01 | FRACTION в результате преобразования |
REAL(J) * Y | 4.0 | REAL, как и тип обоих операндов после
 |  | преобразования

Примечание. Для положительных А и В частное задается выражением А/В, а остаток от деления А на В задается А rem В. Операция rem удовлетворяет следующим соотношениям:

А rem (-В) = А rem В
(-А) rem В = -(А rem В)

Для некоторого целого К справедливо следующее тождество:

А mod В = (А + К*В) mod В

Соотношения между делением нацело, остатком и вычетом по модулю иллюстрируются следующей таблицей:

А | В | А/В | А rem В | A mod B | А | В | А/В | А rem В | A mod B
10 | 5 | 2 | 0 | 0 | -10 | 5 | -2 | 0 | 0
11 | 5 | 2 | 1 | 1 | -11 | 5 | -2 | -1 | 4
12 | 5 | 2 | 2 | 2 | -12 | 5 | -2 | -2 | 3
13 | 5 | 2 | 3 | 3 | -13 | 5 | -2 | -3 | 2
14 | 5 | 2 | 4 | 4 | -14 | 5 | -2 | -4 | 1
10 | -5 | -2 | 0 | 0 | -10 | -5 | 2 | 0 | 0
11 | -5 | -2 | 1 | -4 | -11 | -5 | 2 | -1 | -1
12 | -5 | -2 | 2 | -3 | -12 | -5 | 2 | -2 | -2
13 | -5 | -2 | 3 | -2 | -13 | -5 | 2 | -3 | -3
14 | -5 | -2 | 4 | -1 | -14 | -5 | 2 | -4 | -4

Ссылки: базовый тип 3.3, возбуждение исключений 11, дельта фиксированного типа 3.5.9, исключение NUMERIC_ERROR 11.1, описание 3.1, описание переименования 8.5, плавающий тип 3.5.7, предопределенная операция 4.5, предопределенный пакет STANDARD 8.6, преобразование типа 4.6, фактический параметр 6.4.1, фиксированный тип 3.5.9, формальная подпрограмма настройки 12.1, целый тип 3.5.4, числовой тип 3.5.

4.5.6. ОПЕРАЦИИ ВЫСШЕГО ПРИОРИТЕТА

Унарная операция высшего приоритета abs предопределена для любого числового типа. Унарная операция высшего приоритета not предопределена для любого логического типа и одномерного индексируемого типа с компонентами логического типа.

Знак операции | Операция | Тип операнда | Тип результата
abs | Абсолютное значение | Любой числовой тип | Тот же числовой тип
not | Логическое отрицание | Любой логический тип | Тот же логический тип
 |  | Массив с логическими компонентами | Тот же индексируемый тип

Операция поt, применяемая к одномерному массиву с логическими компонентами, вырабатывает одномерный логический массив с теми же самыми границами; каждая компонента результата получается как логическое отрицание соответствующей компоненты операнда (т. е. компоненты с тем же значением индекса).

Операция возведения в степень »• предопределена для каждого целого и для каждого плавающего типов. В обоих случаях правый операнд, называемый показателем степени, имеет предопределенный тип INTEGER.

Знак операции | Операция | Тип левого операнда | Тип правого операнда | Тип | результата
** | Возведение в степень | Любой целый тип | INTEGER | Тип | левого операнда
 |  | Любой плавающий тип | INTEGER | Тип | левого операнда

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

Ссылки: возбуждение исключений 11, граница массива 3.6.1, индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, компонента массива 3.6, логический тип 3.5.3, операция умножение 4.5.5, плавающий тип 3.5.9, предопределенная операция 4.5, размерность 3.6, целый тип 3.5.4.

4.5.7. ТОЧНОСТЬ ОПЕРАЦИЙ С ВЕЩЕСТВЕННЫМИ ОПЕРАНДАМИ

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

Модельный интервал подтипа — это интервал с границами, заданными модельными числами этого подтипа. Связанный с принадлежащими вещественному подтипу значениями модельный интервал является наименьшим модельным интервалом (данного подтипа), который содержит эти значения (модельный интервал, связанный с модельным числом некоторого подтипа, состоит только из этого числа).

Для любой базовой или предопределенной операции, вырабатывающей результат вещественного подтипа, требуемые границы результата задаются модельным интервалом, который определяется следующим образом:

• Модельный интервал результата — это наименьший модельный интервал (подтипа результата), который включает в себя минимальное и максимальное из всех значений, получаемых при применении (точной) математической операции, где каждый операнд,— это любое значение из модельного интервала (подтипа операнда), определенного для этого операнда.

• Модельный интервал операнда, который сам является результатом операции, отличной от неявного преобразования, является модельным интервалом результата этой операции.

• Модельный интервал операнда, значение которого получено неявным преобразованием универсального выражения, является модельным интервалом, соответствующим этому значению из подтипа операнда.

Модельный интервал результата не определен, если абсолютное значение хотя бы одного из упомянутых выше математических результатов превышает наибольшее хранимое число типа результата. Всякий раз, когда модельный интервал результата не определен и реализация не может обеспечить, чтобы фактический результат лежал в диапазоне хранимых чисел, крайне желательно возбуждение исключения NUMERIC_ERROR. Правила языка, однако, этого не требуют, так как для некоторых объектных машин нет простых методов обнаружения переполнения. Значение атрибута MACHINE_OVERFLOWS указывает, возбуждает ли объектная машина исключение NUMERIC_ERROR в ситуациях переполнения (см. 13.7.3).

Хранимые числа вещественного типа определены (см. 3.5.6) как надмножество модельных чисел, границы ошибок которых подчиняются тем же правилам, что и для модельных чисел. Любое задаваемое в этом разделе в терминах модельных интервалов определение может поэтому быть распространено на хранимые интервалы хранимых чисел. Следствием такого распространения является то, что для реализации не допускается возбуждение исключения NUMERIC_ERROR, если интервал результата является хранимым интервалом.

Для результата операции возведения в степень модельный интервал, определяющий границы результата, определяется по приведенным выше правилам, которые применяются к последовательным умножениям при вычислении степени и к заключительному делению, если показатель степени — отрицательное число.

Для результата операции отношения между двумя вещественными операндами рассмотрим модельный интервал (подтипа операнда), определенный для каждого такого операнда; результат может быть любым значением, полученным при применении математической операции сравнения к значениям, произвольно выбранным в соответствующих модельных интервалах операндов. Если один или оба модельных интервала операндов не определены (и если при вычислении операндов не было возбуждено исключение), то в качестве результата сравнения допустимо любое возможное значение (т. е. либо TRUE, либо FALSE).

Результат проверки принадлежности определен в терминах сравнения значения операнда с нижней и верхней границами заданного диапазона или обозначения типа (к таким сравнени-ям применяются обычные правила).

Примечание. Для плавающего типа числа 15.0, 3.0 и 5.0 всегда являются модельными числами. Следовательно, X/Y, где Х равно 15.0, а Y — 3.0, согласно приведенным выше правилам, вырабатывает в результате точно 5.0. В общем случае деление не вырабатывает в результате модельные числа, и, следовательно, нельзя рассчитывать, что выполнено равенство (1.0/Х)'Х =1.0.

Ссылки: атрибут 4.1.4, атрибут MACHINE_OVERFLOWS 13.7.1, базовая операция типа 3.3.3, вещественный тип 3.5.6, возбуждение исключений 11, граница диапазона 3.5, граница ошибки 3.5.6, диапазон 3.5, исключение NUMERIC_ERROR 11.1, логическое значение FALSE 3.5.3, логи-' ческое значение TRUE 3.5.3, модельное число 3.5.6, обозначение типа 3.3.2, операция возведения в степень 4.5.6, операция отношение 4.5, 4.5.2, операция умножение 4.5.5, отношение 4.4, плавающий тип 3.5.9, подтип 3.3, предопределенная операция типа 3.3.3, преобразование типа 4.6, проверка вхождения 4.5.2, универсальное выражение 4.10, хранимое число 3.5.6.

[5] Если они есть. - Прим. ред.

Пред. | Уровень выше | След.
4.4. ВЫРАЖЕНИЯ | Начало | 4.6. ПРЕОБРАЗОВАНИЕ ТИПА


4.6. ПРЕОБРАЗОВАНИЕ ТИПА
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.6. ПРЕОБРАЗОВАНИЕ ТИПА

Вычисление явного преобразования типа — это вычисление выражения, заданного в качестве операнда, и преобразование результата в значение указанного целевого типа. Явные преобразования типов допустимы между взаимосвязанными типами.

преобразование-типа ::= обозначение-типа (выражение)

Целевой тип преобразования типа — это базовый тип обозначения типа. Тип операнда преобразования типа должен быть определимым независимо от контекста (в частности, независимо от целевого- типа). Более того, недопустимо, чтобы операнд преобразования типа был литералом null, генератором, агрегатом или строковым литералом; задание в качестве операнда преобразования типа выражения, заключенного в скобки, допускается, только если само выражение является допустимым.

Преобразование к подтипу состоит в преобразовании к целевому типу с последующей проверкой принадлежности результата этому подтипу. Допускается преобразование операнда заданного типа к тому же самому типу.

Другие явные преобразования типов допустимы в следующих трех случаях:

а. Числовые типы.

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

б. Производные типы.

Преобразование допустимо, если целевой тип и тип операнда являются производными один от другого, непосредственно или косвенно, или если существует третий тип, от которого производными являются тип операнда и целевой тип, непосредственно или косвенно.

в. Индексируемые типы.

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

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

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

Если допустимо преобразование одного типа в другой, то также допустимым является и обратное преобразование. Это обратное преобразование используется тогда, когда фактический параметр вида in out или out имеет форму преобразования типа имени (переменной), как это поясняется в разд. 6.4.1.

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

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

Для индексируемых типов в языке допускается неявное преобразование подтипов (см. 5.2.1). Последствием явного преобразования типа может быть изменение представления (в частности, см. 13.6). Явные преобразования используются также для фактических параметров (см. 6.4).

Примеры преобразования числовых типов:

RЕАL(2 * J)    -- значение преобразуется к плавающему типу
INТЕGЕR(1.6)   -- значение равно 2 INТЕGЕR(-0.4)
               -- значение равно 0

Примеры преобразования производных типов:

type A_FORM is new BFORM;

X : AFORM; Y : BPORM;

X := A_FORM(Y);
Y := B_FORM(X); -- обратное преобразование

Примеры преобразования индексируемых типов:

type SEQUENCE is array (INTEGER range <>) of INTEGER:
subtype DOZEN is SEQUENCE(1 .. 12);
LEDGER : array(1 .. 100) of INTEGER;

SEQUENCE(LEDGER)             -- с границами как у LEDGER
SEQUENCE(LEDGER(31 .. 42))   -- с границами 31—42
DOZEN(LEDGER(31 .. 42))      -- с границами как у DOZEN

Примеры неявных преобразований:

Х : INTEGER := 2;
X + 1 + 2          -- неявное преобразование каждого целого литерала
1 + 2 + X          -- неявное преобразование каждого целого литерала
X + (1 + 2)        -- неявное преобразование каждого целого литерала

2 = (1 + 1)                                 -- тип - универсальный-целый
                                            -- неявных преобразований нет
A'LENGTH = B'LENGTH                         -- то же, что и выше
С : constant := 3 + 2    -- то же, что и выше
X = 3 and 1 = 2          -- неявное преобразование 3, но не 1 и 2

Ссылки: атрибут 4.1.4, базовый тип 3.3, вещественный тип 3.5.6, вид 6.1, возбуждение исключений 11, выражение 4.4, именованное число 3.2, имя 4.1, индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINED-ERROR 11.1, компонента 3.3, неограниченный индексируемый тип 3.6, обозначение типа 3.3.2, ограниченный индексируемый подтип 3.6, оператор 5, переменная 3.2.1, плавающий тип 3.5.7, подтип 3.3, подтип индекса 3.6, представление 13.1, принадлежать подтипу 3.3, производный тип 3.4, пустой массив 3.6.1, размерность 3.6, сопоставленная компонента 4.5.2, тип 3.3, тип индекса 3.6, универсальный вещественный тип 4.5.6, универсальный целый тип 3.5.4, фактический параметр 6.4.1, целый тип 3.5.4, числовой литерал 2.4, числовой тип 3.5.

Пред. | Уровень выше | След.
4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ | Начало | 4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ


4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ

Квалифицированное выражение используется для явного указания типа и, возможно, подтипа операнда, заданного выражением или агрегатом.

квалифицированное-выражение ::= обозначение-типа' (выражение) | обозначение-типа'агрегат

Тип операнда должен совпадать с базовым типом обозначения типа. Значение квалифицированного выражения — это значение операнда. Вычисление квалифицированного выражения выдает операнд и проверяет, принадлежит ли его значение подтипу, заданному в обозначении типа. При отрицательном результате проверки возбуждается исключениеCONSTRAINT_ERROR.

Примеры:

type MASK is (FIX, DEC, EXP, SIGNIP);
type CODE is (FIX, CLA, DEC, TNZ, SUB);

PRINT (MASK'(DEC)); -- DEC типа MASK
PRINT (СОDЕ'(DЕC)); -- DЕС типа CODE

for J in CODE'(FIX) .. CODE'(DEC) loop ... — квалификация необходима либо для FIX, либо для DEC
for J in. CODE range FIX .. DEC loop ... — квалификация не нужна
for J in CODE'(FIX) .. DEC loop ... — квалификация для DEC не нужна

DOZEN'(1 | 3 | 5 | 7 => 2, others => 0) -- см. 4.6

Примечание. Когда тип литерала перечисления или агрегата неизвестен из контекста, квалифицированное выражение может быть использовано для явного установления типа. Например, совмещенный литерал перечисления должен быть квалифицирован в следующих случаях: при использовании его в качестве параметра в вызове совмещенной подпрограммы, которая не может быть идентифицирована на основе типов остальных параметров и типа результата; в отношении, в котором оба операнда — совмещенные литералы перечисления; в массиве или диапазоне параметра цикла, в которых обе границы — совмещенные литералы перечисления. Явная квалификация используется также для определения совмещенной функции без параметров или для ограничения значения данным подтипом.

Ссылки: агрегат 4.3, базовый тип 3.3, возбуждение исключений 11, вызов подпрограммы 6.4, выражение 4.4, граница диапазона 3.5, диапазон 3.3, исключение CONSTRAINT_ERROR 11.1, контекст разрешения совмещения 8.7, литерал перечисления 3.5.1, массив 3.6, обозначение типа 3.3.2, отношение 4.4, параметр цикла 5.5, подпрограмма 6, подтип 3.3, совмещение 8.5, тип 3.3, функция 6.5.

Пред. | Уровень выше | След.
4.6. ПРЕОБРАЗОВАНИЕ ТИПА | Начало | 4.8. ГЕНЕРАТОРЫ


4.8. ГЕНЕРАТОРЫ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.8. ГЕНЕРАТОРЫ

Вычисление генератора создает объект и вырабатывает ссылочное значение, которое указывает на этот объект.

генератор ::= new указатель-подтипа | new квалифицированное - выражение

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

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

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

При вычислении генератора сначала производится предвыполнение указания подтипа или вычисление квалифицированного выражения. Затем создается новый объект. Далее осуществляется инициализация, как для описанного объекта (см. 3.2.1): явно — для квалифицированного выражения, неявно — для указания подтипа. Наконец, возвращается ссылочное значение, указывающее на созданный объект.

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

В случаях когда требуется более точное управление распределением памяти под указанные значениями ссылочного типа объекты, оно может быть обеспечено следующими средствами:

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

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

pragma CONTROLLED (простое-имя-ссылочного-типа);

Эта прагма для данного ссылочного типа допустима в тех же местах, что и спецификатор представления этого типа (см. 13.1).

в. Явного освобождения памяти, занимаемой объектом, указанным ссылочным значением, можно достичь вызовом процедуры, полученной настройкой предопределенной библиотечной процедуры UNCHECKED_DEALLOCATION (см. 13.10.1). /

При исчерпании памяти генератором возбуждается исключение STORAGE_ERROR. Заметим также, что исключение CONSTRAINT_ERROR может быть возбуждено при вычислении квалифицированного выражения, во время предвыполнения указания подтипа или при инициализации.

Примеры (ссылочных типов, описанных в разд. 3.8):

new CELL'(0, null, null)                -- явная инициализация
new CELL'(VALUE => 0, SUCC => null, PRED => null) -- явная инициализация
new CELL                                -- нет инициализации

new MATRIX(1 .. 10, 1 .. 20)            -- даны только границы
new MATRlX'(1 .. 10 => (1 .. 20 => 0.0)) -— явная инициализация

new BUFFER(100) -- дан только дискриминант
new BUFPER'(SIZE => 80, POS => 0, VALUE => (1 .. 80 => 'А')) -- явная инициализация

Ссылки: библиотечный модуль 10.1, возбуждение исключений 11, вычисление квалифицированного выражения 4.6, главная программа 10.1, граница массива 3.6.1, дискриминант 3.3, завершенная задача 9.4, задачный тип 9.2, имя 4.1, индексируемый тип 3.6, инициализация 3.2.1, исключение CONSTRAINT_ERROR 11.1, исключение STORAGE_ERROR 11.1, квалифицированное выражение 4.7, конкретизация 12.3, контекст разрешения совмещения 8.7, набор 3.8, настраиваемая процедура 12.1, начальное значение 3.2.1, обозначение типа 3.3.2, объект 3.2.1, ограничение 3.3, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, ограниченный подтип 3.3, оператор блока 5.6, описание объекта 3.2.1, описание типа 3.3.1, определение ссылочного типа 3.8, подкомпонента 3.3, подтип 3.3, прагма 2.8, предвыполнение 3.9, производный тип 3.4, простое имя 4.1, процедура 6, спецификатор длины 13.2, спецификатор представления 13.1, ссылочное значение 3.8, ссылочный тип 3.8, тело задачи 9.1, тело подпрограммы 6.7, тип 3.3, тип с дискриминантами 3.3, указание подтипа 3.3.2, указывать 3.8.

Пред. | Уровень выше | След.
4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ | Начало | 4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ


4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ

Некоторые выражения скалярного типа называются статическими. Аналогично статическими называют некоторые дискретные диапазоны, а обозначения типов для некоторых скалярных подтипов называют обозначающими статические подтипы.

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

а. Литерал перечисления (включая символьный литерал).

б. Числовой литерал.

в. Именованное число.

г. Заданная явным описанием константа статического подтипа и инициализированная статическим выражением.

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

е. Определяемый в языке атрибут статического подтипа; если атрибут — функция, фактические параметры должны быть также статическими выражениями.

ж. Квалифицированное выражение, обозначение типа которого задает статический подтип, а операнд — статическое выражение.

з. Заключенное в скобки статическое выражение.

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

Примечание. Точность вычисления статического выражения вещественного типа определена правилами, данными в разд. 4.5.7. Если результат не является модельным (или хранимым) числом этого типа, то значение выражения, полученное при вычислении во время компиляции, не обязано совпадать со значением, которое получится при вычислении во время счета.

Атрибуты массивов не являются статическими, в частности статическим не является атрибут RANGE.

Ссылки: атрибут 4.1.4, базовый тип 3.3, возбуждение исключений 11, выражение 4.4, граница диапазона 3.5, дискретный диапазон 3.6, дискретный тип 3.5, именованное число 3.2, инициализация 3.2.1, исключение 11, квалифицированное выражение 4.7, константа 3.2.1, литерал перечисления 3.5.1, модельное число 3.5.6, неявное описание 3.1, обозначение типа 3.3.2, ограничение диапазона 3.5, описание константы 3.2.1, подтип 3.3, предопределенная операция 4.5, символьный литерал 2.5, скалярный тип 3.5, фактический параметр 6.4.1, фактический параметр настройки 12.3, формальный параметр настройки 12.1.2, функция 6.5, хранимое число 3.5.6, числовой литерал 2.4.

Пред. | Уровень выше | След.
4.8. ГЕНЕРАТОРЫ | Начало | 4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ


4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ
Пред. Глава 4. ИМЕНА И ВЫРАЖЕНИЯ След.

4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ

Универсальное выражение — это выражение, вырабатывающее результат универсального-целого или универсального-вещественного типа.

Для универсального-целого типа предопределены те же операции, что и для любого целого типа. Для универсального-вещественного типа предопределены те же операции, что и для любого плавающего типа. Кроме того, эти операции включают операции умножения и деления.

Знак Операция операции |  | Тип левого операнда | Тип правого операнда | Тип результата
* | Умножение | Универсальный-вещественный | Универсальный- целый | Универсальный- вещественный
 |  | Универсальный - целый | Универсальный- вещественный | Универсальный - вещественный
/ | Деление | Универсальный-вещественный | Универсальный-целый | Универсальный-вещественный

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

При вычислении операций универсального выражения, не являющегося статическим, возбуждение исключения NUMERIC_ERROR реализацией допускается только в том случае, если результат операции — вещественное число с абсолютным значением, превышающим наибольшее хранимое число самого точного предопределенного плавающего типа (исключая универсальный-вещественный), или целое значение, большее, чем SYSTEM.MAX_INT, либо меньшее, чем SYSTEM.MIN_INT.

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

Примеры:

1+1 -- 2
аbs(-10)*3 -- 30

KILO : constant := 1000;
MEGA : constant := KILO*KILO;    -- 1 000 000
LONG : constant := FLOАТ'DIGIТS*2;

HALF_PI    : constant := Р1/2; -- см. 3.2.2.
DEG_TO_RAD : constant := HALF_Р1/90;
RAD_TO_DEG : constant := 1.0/DЕG_ТО_RАD; --- эквивалентно 1.0/((3.14159_26536/2)/90)

Ссылки: атрибут 4.1.4, вещественный тип 3.5.6, вычисление выражения 4.5, мультипликативная операция 4.5, 4.5.5, первичное 4.4, плавающий тип 3.5.9, предопределенная операция типа 3.3.3, SYSTEM.MAX-INT 13.7, SYSTEM.MIN-INT 13.7, тип 3.3, универсальный-вещественный тип 3.5.6, универсальный-целый тип 3.5.4, фактический параметр 6.4.1, функция 6.5, хранимое число 3.5.6, целый тип 3.5.4.

Пред. | Уровень выше | След.
4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ | Начало | Глава 5. ОПЕРАТОРЫ


Глава 5. ОПЕРАТОРЫ
Пред. След.

Глава 5. ОПЕРАТОРЫ

Содержание

5.1. ПРОСТЫЕ И СОСТАВНЫЕ ОПЕРАТОРЫ. ПОСЛЕДОВАТЕЛЬНОСТИ ОПЕРАТОРОВ
5.2. ОПЕРАТОРЫ ПРИСВАИВАНИЯ
5.3. УСЛОВНЫЕ ОПЕРАТОРЫ
5.4. ОПЕРАТОРЫ ВЫБОРА
5.5. ОПЕРАТОРЫ ЦИКЛА
5.6. ОПЕРАТОРЫ БЛОКА
5.7. ОПЕРАТОРЫ ВЫХОДА
5.8. ОПЕРАТОРЫ ВОЗВРАТА
5.9. ОПЕРАТОРЫ ПЕРЕХОДА

Оператор определяет действие, которое предстоит выполнить; процесс реализации этого действия называется выполнением оператора.

В данной главе описываются общие правила, применимые ко всем операторам, и некоторые операторы. Оператор вызова процедуры описывается в гл. 6. Операторы вызова входа, задержки, принятия, отбора и прекращения описываются в гл. 9, оператор возбуждения — в гл. 11, а оператор кода — в гл. 13.

Ссылки: оператор возбуждения 11.3, оператор вызова входа 9.5, оператор вызова процедуры 6.4, оператор задержки 9.6, оператор кода 13.8, оператор отбора 9.7, оператор прекращения 9.10, оператор принятия 9.5.

5.1. ПРОСТЫЕ И СОСТАВНЫЕ ОПЕРАТОРЫ. ПОСЛЕДОВАТЕЛЬНОСТИ ОПЕРАТОРОВ

Оператор может быть или простым, или составным. Простой оператор не содержит других операторов. Составной оператор содержит простые операторы и другие составные операторы.

последовательность-операторов ::= оператор (оператор)
оператор ::= {метка} простой-оператор
           | {метка} составной-оператор
простой-оператор ::= пустой-оператор
   | оператор-присваивания | оператор-вызова-процедуры
   | оператор-выхода       | оператор-возврата
   | оператор-перехода     | оператор-вызова-входа
   | оператор-задержки     | оператор-прекращения
   | оператор-возбуждения  | оператор-кода

составной-оператор ::=
     условный-оператор | оператор-выбора
   | оператор-цикла    | оператор-блока
   | оператор-принятия | оператор-отбора

метка ::= << простое-имя-метки >>
пустой-оператор ::= null:

Говорят, что имя каждой метки, стоящей перед оператором, помечает этот оператор. Имя метки (а также имя цикла или блока) неявно описано в конце раздела описаний самого внутреннего блока, тела подпрограммы, тела пакета, тела задачи или настраиваемого тела, которые содержат данный помеченный оператор (именованный оператор цикла или именованный оператор блока). При отсутствии в операторе блока раздела описаний подразумевается, что оператор блока содержит неявный раздел описаний (с предшествующим declare ).

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

Выполнение пустого оператора заключается в переходе к выполнению следующего оператора.

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

Примеры помеченных операторов:

<<HERE>> <<ICI>> <<AQUI>> <<HIER>> null;

<<AFTER>> X := 1;

Примечание. Область действия описания начинается самим описанием (см. 8.2). Область действия неявного описания имени метки, цикла или блока начинается до первого явного появления соответствующего имени, поскольку это появление возможно лишь в качестве метки оператора, в операторе блока, операторе цикла или операторе перехода. Неявное описание в операторе блока может скрыть описание, данное во внешнем программном модуле или операторе блока (согласно обычным правилам скрытия, изложенным в разд. 8.3).

Ссылки: альтернатива завершения 9.7.1, возбуждение исключений 11, завершенная задача 9.4, задача 9, задачный модуль 9.1, идентификатор 2.3, имя блока 5.6, имя цикла 5.5, исключение 11, настраиваемое тело 12.1, настраиваемый модуль 12, неявное описание 3.1, область действия 8.2, оператор блока 5.6, оператор возбуждения 11.3, оператор возврата 5.8, оператор выбора 5.4, оператор вызова входа 9.5, оператор вызова процедуры 6.4, оператор выхода 5.7, оператор задержки 9.6, оператор кода 13.8, оператор отбора 9.7, оператор перехода 5.9, оператор прекращения 9.10, оператор принятия 9.5, оператор, присваивания 5.2, оператор цикла 5.5, описание 3.1, пакет 7, подпрограмма 6, программный модуль 6, простое имя 4.1, раздел описаний 3.9, скрытие 8.3, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, условный оператор 5.3.

Пред. | Уровень выше | След.
4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ | Начало | 5.2. ОПЕРАТОРЫ ПРИСВАИВАНИЯ


5.2. ОПЕРАТОРЫ ПРИСВАИВАНИЯ
Пред. Глава 5. ОПЕРАТОРЫ След.

5.2. ОПЕРАТОРЫ ПРИСВАИВАНИЯ

Оператор присваивания заменяет текущее значение переменной новым значением, задаваемым выражением. Переменная в левой части оператора присваивания и выражение в его правой части должны быть одного и того же типа, однако он не должен быть лимитируемым.

оператор-присваивания ::= имя-переменной := выражение;

При выполнении оператора присваивания вначале вычисляются имя переменной и выражение в порядке, не определенном в языке. Затем, если переменная не является массивом, проверяется принадлежность значения выражения подтипу переменной (если же переменная — массив, то при присваивании производится преобразование подтипа, как описано в разд. 5.2.1). Наконец, значение выражения становится новым значением переменной.

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

Примеры:

VALUE := MAX_VALUE - 1;
SHADE := BLUE;

NEXT_FRAME(F)(M, N) := 2.5; --CM. 4.1.1
U := DOT_PRODUCT(V, W);     -- CM. 6.5

WRITER := (STATUS => OPEN, UNIT => PRINTER, LINE_COUNT => 60); -- CM. 3.7.3
NEXT_CAR.all := (72074, null); -- CM. 3.8.1

Примеры проверок ограничений:

I,J : INTEGER range 1 ..10;
К : INTEGER range 1 ..20;

I := J; --одинаковые диапазоны
К := J; -- совместимые диапазоны
J := К; -- при К<10 возбудится исключение CONSTRAINT_ERROR

Примечание. Значения дискриминантов объекта, указанного ссылочным значением, не могут быть изменены (даже присваиванием составного значения всему объекту), поскольку такие объекты, созданные генераторами, всегда являются ограниченными (см. 4.8); подкомпоненты таких объектов могут и не быть ограниченными.

Если выражение в правой части является числовым литералом, именованным числом или атрибутом, вырабатывающим результат типа универсальный-целый или универсальный-вещественный, то производится неявное преобразование типа, описанное в разд. 4.6.

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

Ссылки: вызов функции 6.4, выражение 4.4, вычисление 4.5, генератор 4.8, дискриминант 3.7.1, имя 4.1, исключение CONSTRAINT_ERROR 11.1, компонента 3.6, 3.7, массив 3.6, неявное преобразование типа 4.6, объект 3.2, отрезок 4.1.2, ошибочный 1.6, переменная 3.2.1, подкомпонента 3.3, подтип 3.3, преобразование подтипа 4.6, присваивание массива 5.2.1, совмещение 6.6, 8.7, ссылочный тип 3.8, тип 3.3, указывать 3.8, универсальный-вещественный тип 3.5.6, универсальный-целый тип 3.5.4, числовой литерал 2.4.

5.2.1. ПРИСВАИВАНИЯ МАССИВОВ

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

Это значит, что новое значение каждой компоненты индексируемой переменной задается сопоставляемой ей компонентой индексируемого значения, полученного при вычислении выражения (см. определение сопоставляемых компонент в 4.5.2). При преобразовании подтипа для каждой компоненты индексируемой переменной проверяется наличие сопоставляемой компоненты индексируемого значения, и наоборот. При отрицательном результате этой проверки возбуждается исключение CONSTRAINT_ERROR, а значение каждой компоненты переменной не изменяется.

Примеры:

А : STRING(1 .. 31);
В : STRING(3 .. 33);
...
А := B; — одинаковое количество компонент

А(1 .. 9) := "tar sauce";
А(4 .. 12) := A(1 .. 9); -- А(1 .. 12) = "tartar Sauce"

Примечание. Присваивание массива определено даже в случае перекрывающихся отрезков, поскольку выражение в правой части вычисляется До присваивания компонент. Так, в случае последнего из приведенных примеров реализация, вырабатывающая А(1 .. 12) = = "tartartartar", была бы некорректной^.

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

Ссылки: исключение CONSTRAINT_ERROR 11.1, массив 3.6, отрезок 4.1.2, переменная 3.2.1, преобразование подтипа 4.6, присваивание 5.2, сопоставляемые индексируемые компоненты 4.5.2, тип 3.3.

1) Покомпонентная пересылка недопустима. — Прим. ред.

Пред. | Уровень выше | След.
Глава 5. ОПЕРАТОРЫ | Начало | 5.3. УСЛОВНЫЕ ОПЕРАТОРЫ


5.3. УСЛОВНЫЕ ОПЕРАТОРЫ
Пред. Глава 5. ОПЕРАТОРЫ След.

5.3. УСЛОВНЫЕ ОПЕРАТОРЫ

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

условный-оператор ::=
if условие then
   последовательность - операторов |
elsif условие then
   последовательность-операторов)
[else
   последовательность - операторов]
end if

; условие ::= логическое-выражение

Выражение, задающее условие, должно быть логического типа.

Для выполнения условного оператора вычисляются последовательно условия после if и elsif (трактуя заключительное else как elsif TRUE then ) до тех пор, пока одно из них не окажется истинным или не будут исчерпаны все условия. При нахождении условия со значением TRUE выполняется соответствующая последовательность операторов, в противном случае не выполняется ни одна из последовательностей операторов.

Примеры:

if MONTH = DECEMBER and DAY = 31 then
   MONTH := JANUARY;
   DAY := 1;
   YEAR := YEAR + 1;
end if;

if LINE-JOO-SHORT then
   raise LAYOUT-ERROR;
elsif LINEFULL then
   NEW-LINE; PUT(ITEM);
else
PUT(ITEM);
end if;

if MY-.CAR.OWNER.VEHICLE /= MY-.CAR then -- CM. 3.8.1
   REPORT ("Incorrect data");
end if;

Ссылки: выражение 4.4, выполнение 4.5, логический тип 3.5.3, последовательность операторов 5.1.

Пред. | Уровень выше | След.
5.2. ОПЕРАТОРЫ ПРИСВАИВАНИЯ | Начало | 5.4. ОПЕРАТОРЫ ВЫБОРА


5.4. ОПЕРАТОРЫ ВЫБОРА
Пред. Глава 5. ОПЕРАТОРЫ След.

5.4. ОПЕРАТОРЫ ВЫБОРА

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

оператор-выбора ::=
   case выражение is
      альтернатива-оператора-выбора
      {альтернатива - оператора - выбора}
   end case;

альтернатива-оператора-выбора :: =
   when выбор { | выбор } => последовательность-операторов

Выражение должно быть дискретного типа, который должен быть определимым независимо от контекста выражения, но с учетом того факта, что тип выражения должен быть дискретным. Более того, тип этого выражения не должен быть настраиваемым формальным ти-

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

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

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

Выполнение оператора выбора заключается в вычислении выражения, в выборе последовательности операторов и в выполнении выбранной последовательности операторов.

Примеры:

case SENSOR is
   when ELEVATION => RECORDELEVATION (SENSOR-VALUE);
   when AZIMUTH => RECORD.AZIMUTH (SENSOR-VALUE);
   when DISTANCE => RECORD-DISTANCE (SENSOR-VALUE);
   when others => null;
end case;

case TODAY is
   when MON => COMPUTE-INITIAL-BALANCE;
   when FRI => COMPUTE-CLOSING-BALANCE;
   when TUE .. THU => GENERATEREPORT(T-ODAY);
   when SAT .. SUN => null;
end case;

case BIN_NUMBER(COUNT) is
   when 1 => UPDATE_BIN(1);
   when 2 => UPDATE_BIN(2);
   when 3 | 4 => EMPTY_BIN(1); EMPTY_BIN(2);
   when others => raise ERROR;
end case;

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

Выбор others обязателен в операторе выбора, если выражение имеет тип универсальный-целый (например, выражение является целым литералом), так как это единственный способ учесть все значения типа универсальный-целый.

Ссылки: базовый тип 3.3, выбор 3.7.3, вызов функции 6.4, выражение 4.4, дискретный тип 3.5, имя 4.1, квалифицированное выражение 4.7, контекст разрешения совмещения 8.7, литерал перечисления 3.5.1, обозначение типа 3.3.2, объект 3.2.1, последовательность операторов 5.1, преобразование 4.6, преобразование типа 4.6, подтип 3.3, совмещение 6.6, 8.7, статический дискретный диапазон 4.9, статический подтип 4.9, тип 3.3, формальный тип настройки 12.1.

Пред. | Уровень выше | След.
5.3. УСЛОВНЫЕ ОПЕРАТОРЫ | Начало | 5.5. ОПЕРАТОРЫ ЦИКЛА


5.5. ОПЕРАТОРЫ ЦИКЛА
Пред. Глава 5. ОПЕРАТОРЫ След.

5.5. ОПЕРАТОРЫ ЦИКЛА

Оператор цикла содержит последовательность операторов, выполнение которой повторяется несколько раз или ни одного раза. \

оператор-цикла ::=
   [простое-имя-цикла:]
      [схема-итерации] loop
         последовательность - операторов
      end loop [простое-имя-цикла];
схема-итерации ::= while условие
  | for спецификация-параметра-цикла
спецификация-параметра-цикла ::=
    идентификатор in [reverse] дискретный-диапазон

Если в операторе цикла используется простое имя цикла, то оно должно задаваться как в начале, так и в конце этого оператора.

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

Для оператора цикла со схемой итерации while перед каждым выполнением последовательности операторов вычисляется условие; если значением условия является TRUE, то последовательность операторов выполняется, если FALSE, то выполнение оператора цикла заканчивается.

Для оператора цикла со схемой итерации for спецификация параметра цикла является описанием параметра цикла с заданным в схеме итерации идентификатором. Параметр цикла — это объект, типом которого является базовый тип дискретного диапазона (см. 3.6.1). В пределах последовательности операторов параметр цикла считается константой. Поэтому его использование в качестве переменной в левой части оператора присваивания недопустимо. Параметр цикла не должен использоваться в качестве параметра вида out или in out оператора вызова процедуры или входа, а также в качестве параметра вида in out конкретизации настройки.

Для выполнения оператора цикла с итерационной схемой for сначала предвыполняется спецификация параметра цикла. При этом создается параметр цикла и вычисляется дискретный диапазон.

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

Пример оператора цикла без схемы итерации:

loop
   GET(CURRENT_CHARACTER);
   exit when CURRENT_CHARACTER = '*';
end loop;

Пример оператора цикла со схемой итерации while:

while BID(N).PRICE < CUT_OFF.PRICE loop
   RECORD_BID(BID(N).PRICE);
   N := N + 1;
end loop;

Пример оператора цикла со схемой итерации for:

for J in BUFFER'RANGE loop -— правильно даже для пустого диапазона
   if BUFFER(J) /= SPACE then
      PUT(BUFFER(J));
   end if;
end loop;

Пример оператора цикла с простым именем цикла:

SUMMATION:
   while NEXT /= HEAD loop -— CM. 3.8
      SUM := SUM + NEXT.VALUE;
      NEXT := NEXT.SUCC;
   end loop SUMMATION;

Примечание. Область действия параметра цикла простирается от спецификации параметра цикла до конца оператора цикла, а правила видимости таковы, что параметр цикла видим только в пределах последовательности операторов в цикле.

Дискретный диапазон цикла вычисляется только один раз. Использование зарезервированного слова reverse не изменяет дискретный диапазон, так что следующие схемы итерации не эквивалентны (в первой — диапазон пуст):

for J in reverse 1 .. 0
for J in 0 .. 1

Имена циклов используются также в операторах выхода и в расширенных именах (в качестве префикса имени параметра цикла).

Ссылки: альтернатива завершения 9.7.1, базовый тип 3.3, видимость 8.3, возбуждение исключений 11, вызов процедуры 6.4, вычисление 4.5, граница диапазона 3.5, дискретный диапазон 3.6.1, зарезервированное слово 2.9, идентификатор 2.3, конкретизация настройки 12.3, константа 3.2.1, контекст разрешения совмещения 8.7, логическое значение FALSE 3.5.3, логическое значение TRUE 3.5.3, область действия 8.2, объект 3.2, оператор возврата 5.8, оператор вызова входа 9.5, оператор выхода 5.7, оператор перехода 5.9, оператор присваивания 5.2, описание 3.1, последовательность операторов 5.1, пред'выполнение 3.1, преобразование 4.6, префикс 4.1, простое имя 4.1, пустой диапазон 3.5, расширенное имя 4.1.3, условие 5.3, фактический параметр 6.4.1, фактический параметр настройки 12.3, целый тип 3.5.4.

Пред. | Уровень выше | След.
5.4. ОПЕРАТОРЫ ВЫБОРА | Начало | 5.6. ОПЕРАТОРЫ БЛОКА


5.6. ОПЕРАТОРЫ БЛОКА
Пред. Глава 5. ОПЕРАТОРЫ След.

5.6. ОПЕРАТОРЫ БЛОКА

Оператор блока содержит последовательность операторов, которой может предшествовать раздел описаний и за которой могут следовать обработчики исключений.

оператор-блока ::=
   [простое - имя - блока:]
      [declare
         раздел - описаний]
      begin
         последовательность-операторов
      [exception
         обработчик - исключения
         {обработчик - исключения}]
      end [простое- имя -блока];

Если в операторе блока используется простое имя блока, то оно должно задаваться как в начале, так и в конце.

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

Пример:

SWAP:
   declare
      TEMP : INTEGER;
   begin
      TEMP := V;
      V := U;
      U :== TEMP;
   end SWAP;

Примечание. Если в операторе блока, выполнение последовательности операторов которого окончено, описаны объекты задачного типа, то оператор блока не заканчивается до тех пор, пока не будут завершены все его подчиненные задачи (см. 9.4). Это правило применяется также при окончании из-за выполнения операторов выхода, возврата или перехода или из-за возбуждения исключения.

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

Ссылки: возбуждение исключений 11, задачный объект 9.2, обработчик исключений 11.2, оператор возврата 5.8, оператор выхода 5.7, оператор перехода 5.9, подчиненная задача 9.4, последовательность операторов 5.1, простое имя 4.1, раздел описаний 3.9, расширенное имя 4.1.3.

Пред. | Уровень выше | След.
5.5. ОПЕРАТОРЫ ЦИКЛА | Начало | 5.7. ОПЕРАТОРЫ ВЫХОДА


5.7. ОПЕРАТОРЫ ВЫХОДА
Пред. Глава 5. ОПЕРАТОРЫ След.

5.7. ОПЕРАТОРЫ ВЫХОДА

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

оператор-выхода ::=
    exit [ имя-цикла][ when условие];

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

Для выполнения оператора выхода сначала вычисляется условие, если оно есть. Выход из цикла происходит, если значением условия является TRUE или условие отсутствует.

Примеры:

for N in 1 .. MAXJMUMJTEMS loop
   GET_NEW_ITEM(NEW_ITEM);
   MERGE_ITEM(NEW_ITEM, STORAGE_FILE);
   exit when NEW_ITEM = TERMINAL_ITEM;
end loop;

MAIN_CYCLE:
   loop
      -- начальные операторы
      exit MAINCYCLE when FOUND;
      -- заключительные операторы
   end loop MAINCYCLE;

Примечание. Выход из нескольких вложенных циклов можно осуществить с помощью оператора выхода с именем внешнего цикла.

Ссылки: вычисление 4.5, имя цикла 5.5, логическое значение 3.5.3, настраиваемое тело 12.1, оператор принятия 9.5, оператор цикла 5.5, тело пакета 7.1, тело подпрограммы 6.3, условие 5.3.

Пред. | Уровень выше | След.
5.6. ОПЕРАТОРЫ БЛОКА | Начало | 5.8. ОПЕРАТОРЫ ВОЗВРАТА


5.8. ОПЕРАТОРЫ ВОЗВРАТА
Пред. Глава 5. ОПЕРАТОРЫ След.

5.8. ОПЕРАТОРЫ ВОЗВРАТА

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

оператор-возврата ::= return [выражение];

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

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

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

Для выполнения оператора возврата сначала вычисляется выражение (при его наличии) и проверяется принадлежность его значения подтипу результата. При положительном итоге проверки заканчивается вычисление оператора возврата и одновременно подпрограммы или оператора принятия, при отрицательном — в месте оператора возврата возбуждается исключение CONSTRAINT_ERROR.

Примеры:

return;                       -- в процедуре
return KEY_VALUE(LAST_INDEX); -- в функции

Примечание. Если выражение является числовым литералом, именованным числом или атрибутом, который вырабатывает результат типа универсальный-целый или универсальный-вещественный, то выполняется неявное преобразование результата, как описано в разд. 4.6.

Ссыпки: атрибут А, вызов функции 6.4, выражение 4.4, именованное число 3.2, зарезервированное слово 2.9, исключение CONSTRAINT_ERROR 11.1, модуль-задача 9.1, настраиваемое тело 12.1, неявное преобразование типа 4.6, обозначение типа 3.3.2, оператор блока 5.6, оператор принятия 9.5, подтип 3.3, подтип результата 6.1, спецификация подпрограммы 6.1, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, тело процедуры 6.3, тело функции 6.3, универсальный вещественный тип 3.5.6, универсальный целый тип 3.5.4, числовой литерал 2.4.

Пред. | Уровень выше | След.
5.7. ОПЕРАТОРЫ ВЫХОДА | Начало | 5.9. ОПЕРАТОРЫ ПЕРЕХОДА


5.9. ОПЕРАТОРЫ ПЕРЕХОДА
Пред. Глава 5. ОПЕРАТОРЫ След.

5.9. ОПЕРАТОРЫ ПЕРЕХОДА

Оператор перехода определяет явную передачу управления на помеченный меткой оператор.

оператор перехода ::= goto имя-метки;

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

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

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

Пример:

<<COMPARE>>
   if A(l) < ELEMENT then
      if LEFT(I) /= 0 then
         I := LEFT(t);
         goto COMPARE;
      end if;
      -- некоторые операторы
   end if;

Ссылки: метка 5.1, настраиваемое тело 12.1, обработчик исключения 11.2, окружение 11.2, оператор 5.1, оператор блока 5.6, оператор выбора 5.4, оператор отбора 9.7, оператор принятия 9.5, передача управления 5.1, последовательность операторов 5.1, программный модуль 6, составной оператор 5.1, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, условный оператор 5.3.

Пред. | Уровень выше | След.
5.8. ОПЕРАТОРЫ ВОЗВРАТА | Начало | Глава 6. ПОДПРОГРАММЫ


Глава 6. ПОДПРОГРАММЫ
Пред. След.

Глава 6. ПОДПРОГРАММЫ

Содержание

6.1. ОПИСАНИЕ ПОДПРОГРАММЫ
6.2. ВИДЫ ФОРМАЛЬНЫХ ПАРАМЕТРОВ
6.3. ТЕЛА ПОДПРОГРАММ
6.4. ВЫЗОВЫ ПОДПРОГРАММ
6.5. ФУНКЦИИ
6.6. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ
6.7. СОВМЕЩЕНИЕ ОПЕРАЦИЙ

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

Подпрограмма — это программный модуль, выполнение которого инициируется вызовом подпрограммы. Существуют две формы подпрограмм: процедуры и функции. Вызов процедуры — это оператор; вызов функции является выражением. Вызов функции возвращает значение. Определение подпрограммы может состоять из двух частей: описания подпрограммы, определяющего соглашения о ее вызове, и тела подпрограммы, определяющего ее выполнение.

Ссылки: вызов подпрограммы 6.4, вызов процедуры 6.4, вызов функции 6.4, задачный модуль 9, настраиваемый модуль 12, описание подпрограммы 6.1, пакет 7, процедура 6.1, тело подпрограммы 6.3, функция 6.5.

6.1. ОПИСАНИЕ ПОДПРОГРАММЫ

Описание подпрограммы объявляет процедуру или функцию в зависимости от указанного начального зарезервированного слова.

описание-подпрограммы ::= спецификация-подпрограммы;

спецификация - подпрограммы ::=
   procedure идентификатор [раздел-формальных-параметров]
   | function обозначение [раздел-формальных-параметров]
        return обозначение-типа

обозначение ::= идентификатор | знак-операции
знак-операции ::= строковый-литерал

раздел-формальных-параметров ::=
   (спецификация-параметра {; спецификация-параметра})

спецификация-параметра ::=
   список-идентификаторов : вид обозначение-типа [:= выражение]

вид ::= [in] | in out | out

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

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

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

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

Примеры описания подпрограмм:

procedure TRAVERSE_TREE;
procedure INCREMENT(X : in out INTEGER);
procedure RIGHTINDENT(MARGIN : out LINESIZE); -- CM. 3.5.4
procedure SWITCH(FROM, TO : in out LINK); -- CM. 3.8.1

function RANDOM return PROBABILITY; -- CM. 3.5.7
function MINCELL(X : LINK) return CELL; -- CM. 3.8.1
function NEXTFRAME(K : POSITIVE) return FRAME; -- CM. 3.8
function DOTPRODUCT(LEFT,RIGHT: VECTOR) return REAL; -- CM. 3.6

function"*"(LEFT,RIGHT : MATRIX) return MATRIX; -- CM. 3.6

Примеры параметров с выражениями по умолчанию:

procedure PRINT_HEADER( PAGES : in NATURAL;
   HEADER : in LINE := (1 .. LINE'LAST => ' '); -- CM. 3.6
   CENTER : in BOOLEAN := TRUE);

Примечание. Вычисление выражений по умолчанию начинается при определенных вызовах подпрограмм, как пояснено в разд. 6.4.2 (выражения по умолчанию не вычисляются при предвыполнении описания подпрограммы).

Все подпрограммы могут быть вызваны рекурсивно и являются реентерабельными. Ссылки: вид 6.2, вызов подпрограммы 6.4, выражение 4.4, вычисление 4.5, идентификатор 2.3, имя 4.1, обозначение типа 3.3.2, операция 4.5, описание 3.1, Предвыполнение 3.9, пред-выполнение не имеет другого эффекта 3.9, процедура 6, совмещение 6.6, 8.7, список идентификаторов 3.2, строковый литерал 2.6, формальный параметр 6.2, функция 6.5.

Пред. | Уровень выше | След.
5.9. ОПЕРАТОРЫ ПЕРЕХОДА | Начало | 6.2. ВИДЫ ФОРМАЛЬНЫХ ПАРАМЕТРОВ


6.2. ВИДЫ ФОРМАЛЬНЫХ ПАРАМЕТРОВ
Пред. Глава 6. ПОДПРОГРАММЫ След.

6.2. ВИДЫ ФОРМАЛЬНЫХ ПАРАМЕТРОВ

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

Формальный параметр подпрограммы бывает одного из следующих трех видов:

in | Формальный параметр — константа, разрешается только чтение значения соответствующего фактического параметра.
in out | Формальный параметр — переменная, разрешается как чтение, так и изменение значения соответствующего фактического параметра.
out | Формальный параметр — переменная, разрешается изменение значения соответствующего фактического параметра. Значение скалярного параметра, которое не изменяется при вызове, после возврата не определено; то же самое имеет место для значения скалярной подкомпоненты, отличной от дискриминанта. Допускается чтение границ и дискриминантов формального параметра и его подкомпонент; никакое другое чтение не допускается.

Для скалярного параметра такой эффект достигается копированием: в начале каждого вызова значение фактического параметра, соответствующего формальному параметру вида in или in out, копируется в этом формальном параметре (прямое копирование); затем после нормального окончания тела подпрограммы значение формального параметра вида in out или out копируется обратно в соответствующем фактическом параметре (обратное копирование). Для параметра ссылочного типа прямое копирование используется для всех трех видов, а обратное — для видов in out и out.

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

Для параметра личного типа вышеуказанный эффект достигается по правилу, которое применяется к соответствующему полному описанию типа.

В теле подпрограммы формальный параметр отвечает любому ограничению, вытекающему из обозначения типа, данного в спецификации этого параметра. В качестве границ формального параметра неограниченного индексируемого типа берутся границы фактического параметра (см. 3.6.2). Для формального параметра, описание которого задает неограниченный (личный или именуемый) тип с дискриминантами, дискриминанты этого формального параметра инициализируются значениями соответствующих дискриминантов фактического параметра; формальный параметр не ограничен тогда и только тогда, когда его вид in out или out и имя переменной, являющейся фактическим параметром, обозначает неограниченную переменную (см. 3.7.1 и 6.4.1).

Если фактический параметр вызова подпрограммы является подкомпонентой, которая зависит от дискриминантов переменной неограниченного именуемого типа, то выполнение вызова ошибочно, если значение любого дискриминанта переменной изменяется при этом выполнении; это правило не применяется, если вид параметра in и тип подкомпоненты — скалярный тип или ссылочный тип.

Примечание. Из правил передачи параметров индексируемого и именуемого типов следует:

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

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

Такие же виды параметров определены и для формальных параметров входов (см. 9.5) с тем же смыслом, что и для подпрограмм. Для формальных параметров настройки определены другие виды параметров (см. 12.1.1).

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

Ссылки: вид 6.1, выражение 4.4, вычисление 4.5, глобальный 8.1, граница массива 3.6.1, дискриминант 3.7.1, зависеть от дискриминанта 3.7.1, задача 9, задачный тип 9.2, именуемый тип 3.7, индексируемый тип 3.6, исключение 11, личный тип 7.4, неограниченная переменная 3.2.1, неограниченный индексируемый тип 3.6, неограниченный тип с дискриминантами 3.7.1, обозначение типа 3.3.2, объект 3.2, ограничение 3.3, оператор вызова входа 9.5, оператор вызова подпрограммы 6.4, ошибочный 1.6, переменная 3.2.1, подкомпонента 3.3, присваивание 5.2, скалярный тип 3.5, спецификация параметра 6.1, ссылочное значение null 3.8, ссылочный тип 3.8, тело подпрограммы 6.3, фактический параметр 6.4.1, формальный параметр 6.1, формальный параметр настройки 12.1.

Пред. | Уровень выше | След.
Глава 6. ПОДПРОГРАММЫ | Начало | 6.3. ТЕЛА ПОДПРОГРАММ


6.3. ТЕЛА ПОДПРОГРАММ
Пред. Глава 6. ПОДПРОГРАММЫ След.

6.3. ТЕЛА ПОДПРОГРАММ

Тело подпрограммы определяет ее выполнение.

тело-подпрограммы ::=
   спецификация-подпрограммы is
      [раздел - описаний]
   begin
      последовательность-операторов
   [exception
      обработчик - исключения
      {обработчик-исключения}]
   end [обозначение];

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

Если в конце тела подпрограммы присутствует обозначение, то оно должно совпадать с обозначением в спецификации подпрограммы.

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

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

Примечание. Из правил видимости следует, что если описанная в пакете подпрограмма обязана быть видимой вне пакета, то спецификация подпрограммы должна быть дана в видимой части пакета. Эти же правила предписывают, что описание подпрограммы должно быть дано, если вызов подпрограммы возникает текстуально до тела подпрограммы (описание должно помещаться в тексте программы раньше вызова). Данные в разд. 3.9 и 7.1 правила подразумевают, что описание подпрограммы и соответствующее тело должны находиться непосредственно в одной и той же зоне описаний.

Пример тела подпрограммы:

procedure PUSH(E : in ELEMENT.TYPE; S : in out STACK) ) is
begin
   if S.INDEX = S.SIZE then
      raise STACK-OVERFLOW;
   else
      S.INDEX := S.INDEX + 1; S.SPACE(S.INDEX) := E;
   end if;
end PUSH;

Ссылки: видимость 8.3, видимый раздел 7.2, вызов подпрограммы 6.4, зона описаний 8.1, исключение 11, находится непосредственно в 8.1, обозначение 6.1, обработчик исключения 11.2, описание 3.1, описание подпрограммы 6.1, пакет 7, подпрограмма 6, последовательность операторов 5.1, Предвыполнение 3.9, Предвыполнение не имеет другого эффекта 3.1, раздел описаний 3.9, след тела 10.2, согласованный 6.3.1, спецификация подпрограммы 6.1, фактический параметр 6.4.1, формальный параметр 6.1.

6.3.1. ПРАВИЛА СОГЛАСОВАНИЯ

Всякий раз, когда правила языка требуют или допускают появления спецификации данной подпрограммы более одного раза, в каждом месте допустимы следующие вариации:

•Числовой литерал может быть заменен другим числовым литералом тогда и только тогда, когда они имеют одно и то же значение.

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

• Строковый литерал в качестве знака операции может быть заменен на другой строковый литерал тогда и только тогда, когда они представляют одну и ту же операцию (см. 8.5).

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

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

Примечание. Простое имя может быть заменено на расширенное имя, даже если простое имя само является префиксом именуемой компоненты. Например, Q.R может быть заменено на P.Q.R, если. Q описано непосредственно в Р.

Следующие спецификации не согласуются, так как они сформированы различными последовательностями лексем:

procedure P(X.Y : INTEGER)
procedure P(X : INTEGER; Y : INTEGER)
procedure P(X.Y : in INTEGER)

Ссылки: видимость 8.3, допустимый 1.6, знак операции 6.1, именуемая компонента 4.1.3, имя 4.1, комментарий 2.7, лексема 2, непосредственная видимость 8.3, описание 3.1, постфикс 4.1.3, преобразование типа 4.6, префикс 4.1, простое имя 4.1, раздел дискриминантов 3.7.1, раздел формальных параметров 6.1, расширенное имя 4.1.3, совмещение 6.6, 8.7, спецификация подпрограммы 6.1, субконстанта 7.4.3, фактический параметр 6.4, 6.4.1, числовой литерал 2.4.

6.3.2. ПОДСТАНОВКА ПОДПРОГРАММ

Прагма INLINE используется для указания того факта, что для каждого вызова каждого указанного в прагме имени подпрограммы желательна подстановка тела соответствующей подпрограммы. Форма этой прагмы следующая:

pragma INLINE (имя (, имя));

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

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

Смысл подпрограммы не изменяется прагмой INLINE. Для каждого вызова заданных в прагме подпрограмм реализация может выполнять или игнорировать рекомендации прагмы. (Заметим, в частности, что подстановка не может быть выполнена для рекурсивных подпрограмм.)

Ссылки: библиотечный модуль 10.1, вызоё подпрограммы 6.4, допустимый 1.6, имя 4.1, компилируемый модуль 10.1, компиляция 10.1, конкретизация 12.3, настраиваемая подпрограмма 12.1, настраиваемый модуль 12, 12.1, подпрограмма 6, прагма 2.8, раздел описаний 3.9, совмещение 6.6, 8.7, спецификация пакета 7.1, тело подпрограммы 6.3, элемент описания 3.9.

Пред. | Уровень выше | След.
6.2. ВИДЫ ФОРМАЛЬНЫХ ПАРАМЕТРОВ | Начало | 6.4. ВЫЗОВЫ ПОДПРОГРАММ


6.4. ВЫЗОВЫ ПОДПРОГРАММ
Пред. Глава 6. ПОДПРОГРАММЫ След.

6.4. ВЫЗОВЫ ПОДПРОГРАММ

Вызов подпрограммы — это либо оператор вызова процедуры, либо вызов функции; он вызывает выполнение соответствующего тела подпрограммы. Вызов определяет связь фактических параметров, если они есть, с формальными параметрами подпрограммы.

оператор-вызова-процедуры ::=
    имя-процедуры [раздел - фактических - параметров];
вызов функции ::=
    имя-функции [раздел - фактических - параметров]

раздел-фактических-параметров ::=
    (сопоставление-параметров {, сопоставление-параметров})

сопоставление - параметров ::=
    [формальный-параметр =>] фактический-параметр

формальный-параметр ::= простое-имя-параметра

фактический-параметр ::= выражение | имя-переменной
    | обозначение-типа (имя-переменной)

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

Именованные сопоставления могут быть даны в любом порядке, но если в одном и том же вызове использованы позиционные и именованные сопоставления, то позиционные сопоставления должны стоять первыми, на своих местах. Следовательно, после именованного сопоставления все остальные должны быть только именованными сопоставлениями.

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

Сопоставления параметров вызова подпрограммы вычисляются в некотором порядке, не определенном в языке. Аналогично правила языка не определяют, в каком порядке значения параметров вида in out или out копируются обратно в соответствующих фактических параметрах (если это делается).

Примеры вызовов процедур:

TRAVERSE_TREE;                                                   -— СМ. 6.1
TABLE_MANAGER.INSERT(E);                                         -— 7.5
PRINT_HEADER(128, TITLE, TRUE);                                  —- см. 6.1

SWITCH(FROM => X, TO => NEXT);                                   -— CM. 6.1
PRINT_HEADER(128, HEADER => TITLE, CENTER => TRUE);              -— CM. 6.1
PRINT_HEADER(HEADER => TITLE, CENTER => TRUE, PAGES => 128);     -— CM. 6.1

Примеры вызовов функций:

DOTPRODUCT(U, V)     -— см. 6.1 и 6.5
CLOCK                —- см. 9.6

Ссылки: выражение 4.4, выражение по умолчанию для формального параметра 6.1, имя 4.1, обозначение типа 3.3.2, ошибочный 1.6, переменная 3.2.1, подпрограмма 6, простое имя 4.1, раздел формальных параметров 6.1, формальный параметр 6.1.

6.4.1. СОПОСТАВЛЕНИЯ ПАРАМЕТРОВ

Тип каждого фактического параметра должен совпадать с типом соответствующего формального параметра.

Фактический параметр, сопоставляемый с формальным параметром вида in, должен быть выражением; оно вычисляется до вызова.

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

Данное для фактического параметра вида in out или out имя переменной вычисляется до вызова. Если фактический параметр имеет форму преобразования типа, то перед вызовом для параметра вида in out переменная преобразуется к заданному типу; после (нормального) окончания тела подпрограммы формальные параметры вида in out или out преобразуются обратно в тип переменной. (Тип преобразования должен быть тем же, что и у формального параметра.)

Для параметров скалярного и ссылочного типов проверяются следующие ограничения:

• Перед вызовом для параметра вида in или in out проверяется принадлежность фактического параметра подтипу формального параметра.

• После (нормального) окончания тела подпрограммы для параметра вида in out или out проверяется принадлежность значения формального параметра подтипу фактического параметра. В случае преобразования типа значение формального параметра преобразуется обратно и проверяется результат преобразования.

В каждом из вышеуказанных случаев выполнение программы ошибочно, если проверяемое значение неопределено.

Для параметров других типов всех видов проверка осуществляется до вызова, как для скалярных и ссылочных типов; после возврата никаких проверок не делается.

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

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

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

Ссылки: вид 6.1, вызов подпрограммы 6.4, выражение 4.4, вычисление 4.5, вычисление имени 4.1, граница массива 3.6, дискриминант 3.7.1, имя 4.1, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, неограниченный индексируемый тип 3.6, неограниченный тип с дискриминантами 3.7.1, неопределенное значение 3.2.1, обозначение типа 3.8.2, ограничение 3.3, ограниченный подтип 3.3, ошибочный 1.6, переменная 3.2.1, пбдтип 3.3, преобразование типа 4.6, согласованный 6.3.1, сопоставление параметров 6.4, тип 3.3, фактический параметр 6.4, формальный параметр 6.1.

6.4.2. ОПУЩЕННЫЕ ПАРАМЕТРЫ

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

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

Примеры процедур со значениями по умолчанию:

procedure ACTIVATE) PROCESS : in PROCESSNAME;
   AFTER : in PROCESSNAME := NOPROCESS;
   WAIT : in DURATION := 0.0;
   PRIOR : in BOOLEAN := FALSE);

procedure PAIR(LEPT, RIGHT : PERSONNAME := new PERSON);

Примеры их вызовов:

ACTIVATE(X);
ACTIVATE(X, AFTER => Y);
ACTIVATE(X, WAIT => 60.0, PRIOR => TRUE);
ACTIVATE(X, Y, 10.0, FALSE);

PAIR;
PAIR(LEFT => new PERSON, RIGHT => new PERSON);

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

Ссылки: вид 6.1, вызов подпрограммы 6.4, выражение по умолчанию для формального параметра 6.1, вычисление 4.5, именованное сопоставление параметров 6.4, позиционное сопоставление параметров 6.4, спецификация параметра 6.1, фактический параметр 6.1.

Пред. | Уровень выше | След.
6.3. ТЕЛА ПОДПРОГРАММ | Начало | 6.5. ФУНКЦИИ


6.5. ФУНКЦИИ
Пред. Глава 6. ПОДПРОГРАММЫ След.

6.5. ФУНКЦИИ

Функция — это подпрограмма, которая возвращает значение (результат вызова функции). Спецификация функции начинается с зарезервированного слова function, а параметры, если они есть, должны иметь вид in (указанный явно или неявно). Операторы тела функции (исключая операторы программных модулей, вложенных в тело функции) должны содержать один или несколько операторов возврата, -определяющих возвращаемое значение.

Исключение PROGRAM - ERROR возбуждается, если выход из тела функции осуществляется не через оператор возврата. Это исключение не возбуждается, если выполнение функции прекращается в результате исключения.

Пример:

function DOTPRODUCT(LEFT, RIGHT : VECTOR) return REAL is
   SUM : REAL := 0.0;
begin
   CHECK(LEFT'FIRST = RIGHT'FIRST and LEFT'LAST = RIGHT'LAST);
   for J in LEFT'RANGE loop
      SUM := SUM + LEFT(J)*RIGHT(J);
   end loop;
   return SUM;
end DOTPRODUCT;

Ссылки: вид 6.1, возбуждение исключений 11, вызов функции 6.4, исключение 11, исключение PROGRAM_ERROR 11.1, оператор 5, оператор возврата 5.8, спецификация функции 6.1, тело функции 6.3, формальный параметр 6.1, функция 6.1.

Пред. | Уровень выше | След.
6.4. ВЫЗОВЫ ПОДПРОГРАММ | Начало | 6.6. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ


6.6. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ
Пред. Глава 6. ПОДПРОГРАММЫ След.

6.6. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ

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

Один и тот же идентификатор подпрограммы или знак операции может быть использован для нескольких спецификаций подпрограмм. В этом случае идентификатор или знак операции называется совмещенным; подпрограммы, которые имеют этот идентификатор или знак операции, тоже называются совмещенными и, следовательно, могут совмещаться друг с другом. Как поясняется в разд. 8.3, если две подпрограммы совмещаются друг с другом, то одна из них может скрыть другую, только если обе подпрограммы имеют одинаковый профиль типа параметров и результата [6] (см. 8.3, где описаны другие требования, необходимые для скрытия).

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

Примеры совмещенных подпрограмм:

procedure PUT(X : INTEGER»;
procedure PUT(X : STRING);
procedure SET(TINT : COLOR);
procedure SET(SIGNAL : LIGHT);

Примеры вызовов:

PUT(28);
PUT("no possibte ambiguity here");
SET(TINT   => RED»:
SET(SIGNAL => RED);
SET(COLOR'(RED));

-- SET (RED) может быть неоднозначным, так как
-- может обозначать значение типа COLOR и типа

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

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

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

Ссылки: агрегат 4.3, базовый тип 3.3, вид 6.1, вход 9.5, вызов функции 6.4, выражение по умолчанию для формального параметра 6.1, знак операции 6.1, идентификатор 2.3, именованное сопоставление параметров 6.4, квалифицированное выражение 4.7, литерал 4.2, неправильный 1.6, описание переименования 8.5, пакет 7, параметр подпрограммы 6.2, подпрограмма 6, подтип 3.3, подтип результата 6.1, скрытие 8.3, совмещение 8.7, спецификация подпрограммы 6.1, тип 3.3, фактический параметр 6.4.1, формальный параметр 6.1, функция 6.5.

[6] 1) Имеется в виду, что обе подпрограммы имеют разные зоны описания. - Прим. ред.

Пред. | Уровень выше | След.
6.5. ФУНКЦИИ | Начало | 6.7. СОВМЕЩЕНИЕ ОПЕРАЦИЙ


6.7. СОВМЕЩЕНИЕ ОПЕРАЦИЙ
Пред. Глава 6. ПОДПРОГРАММЫ След.

6.7. СОВМЕЩЕНИЕ ОПЕРАЦИЙ

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

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

Операции + и - допускают как унарную, так и бинарную совмещенную операцию.

Явное описание функции, которая совмещает операцию =, отличное от описания переименования, допустимо, только если оба параметра являются параметрами одного и того же лимитируемого типа. Совмещение равенства должно давать результат предопределенного типа BOOLEAN; операция неравенства /=, дающая результат, дополнительный к результату операции равенства, совмещается неявно при задании операции равенства. Явное совмещение операции неравенства недопустимо.

Описание переименования, обозначение которого — операция равенства, допустимо только для переименования другой операции равенства. (Например, такое описание переименования может быть использовано, когда равенство видимо по имени, но не непосредственно.)

Примечание. Совмещение операций отношения не нарушает соотношений, таких как проверка вхождения в диапазон или выборы в операторе выбора.

Примеры:

function "+" (LEFT, RIGHT : MATRIX) return MATRIX;
function "+" (LEFT, RIGHT : VECTOR) return VECTOR;

-- в предположении, что А, В и С типа VECTOR
-- три следующих присваивания эквивалентны

А := B + С;

А := "+"(В, С);
А := "+"(LEFT => В, RIGHT => С);

Ссылки: бинарная аддитивная операция 4.5, 4.5.3, видимый по именованию 8.3, выражение по умолчанию для формального параметра 6.1, дополнительный результат 4.5.2, допустимо 1.6, знак операции 6.1, лимитируемый тип 7.4.4, логическая операция 4.5, 4.5.1, логический предопределенный тип 3.5.3, мультипликативная операция 4.5, 4.5.5, непосредственно видимо 8.3, неявное описание 3.1, обозначение 6.1, операция 4.5, операция высшего приоритета 4.5, 4.5.6, операция неравенства 4.5.2, операция отношения 4.5, 4.5.2, операция равенства 4.5, описание 3.1, описание функции 6.1, определение типа 3.3.1, проверка вхождения 4.5, 4.5.2, символ 2.1, совмещение 6.6, 8.7, унарная аддитивная операция 4.5, 4.5.4, фактический параметр 6.4.1, форма управления с промежуточной проверкой 4.5, 4.5.1, формальный параметр 6.1.

Пред. | Уровень выше | След.
6.6. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ | Начало | Глава 7. ПАКЕТЫ


Глава 7. ПАКЕТЫ
Пред. След.

Глава 7. ПАКЕТЫ

Содержание

7.1. СТРУКТУРА ПАКЕТА
7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ
7.3. ТЕЛА ПАКЕТОВ
7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ
7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ
7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ

Пакеты — это одна из четырех форм программных модулей, из которых составляются программы. Другие формы — это подпрограммы, задачные модули и настраиваемые модули.

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

Ссылки: задачный модуль 9, настраиваемый модуль 12, описание типа 3.3.1, подпрограмма 6, программный модуль 6.

7.1. СТРУКТУРА ПАКЕТА

Пакет обычно представлен двумя частями: спецификацией пакета и телом пакета. Спецификация имеется у каждого пакета, а тело имеют не все пакеты.

описание-пакета ::= спецификация-пакета;

спецификация -пакета ::=
   package идентификатор is
      {основной-элемент-описания}
   [private
      {основной-элемент-описания)]
   end [простое-имя-пакета]

тело-пакета ::=
   package body простое-имя-пакета is
      [раздел - описаний]
   [begin
      последовательность-операторов
   [exception
      обработчик-исключения
      {обработчик-исключения}]]
   end [простое-имя-пакета];

Простое имя в начале тела пакета должно совпадать с идентификатором этого пакета. Аналогично если простое имя помещено в конце спецификации или тела пакета, то оно должно совпадать с идентификатором этого пакета.

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

Примечание. Для простой формы пакета, специфицирующей совокупность объектов и типов, тело не обязательно. Одной из возможностей использования последовательности операторов тела пакета является инициализация таких объектов. Для каждого описания подпрограммы должно существовать соответствующее тело (за исключением подпрограмм, написанных на другом языке, см. 13.9). Если тело программного модуля является следом тела, то для этого программного модуля требуется раздельно компилируемый субмодуль, содержащий соответствующее тело (см. 10.2). Тело не является основным элементом описания и, таким образом, не может присутствовать в спецификации пакета.

Описание пакета — это либо библиотечный пакет (см. 10.2), либо элемент описания внутри другого программного модуля.

Ссылки: библиотечный модуль 10.1, идентификатор 2.3, настраиваемое тело 12.2, обработчик исключения 11.2, объект 3.2, описание задачи 9.1, описание настройки 12.1, описание подпрограммы 6.1, основной элемент описания 3.9, последовательность операторов 5.1, программный модуль 6, простое имя 4.1, раздел описаний 3.8, след тела 10.2, соответствующее тело 3.9, субмодуль 10.2, тело задачи 9.1, тело пакета 7.3, тело подпрограммы 6.3, тип 3.3, элемент описания 3.9.

Пред. | Уровень выше | След.
6.7. СОВМЕЩЕНИЕ ОПЕРАЦИЙ | Начало | 7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ


7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ
Пред. Глава 7. ПАКЕТЫ След.

7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ

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

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

Предвыполнение описания пакета состоит в предвыполнении его основных элементов описания в порядке их следования.

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

Пример пакета, описывающего группу общих переменных:

package PLOTTING_DATA is
   PEN_UP : BOOLEAN;

   CONVERSION_FACTOR,
   X_OFFSET, Y_OFFSET,
   X_MIN,    Y_MIN,
   X_MAX,    Y_MAX:   REAL;     -— CM. 3.5.7

   X_VALUE : array (1 .. 500) of REAL;
   Y_VALUE : array (1 .. 500) of REAL;
end PLOTTING-DATA;

Пример пакета, описывающего общую совокупность объектов и типов:

package WORK_DATA is

   type DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);
   type HOURS_SPENT is delta 0.25 range 0.0 .. 24.0;
   type TIME_TABLE  is array (DAY) of HOURS_SPENT;

   WORK_HOURS   : TIME_TABLE;

   NORMAL_HOURS : contant TIME_TABLE :=
                   (MON .. THU => 8.25, FRI ==> 7.0, SAT | SUN => 0.0>;
end WORK_DATA;

Ссылки: идентификатор пакета 7.1, имя 4.1, константа 3.2.1, область действия 8.2, описание объекта 3.2.1, описание пакета 7.1, описание типа 3.3.1, описание числа 3.2.2, основной элемент описания 3.9, пакет 7, переменная 3.2.1, Предвыполнение 3.9, простое имя 4.1, прямая видимость 8.3, расширенное имя 4.1.3, спецификатор использования 8.4, спецификация пакета 7.1, элемент описания 3.9.

Пред. | Уровень выше | След.
Глава 7. ПАКЕТЫ | Начало | 7.3. ТЕЛА ПАКЕТОВ


7.3. ТЕЛА ПАКЕТОВ
Пред. Глава 7. ПАКЕТЫ След.

7.3. ТЕЛА ПАКЕТОВ

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

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

Примечание. Переменная, описанная в теле пакета, видима только внутри этого тела, и, следовательно, ее значение может быть изменено только внутри этого тела пакета. В отсутствие локальных задач значение такой переменной сохраняется неизменным между вызовами извне пакета подпрограмм, описанных в его видимом разделе. Свойства такой переменной аналогичны свойствам «собственной» переменной в языке Алгол-60.

Предвыполнение тела подпрограммы, описанной в видимом разделе пакета, осуществляется при предвыполнении тела пакета. Следовательно, при вызове такой подпрограммы извне программного модуля возбуждается исключение PROGRAM-ERROR, если вызов производится до предвыполнения тела пакета (см. 3.9).

Пример пакета:

package RATIONAL-NUMBERS is

   type RATIONAL is
      record
         NUMERATOR   : INTEGER;
         DENOMINATOR : POSITIVE;
      end record;

   function EQUAL (X,Y  RATIONAL) return BOOLEAN;

   function "/"    (X,Y  INTEGER) return RATIONAL; —- для образования рационального числа

   function "+"    (X,Y  RATIONAL) return RATIONAL;
   function "-"    (X,Y  RATIONAL) return RATIONAL;
   function "*"    (X,Y  RATIONAL) return RATIONAL;
   function "/"    (X,Y  RATIONAL) return RATIONAL;

end;

package body RATIONAL-NUMBERS is

   procedure SAME-DENOMINATOR (X,Y : in out RATIONAL) is
   begin
      -- приведение Х и Y к общему знаменателю;
   end;

   function EQUAL(X,Y : RATIONAL) return BOOLEAN is
      U,V : RATIONAL;
   begin
      U := X;
      V := Y;
      SAME-DENOMINATOR (U,V);
      return ENUMERATOR = V.NUMERATOR;
   end EQUAL;

   function "/" (X,Y : INTEGER) return RATIONAL is
   begin
      if Y > 0 then
         return (NUMERATOR => X, DENOMINATOR => Y);
      else
         return (NUMERATOR => -X, DENOMINATOR => -Y);
      end if;
   end"/";

   function "+" (X,Y  RATIONAL) return RATIONAL is ... end "+";
   function "-" (X,Y  RATIONAL) return RATIONAL is ... end "-";
   function "*" (X,Y  RATIONAL) return RATIONAL is ... end "*";
   function "/" (X,Y  RATIONAL) return RATIONAL is ... end "/";

end RATIONAL_NUMBERS;

Ссылки: видимый раздел 7.2, имя 4.1, исключение 11, исключение PROGRAM-ERROR 11.1, ДЮЗ обработчик исключения 11.1, описание 3.1, переменная 3.2.1, подпрограмма б, последовательность операторов 5.1, Предвыполнение 3.1, 3.9, .программный модуль 6, раздел описаний 3.9, спецификация пакета 7.1.

Пред. | Уровень выше | След.
7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ | Начало | 7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ


7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ
Пред. Глава 7. ПАКЕТЫ След.

7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ

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

описание-личного-типа ::=
   type идентификатор [раздел-дискриминантов] is [limited] private;

описание-субконстанты ::=
   список-идентификаторов : constant обозначение-типа;

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

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

Примеры описаний личного типа:

type KEY is private;
type FILENAME is limited private;

Пример описания субконстанты:

NULLKEY : constant KEY;

Ссылки: видимый раздел 7.2, идентификатор 2.3, константа 3.2.1, лимитируемый тип 7.4.4, личный тип 7.4.1, обозначение типа 3.3.2, описание 3.1, описание параметра настройки 12.1, пакет 7, подтип 3.3, программный модуль 6, раздел дискриминанта 3.7.1, раздел формальных параметров настройки 12.1, список идентификаторов 3.2, тип 3.3, формальный тип настройки 12.1, элемент описания 3.9.

7.4.1. ЛИЧНЫЕ ТИПЫ

Если описание личного типа дается в видимом разделе пакета, то соответствующее описание типа с тем же самым идентификатором должно присутствовать в качестве элемента описания в личном разделе пакета. Соответствующее описание должно быть либо полным описанием типа, либо описанием задачного типа. В оставшейся части этого раздела объяснения даются для полных описаний типов. Те же правила применяются к описаниям задачных типов.

Описание личного типа и соответствующее полное описание типа определяют один тип. Описание личного типа вместе с видимым разделом определяет операции, которые могут использовать внешние программные модули (см. 7.4.2). С другой стороны, полное описание типа определяет другие операции, непосредственное использование которых возможно только внутри самого пакета.

Если описание личного типа включает раздел дискриминантов, то полное описание типа должно включать раздел дискриминантов по правилам согласования (см. 6.3.1) и определением типа должно быть определение именуемого типа. И наоборот, если описание личного типа не включает раздела дискриминантов, то тип, описанный с помощью полного описания типа {полный тип), не должен быть неограниченным типом с дискриминантами. Полный тип не должен быть неограниченным индексируемым типом. Лимитируемый тип (в частности, задач-ный тип) допускается в качестве полного типа, только если в описании личного типа присутствует зарезервированное слово limited (см. 7.4.4).

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

При предвыполнении описания личного типа создается личный тип. Если описание личного типа имеет раздел дискриминантов, то он также предвыполняется. Предвыполнение полного описания типа заключается в предвыполнении определения типа; если имеется раздел дискриминантов, то он не предвыполняется (так как уже предвыполнен согласованный раздел дискриминантов в описании личного типа).

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

Ссылки: видимый раздел 7.2, выражение 4.4, генератор 4.8, зарезервированное слово 2.9, идентификатор 2.3, имя 4.1, индексируемый тип 3.6, конкретизация настройки 12.3, лимитируемый тип 7.4.4, личный раздел 7.2, личный тип 7.4, неограниченный индексируемый тип 3.6, неполное описание типа 3.8.1, операция 3.3, описание входа 9.5, описание личного типа 7.4, описание подтипа 3.3.2, описание субконстанты 7.4.3, описание типа 3.3.1, определение именуемого типа 3.7, определение типа 3.3.1, пакет 7, переменная 3.2.1, подкомпонента 3.3, подтип 3.3, полное описание типа 3.3.1, Предвыполнение 3.9, производный тип 3.4, раздел дискриминанта 3.7.1, согласованный 6.3.1, спецификатор представления 13.1, спецификация пакета 7.1, спецификация подпрограммы 6.1, тип 3.3, элемент описания 3.9.

7.4.2. ОПЕРАЦИИ НАД ЛИЧНЫМ ТИПОМ

Операции, которые неявно описаны введением описания личного типа, включают базовые операции: присваивание (кроме лимитируемого типа), проверку принадлежности, квалификацию, явное преобразование и именование компоненты для какого-либо дискриминанта. минанта.

Для личного типа Т в базовые операции также входят атрибуты Т'BASE (см. 3.3.3) и T'SIZE (см. 13.7.2). Для объекта А личного типа в базовые операции включается атрибут A'CONSTRAINED, если личный тип содержит дискриминант (см. 3.7.4), и во всех случаях — атрибуты A'SIZE и A'ADDRESS (см. 13.7.2).

Наконец, операции, неявно описанные описанием личного типа, включают предопределенные отношения равенства и неравенства (кроме личных типов, в описании которых присутствует зарезервированное слово limited).

Рассмотренные выше операции вместе с подпрограммами, которые имеют параметр или результат личного типа и описаны в видимом разделе пакета, являются единственными операциями над .личным типом, используемыми вне пакета.

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

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

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

Те же правила относятся к неявно описанным для ссылочного типа операциям, чье обозначение типа есть личный тип или тип, описанный посредством неполного описания типа.

Для каждого личного типа или полтипа Т определен следующий атрибут:

T'CONSTRAINED | Вырабатывает значение FALSE, если Т обозначает неограниченный неформальный личный тип с дискриминантами, не являющийся формальным параметром настройки; вырабатывает также значения FALSE, если Т обозначает личный тип, являющийся формальным параметром настройки, а соответствующий подтип фактического параметра является либо неограниченным типом с дискриминантом, либо неограниченным индексируемым типом; в остальных случаях вырабатывает значение TRUE. Значение атрибута имеет предопределенный тип BOOLEAN.

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

Последствия такой фактической реализации сказываются тем не менее везде. Например, производится некоторая инициализация компонент по умолчанию; атрибут SIZE вырабатывает раз'мер полного типа; правила зависимости задач распространяются также на компоненты — объекты задачного типа.

Пример:

package KEY_MANAGER is
   type KEY is private;
   NULL_KEY : constant KEY;
   procedure GET_KEY(K : out KEY);
   function "<" (X, Y : KEY) return BOOLEAN:
private
   type KEY is new NATURAL:
   NULLKEY : constant KEY := 0;
end;

package body KEY_MANAGER is
   LAST_KEY : KEY := 0;
   procedure GET_KEY(K : out KEY) is
   begin
      LAST_KEY := LAST_KEY + 1;
      К := LAST_KEY;
   end GET_KEY;

   function "<" (X. Y : KEY) return BOOLEAN is
   begin
      return INTEGER(X) < INTEGER(Y);
   end "<";
end KEY_MANAGER;

Примечание к примеру: Операциями, применимыми к объектам типа KEY вне пакета KEY MANAGER являются: присваивание, сравнение на равенство и неравенство, процедура GET_KEY и операция "<"; сюда не включаются другие операции отношения, например >= или арифметические операции.

Явно описанная операция " <" скрывает предопределенную операцию < , неявно опи_ санную полным описанием типа. В теле функции необходимо явное преобразование Х и Y к типу INTEGER для явного вызова операции "<" над этим типом. С другой стороны результат функции мог бы быть записан в виде not(X > = Y), так как операция " > = не переопре-

Значение переменной LAST_KEY, описанной в теле пакета, не меняется между вызовами процедуры GET_KEY (см. также примечание к разд. 7.3).

Ссылки- атрибут 4.1.4, базовая операция 3.3.3, видимый раздел 7.2, дискриминант 3.3, зависимость задач 9.4, именованная компонента 4.1.3, квалификация 4.7, компонента 3.3, контроль принадлежности 4.5, личный тип 7.4, неполное описание типа 3.8.1, непосредственная область действия 8.2, неявное описание 3.1, область описания 8.1, основная операция 3.3.3, операция 3.3, операция отношения 4.5, описание 3.1, описание личного типа 7.4, пакет 7, параметр подпрограммы 6.2, подпрограмма 6, полное описание типа 3.3.1, полный тип 7.4.1, предопределенная операция 4.5, предопределенная функция 8.6, преобразование 4.6, присваивание 5.2, программный модуль 6, производная подпрограмма 3.4, производный тип 3.4, равенство 4.5.2, размерность 3.6, скрытие 8.3, составной тип 3.3.

7.4.3. СУБКОНСТАНТЫ

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

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

Предвыполнение описания субконстанты не дает другого эффекта.

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

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

Ссыпки: видимый раздел 7.2, выражение по умолчанию для дискриминанта 3.7.1, идентификатор 2.3, именуемая компонента 3.7, личный раздел 7.2, обозначение типа 3.3.2, описание константы 3.2.1, описание объекта 3.2.1, описание субконстанты 7.4, пакет 7, Предвыполнение не дает другого эффекта 3.1, согласованный 6.3.1, спецификация пакета 7.1, субконстанта 7.4, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3, элемент описания 3.9.

7.4.4. ЛИМИТИРУЕМЫЕ ТИПЫ

Лимитируемый тип — это тип, для которого неявным описанием не вводится ни присваивание, ни сравнение на равенство и неравенство.

Описание личного типа с зарезервированным словом limited описывает лимитируемый тип. Задачный тип является лимитируемым типом. Производный тип от лимитируемого типа сам является лимитируемым типом. Наконец, составной тип является лимитируемым, если тип одной из его компонент является лимитируемым.

Над личным лимитируемым типом определены операции, которые даны в разд. 7.4.2, за исключением присваивания и предопределенного сравнения на равенство и неравенство.

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

Из правил для лимитируемых типов вытекает следующее:

• Если тип объекта является лимитируемым, то в описании этого объекта явная инициализация недопустима.

• Если тип именуемой компоненты является лимитируемым, то выражение по умолчанию в описании компоненты недопустимо.

• Если тип объекта, указанного ссылочным типом, является лимитируемым, то в генераторе явная инициализация недопустима.

• Формальный параметр настройки вида in не должен быть лимитируемого типа. Примечание. Описанные выше правила не исключают выражение по умолчанию для формального параметра лимитируемого типа; они не исключают также субконстанту лимитируемого типа, если полный тип не является лимитируемым. Для лимитируемого типа допускается явное описание операции равенства (см. 6.7).

Для лимитируемого составного типа не разрешаются агрегаты (см. 3.6.2 и 3.7.4). Для лимитируемого индексируемого типа не разрешается катенация (см. 3.6.2).

Пример:

package I_O_PACKAGE is
   type FILE_NAME is limited private;

   procedure OPEN (F   in out FILE_NAME);
   procedure CLOSE (F   in out FILE_NAME);
   procedure READ (F   in FILE_NAME; ITEM : out INTEGER);
   procedure WRITE (F   in FILE_NAME; ITEM : in  INTEGER);
private
   type FILE_NAME is
      record
         INTERNAL_NAME : INTEGER := 0;
      end record;
end I_0_PACKAGE;

package body I_0_PACKAGE is
   LIMIT : constant := 200;
   type FILE_DESCRIPTOR is record ... end record;
   DIRECTORY : array (1 .. LIMIT) of P1LE_DESCRIPTOR;
   ...
   procedure OPEN (F   in out FILE_NAME) is ... end;
   procedure CLOSE (F   in out FILEJMAME) Is ... end;
   procedure READ (F  in FILE_NAME; ITEM : out INTEGER) is ... end:
   procedure WRITE (F  in FILEJMAME; ITEM : in   INTEGER) Is ... end;
begin
   ...
end I_O_PACKAGE;

Примечание к примеру. В приведенном примере для внешних подпрограмм, использующих !_ О-PACKAGE, имя файла можно получить в результате вызова процедуры OPEN, а затем использовать его в вызовах процедур READ и WRITE. Следовательно, вне пакета имя файла, полученное после вызова процедуры OPEN, выполняет функцию пароля; его внутренние свойства (например, содержать числовое значение) неизвестны, и никакие другие операции (такие как сложение или сравнение внутренних имен) над этим именем не могут выполняться.

Этот пример характерен для тех случаев, когда желателен полный контроль над операциями. Такие пакеты служат двум целям: они препятствуют пользователю в использовании внутренней структуры типа, а также реализуют понятие упрятывания (скрытия) типа данных, для которых определены только заданные в спецификации пакета операции.

Ссылки: агрегат 4.3, вид 12.1.1, выражение по умолчанию для дискриминанта 3.7, генератор 4.8, задачный тип 9.1, 9.2, именуемая компонента 3.7, именуемый тип 3.7, личный тип 7.4, начальное значение 3.2.1, неявное описание 3.1, обозначает 3.8, объект 3.2, операция 3.3, операция катенации 4.5, операция отношения 4.5, описание компоненты 3.7, описание личного типа 7.4. пакет 7, подкомпонента 3.3, подпрограмма 6, полное описание типа 3.3.1, полный тип 7.4.1, предопределенная операция 4.5, присваивание 5.2, производный тип 3.4, равенство 4.5.2, составной тип 3.3, спецификация дискриминанта 3.7.1, субконстанта 7.4.3, тип 3.3, тип компоненты 3.3, формальный параметр 6.1, формальный параметр настройки 12.1, 12.3.

Пред. | Уровень выше | След.
7.3. ТЕЛА ПАКЕТОВ | Начало | 7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ


7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ
Пред. Глава 7. ПАКЕТЫ След.

7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ

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

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

С точки зрения пользователя, пакет чрезвычайно прост. Существует тип с именем ITEM — тип элемента таблицы, есть процедура INSERT для включения элементов в таблицу и процедура RETRIEVE для извлечения элемента с наименьшим порядковым номером. Если таблица пуста, то возвращается специальный элемент NULL-ITEM, а если таблица заполнена, то при выяпяй nnniiftnvnki INRFRT по.чЛужляйтся искпючание TABLE _FULL-

Ниже приведена схема такого пакета. Пользователю известна только спецификация пакета.

package TABLE_MANAGER is

   type ITEM is
      record
         ORDER_NUM   : INTEGER;
         ITEM_CODE   : INTEGER;
         QUANTITY    : INTEGER;
         ITEM-TYPE   : CHARACTER;
      end record;

   NULL-ITEM : constant ITEM :=
      (ORDER_NUM | ITEM_CODE | QUANTITY => 0, ITEM_TYPE => ' ');

  procedure INSERT (NEWJTEM : in ITEM);
  procedure RETRIEVE (FIRSTJTEM : out ITEM);

  TABLE_FULL : exception; -— это исключение возбуждается в процедуре
end;                      -— INSERT, если таблица заполнена

Детали реализации таких пакетов могут быть достаточно сложными; в данном случае используются двусвязные списки внутренних элементов. Локальная вспомогательная процедура EXCHANGE используется для перемещения внутренних элементов из списка занятых в список свободных. Начальные связи таблицы устанавливаются в разделе инициализации. Нет необходимости показывать пользователям тело пакета.

package body TABLE_MANAGER is
   SIZE : constant := 2000;
   subtype INDEX is INTEGER range 0 .. SIZE;

   type INTERNAL-ITEM is
      record
         CONTENT : ITEM;
         SUCC    : INDEX;
         PRED     : INDEX;
      end record;

   TABLE : array (INDEX) of INTERNAL-ITEM;
   FIRST_BUSY_ITEM : INDEX := 0;
   FIRST_FREE_ITEM : INDEX := 1;
   function FREE_LIST_EMPTY return BOOLEAN is ... end;
   function BUSY_LIST_EMPTY return BOOLEAN is ... end;
   procedure EXCHANGE (FROM : in INDEX; TO : in INDEX) is ... end;

   procedure INSERT (NEWJTEM : in ITEM) is
   begin
      if FREE_LIST_EMPTY then
         raise TABLE_FULL;
      end if;
      -— остальная часть кода подпрограммы INSERT
   end INSERT;

   procedure RETRIEVE (FIRSTJTEM : out ITEM) is ... end;

begin
   -— инициализация связей таблицы
end TABLE_MANAGER;

Пред. | Уровень выше | След.
7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ | Начало | 7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ


7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ
Пред. Глава 7. ПАКЕТЫ След.

7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ

Этот пример иллюстрирует простой пакет обработки текстов. Пользователи имеют доступ только к видимому разделу; реализация от них скрыта в личном разделе и теле пакета (тело не показано).

С точки зрения пользователя, TEXT является строкой переменной длины. Каждый текстовый объект имеет максимальную длину, которая должна задаваться при описании этого объекта, и текущую длину, которая равна длине в диапазоне от нуля до максимального. Максимальная возможная длина текстового объекта является константой, определяемой реализацией.

Сначала в пакете определяются необходимые типы, затем функции, возвращающие некоторые характеристики объектов типа, затем функции преобразования текстов и предопределенных типов CHARACTER и STRING и, наконец, некоторые стандартные операции над переменными строками. Большинство операций над строками, символами, а также над типом TEXT совмещены для минимизации числа явных преобразований, которые должен написать пользователь.

package TEXT_HANDLER is
   MAXIMUM : constant := SOME_VALUE; -— это значение определено реализацией
   subtype INDEX it INTEGER range 0 .. MAXIMUM;

   type TEXT(MAXIMUM_LENGTH : INDEX) is limited private;

   function LENGTH (T TEXT) return INDEX;
   function VALUE   (T  TEXT) return STRING;
   function EMPTY   (T TEXT) return BOOLEAN;

   function TO_TEXT (S STRING;    MAX : INDEX) return TEXT; -- максимальная длина МАХ
   function TO_TEXT (С CHARACTER; MAX : INDEX) return TEXT;
   function TO_TEXT (S  STRING)     return TEXT; - - максимальная длина S'LENGTH
   function TO_TEXT (C  CHARACTER) return TEXT;

   function "&" (LEFT : TEXT;       RIGHT TEXT)        return TEXT;
   function "&" (LEFT : TEXT;       RIGHT  STRING)     return TEXT;
   function "&" (LEFT : STRING;     RIGHT TEXT)        return TEXT;
   function "&" (LEFT : TEXT;       RIGHT CHARACTER) return TEXT;
   function "&" (LEFT : CHARACTER; RIGHT TEXT)       return TEXT;

   function "="  (LEFT : TEXT; RIGHT TEXT) return BOOLEAN;
   function "<"   (LEFT : TEXT; RIGHT TEXT) return BOOLEAN;
   function "<=" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN;
   function ">"  (LEFT : TEXT; RIGHT TEXT) return BOOLEAN;
   function ">=" (LEFT : TEXT; RIGHT TEXT) return BOOLEAN;

   procedure SET (OBJECT ; in out TEXT; VALUE : In TEXT);
   procedure SET (OBJECT : In out TEXT; VALUE : In STRING);
   procedure SET (OBJECT : In out TEXT; VALUE : in CHARACTER);

   procedure APPEND (TAIL : In TEXT;        TO  In out TEXT);
   procedure APPEND (TAIL : in STRING;      TO  In out TEXT);
   procedure APPEND (TAIL : In CHARACTER; TO  in out TEXT);

   procedure AMEND (OBJECT  in out TEXT; BY  In TEXT;       POSITION : In INDEX);
   procedure AMEND (OBJECT in out TEXT; BY  In STRING;     POSITION : In INDEX);
   procedure AMEND (OBJECT In out TEXT; BY  In CHARACTER; POSITION : In INDEX);

   -— заменяет часть объекта с заданной позиции на данный
   -— текст, строку или символ

   function LOCATE (FRAGMENT : TEXT;       WITHIN : TEXT) return INDEX;
   function LOCATE (FRAGMENT : STRING;     WITHIN : TEXT) return INDEX;
   function LOCATE (FRAGMENT : CHARACTER; WITHIN : TEXT) return INDEX;

   —- возвращают значение О, если фрагмент не размещается

private
   type TEXT(MAXIMUM_LENGTH : INDEX) is
      record
         POS   : INDEX := 0;
         VALUE : STRING(1 .. MAXIMUM_LENGTH);
      end record;

end TEXT-HANDLER;

Пример использования пакета обработки текста:

Программа открывает файл вывода, имя которого дается строкой NAME. Эта строка имеет вид

[УСТРОЙСТВО :] [ИМЯ ТИПА [.РАСШИРЕНИЕ]]

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

function EXPAND_FILE_NAME (NAME : STRING) return STRING is
   use TEXT_HANDLER;

   DEFAULT_DEVICE     : constant STRING = "SY:";
   DEFAULT_FILE_NAME  : constant STRING = "RESULTS";
   DEFAULT_EXTENSION  : constant STRING = ".DAT";

   MAXIMUM_FILE_NAME_LENGTH : constant INDEX := SOME_APPROPRIATE_VALUE:
   FILE_NAME : TEXT(MAXIMUM_FILE_NAME_LENGTH);

begin
   SET(FILE_NAME, NAME);
   if EMPTY(FILE_NAME) then
      SET(FILE_NAME, DEFAULT_FILE_NAME);
   end if;

   if LOCATEC:', FILE_NAME) = 0 then
      SET(FILE_NAME, DEFAULT_DEVICE & FILE_NAME);
   end if;

   if LOCATE('.', FILE_NAME) = 0 then
      APPEND(DEFAULT_EXTENSION, TO => FILE_NAME);
   end if;

   return VALUE(FILE_NAME);

end EXPAND_FILE_NAME;

Пред. | Уровень выше | След.
7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ | Начало | Глава 8. ПРАВИЛА ВИДИМОСТИ


Глава 8. ПРАВИЛА ВИДИМОСТИ
Пред. След.

Глава 8. ПРАВИЛА ВИДИМОСТИ

Содержание

8.1. ЗОНА ОПИСАНИЯ
8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ
8.3. ВИДИМОСТЬ
8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ
8.6. СТАНДАРТНЫЙ ПАКЕТ
8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ

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

Ссылки: видимость 8.3, зона описания 8.1, идентификатор 2.3, область 8.2, описание 3.1.

8.1. ЗОНА ОПИСАНИЯ

Зона описания является частью текста программы. Единичная зона описания — это:

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

• Описание входа с соответствующими операторами принятия.

• Описание именуемого типа с соответствующими описанием личного типа или неполным описанием типа (если они есть) и спецификатором представления записи (если он есть).

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

•Оператор блока или оператор цикла.

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

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

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

Примечание. Как определено в разд. 3.1, в термин описание включаются основные описания, неявные описания и описания, являющиеся разделом основных описаний, например спецификации дискриминантов и параметров. Из определения зоны описания следует, что спецификация дискриминанта находится непосредственно в зоне, связанной с охватывающим описанием именуемого типа. Аналогично спецификация параметра находится непосредственно в зоне, связанной с телом охватывающей подпрограммы или с оператором принятия.

Пакет STANDARD образует зону описания, которая охватывает все библиотечные модули; предполагается, что неявное описание каждого библиотечного модуля находится непосредственно в этом пакете (см. разд. 8.6 и 10.1.1).

Зоны описания могут быть вложены в другие зоны описания. Например, подпрограммы, пакеты, задачные модули, настраиваемые модули и операторы блока могут быть вложены друг в друга и содержать описания именуемого типа, оператор цикла, а также операторы принятия.

Ссылки: библиотечный модуль 10.1, задачный модуль 9, именуемый тип 3.7, настраивав-1 мое тело 12.2, неполное oni-ср.ние типа 3.8.1, неявное описание 3.1, оператор блока 5.6, оператор принятия 9.5, оператор цикла 5.5, описание 3.1, описание входа 9.5, описание задачи 9.1, описание личного типа 7.4, описание настройки 12.1, описание пакета 7.1, описание параметров настройки 12.1, описание переименования 8.5, описание подпрограммы 6.1, основное описание 3.1, пакет 7, раздел дискриминантов 3.7.1, раздел формальных параметров 6.1, след тела 10.2, спецификатор представления записи 13.4, спецификация дискриминанта 3.7.1, спецификация параметра 6.1, стандартный пакет 8.6, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3.

Пред. | Уровень выше | След.
7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ | Начало | 8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ


8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ
Пред. Глава 8. ПРАВИЛА ВИДИМОСТИ След.

8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ

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

Область действия описания, находящегося непосредственно в зоне описания, распространяется от начала описания до конца зоны описания; этот раздел области действия описания называется непосредственной областью действия. Более того, для любого из описаний, перечисленных ниже, область действия описания распространяется за пределы непосредственной области действия:

а) описание, которое находится непосредственно в видимом разделе описания пакета;

б) описание входа;

в) описание компоненты;

г) спецификация дискриминанта;

д) спецификация параметра;

е) описание параметра настройки.

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

При отсутствии описания подпрограммы спецификация подпрограммы, заданная в теле подпрограммы или в следе тела, действует как описание, и в этом случае применимо правило Д).

Примечание. Приведенные правила, определяющие область действия, применяются для всех форм описаний, определенных в разд. 3.1; они применяются, в частности, и к неявным описаниям. Правило а) применяется к описанию пакета и тем самым неприменимо к спецификации пакета в описании настройки. Для вложенных описаний правила от а) до е) применяются на каждом уровне. Например, если задачный модуль описан в видимом разделе пакета, то область действия входа задачного модуля распространяется до конца области действия этого задачного модуля, т. е. до конца области действия охватывающего пакета. Область действия спецификатора использования определена в разд. 8.4.

Ссылки: видимость 8.3, видимый раздел 7.2, задача 9, знак операции 6.1, зона описания 8.1, идентификатор 2.3, именуемый тип 3.7, находится непосредственно в 8.1, неявное описание 3.1, описание 3.1, описание входа 9.5, описание задачи 9.1, описание компоненты 3.7, описание настройки 12.1, описание пакета 7.1, описание параметров настройки 12.1, описание переименования 8.5, описание подпрограммы 6.1, описание типа 3.3.1, основная операция 3.3.3, распространяется 8.1, спецификатор использования 8.4, символьный литерал 2.5, след тела 10.2, совмещение 6.6, 8.7, спецификация дискриминанта 3.7.1, спецификация пакета 7.1, спецификация параметра 6.1, тело подпрограммы 6.3.

Пред. | Уровень выше | След.
Глава 8. ПРАВИЛА ВИДИМОСТИ | Начало | 8.3. ВИДИМОСТЬ


8.3. ВИДИМОСТЬ
Пред. Глава 8. ПРАВИЛА ВИДИМОСТИ След.

8.3. ВИДИМОСТЬ

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

Для каждого идентификатора и в каждой точке текста программы правила видимости определяют набор описаний (с этим идентификатором), т. е. варианты трактовки идентификатора. Говорят, что описание видимо в данной точке текста, когда, согласно правилам видимости, оно определяет возможные трактовки его вхождения. Возникают два случая:

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

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

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

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

а) описания, находящегося в видимом разделе описания пакета — на месте постфикса после точки в расширенном имени, префикс которого обозначает пакет;

б) описания входа конкретного задачного типа — на месте постфикса после точки в именованной компоненте, префикс которой соответствует задачному типу;

в) описания компоненты конкретного описания именуемого типа — на месте постфикса после точки в именованной компоненте, префикс которой соответствует этому типу, а также на месте простого имени компоненты (перед составным ограничителем =>) в именованном сопоставлении компонент агрегата этого типа;

г) спецификации дискриминанта конкретного описания типа — в местах, предназначенных для описания компоненты и простого имени дискриминанта (перед составным ограничителем =>) в именованном сопоставлении дискриминанта в ограничении дискриминанта для этого типа;

д) спецификации параметра данной спецификации подпрограммы или описания входа — на месте формального параметра (перед составным ограничителем =>) в именованном сопоставлении параметра соответствующей подпрограммы или вызова входа;

е) описания параметра настройки данного настраиваемого модуля — на месте формального параметра настройки (перед составным ограничителем =>) в именованном сопоставлении соответствующей конкретизации настройки.

Наконец, в зоне описания, связанной с конструкцией, не являющейся описанием именуемого типа, любое описание видимо по имени на месте постфикса после точки в расширенном имени, префикс которого обозначает эту конструкцию.

Там, где нет видимости по имени, говорят, что описание видимо непосредственно. Описание видимо непосредственно в определенном разделе его непосредственной области действия; этот раздел распространяется до конца непосредственной области действия описания, за исключением тех мест, где это описание скрыто, как поясняется ниже. Кроме того, описание, находящееся непосредственно в видимом разделе пакета, может быть сделано непосредственно видимым с помощью спецификатора использования по правилам, описанным в разд. 8.4 (см. также разд. 8.6 о видимости библиотечных модулей).

Описание скрыто во внутренней зоне описания, если она содержит омоним этого описания; внешнее описание является тогда скрытым в непосредственной области действия этого внутреннего омонима. Каждое из двух описаний является омонимом другого, если оба описания имеют один и тот же идентификатор и не более чем для одного из них допустимо совмещение. Если совмещение допустимо для обоих описаний, то каждое из двух является омонимом другого в случае, если они имеют одинаковый идентификатор, символ операции или символьный литерал, а также одинаковый профиль типа параметров и результата (см. 6.6).

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

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

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

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

Пример:

procedure P is
   А, В : BOOLEAN;

   procedure Q is
      С : BOOLEAN;
      В : BOOLEAN;      -— внутренний омоним В
   begin
      ...
      B := А;           -- означает.а.в := Р.А;
      С := Р.В;         -— означает Q.C := Р.В;
   end;
begin
   А := B;              -—означает Р.А := Р.В;
end;

Примечание о видимости библиотечных модулей. Видимость библиотечных модулей определена спецификаторами совместности (см. 10.1.1) и тем фактом, что библиотечные модули неявно описаны в пакете STANDARD (см. 8.6).

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

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

K : INTEGER := K * K;         -- неправильно
T : T;                        -- неправильно
procedure Р(х : P);           -- неправильно
procedure Q(X : REAL := Q);   -- неправильно даже если существует функция с именем Q
procedure R(R : REAL);        -- правильное, хотя создает путаницу.

Ссылки: агрегат 4.3, аргумент 2.8, базовая операция 3.3.3, библиотечный модуль 10.1, видимый раздел 7.2, вызов входа 9.5, вызов подпрограммы 6.4, задачный модуль 9, задачный тип 9.1, зарезервированное слово 2.9, знак операции 6.1, зона описания 8.1, идентификатор 2.3, именованная компонента 4.1.3, именуемый тип 3.7, конкретизация настройки 12.3, лексема 2.2, литерал 2.5, настраиваемый модуль 12, настраиваемый пакет 12.1, находится непосредственно в 8.1, непосредственная область действия 8.2, неявное описание 3.1, область действия 8.2, объект 3.2, ограничение дискриминанта 3.7.2, оператор принятия 9.5, операция 4.5, описание 3.1, описание входа 9.5, описание компоненты 3.7, описание параметра настройки 12.1, описание подпрограммы 6.1, описание типа 3.3.1, пакет 7, параметр 6.2, подпрограмма 6, постфикс

4.1.3, прагма 2.8, программный модуль 6, простое имя 4.1, распространяется 8.1, расширенное имя 4.1.3, семейство входов 9.5, совмещение 6.6, 8.7, соответствует типу 4.1, сопоставление компонент 4.3, сопоставление параметров 6.4, сопоставление параметров настройки 12.3, составной ограничитель 2.2, спецификатор использования 8.4, спецификация дискриминанта 3.7.1, спецификация литерала перечисления 3.5.1, спецификация параметра 6.1, спецификация подпрограммы 6.1, тип 3.3, указывать 3.8, формальный параметр 6.1, формальный параметр настройки 12.1.

-8.4. СПЕЦИФИКАТОРЫ ИСПОЛЬЗОВАНИЯ

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

спецификатор-использования ::= use имя-пакета {, имя-пакета};

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

Чтобы определить, какие описания становятся прямо видимыми в данном месте с помощью спецификатора использования, рассмотрим пакеты, упомянутые в спецификаторах использования, области действия которых охватывают это место. Описанием, которое может быть сделано прямо видимым с помощью спецификатора использования (потенциально видимое описание), является такое описание, которое находится непосредственно в видимом разделе одного из этих пакетов. Потенциально видимое описание становится фактически прямо видимым, за исключением двух случаев:

• Потенциально видимое описание не становится прямо видимым, если рассматриваемое место программы находится непосредственно в области действия описания омонима.

• Потенциально видимые описания с-одинаковыми идентификаторами не становятся прямо видимыми, если только каждое из них не является спецификацией литерала перечисления или описанием подпрограммы (представляющим собой описание подпрограммы, описание переименования, конкретизацию настройки или неявное описание).

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

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

Следовательно, приведенные ниже строчки текста дают один и тот же эффект (в предположении существования единственного пакета Р).

use Р;

use Р; use Р, Р;

Пример противоречия имен в двух пакетах:

procedure R is
   package TRAFFIC is
      type COLOR is (RED, AMBER, GREEN);
      ...
   end TRAFFIC;

   package WATER_COLORS is
      type COLOR is (WHITE, RED, YELLOW, GREEN, BLUE, BROWN, BLACK);
      ...
   end WATER_COLORS;

   use TRAFFIC;        -- COLOR, RED, AMBER, и GREEN непосредственно видимы
   use WATER_COLORS;   -- Два омонима GREEN непосредственно видимы,
                            -- butCOLOR не является более непосредственно видимым
   subtype LIGHT is TRAPPIC.COLOR;    -- подтип использован для разрешения
   subtype SHADE is WATER_COLORS.COLOR; -- противоречия, связанного с именем типа. COLOR

   SIGNAL : LIGHT;
   PAINT  : SHADE;
begin
   SIGNAL := GREEN; -— из пакета TRAFFIC
   PAINT  := GREEN; -— из пакета WATER-COLORS
end R;

Пример идентификации имени со спецификатором использования:

package D is
   Т, U, V : BOOLEAN;
end D;

procedure P is
   package E is
      B, W, V : INTEGER;
   end E;

   procedure Q is
      Т, Х : REAL;
      use D, E;
   begin
      -— имя     Т означает Q.Т, not D.T
      -— имя     U ознaчaeT D.U
      -— имя     В означает Е.В
      -— имя     W oзнaчaeT E.W
      -— имя     Х означает Q.Х
      -— имя неправильно: должно быть использовано D.V или
      ...
   end Q;
begin
   ...
end P;

Ссылки: видимый раздел 7.2, зона описания 8.1, идентификатор 2.3, имя 4.1, компилируемый модуль 10.1, находиться непосредственно в 8.1, непосредственная видимость 8.3, непосредственная область действия 8.2, область действия 8.2, омоним 8.3, описание 3.1, описание подпрограммы 6.1, пакет 7, Предвыполнение 3.1, 3.9, Предвыполнение не имеет другого эффекта 3.1, распространение 8.1, скрытие 8.3, спецификатор контекста 10.1, спецификация литерала перечисления 3.5.1, элемент описания 3.9.

Пред. | Уровень выше | След.
8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ | Начало | 8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ


8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ
Пред. Глава 8. ПРАВИЛА ВИДИМОСТИ След.

8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ

Описание переименования задает другое имя для понятия.

описание-переименования ::=
    идентификатор : обозначение-типа renames имя-объекта;
  | идентификатор : exception renames имя-исключения;

  | package идентификатор renames имя-пакета;
  | спецификация-подпрограммы renames имя-подпрограммы-или-входа;

Предвыполнение описания переименования вычисляет имя, которое следует после зарезервированного слова renames, и таким образом определяет понятие, обозначенное этим именем (переименованное понятие). В любой точке, где описание переименования видимо, идентификатор или знак операции, заданный в этом описании, обозначает переименованное понятие.

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

Существуют следующие ограничения, связанные с переименованием подкомпоненты переменной, которая зависит от дискриминантов. Переименование недопустимо, если подтип переменной, как это определено в соответствующем описании объекта, описании компоненты или указании подтипа компоненты, является неограниченным типом или если переменная — это формальный объект настройки (вида in out). Также если переменная — формальный параметр, то переименование недопустимо, если заданное в спецификации параметра обозначение типа обозначает неограниченный тип, чьи дискриминанты имеют выражения по умолчанию.

Вторая форма описания переименования используется для переименования исключений; третья форма — для переименования пакетов.

Последняя форма описания переименования используется для переименования подпрограмм и входов. Переименованная подпрограмма или вход и спецификация подпрограммы, заданная в описании переименования, должны иметь один и тот же профиль типа параметров и результата (см. 6.6). Описание переименования правильно только в том случае, если точно одна видимая подпрограмма или вход удовлетворяют упомянутым выше требованиям и могут быть обозначены конкретным именем подпрограммы или входа. Кроме того, виды параметров должны совпадать с видами соответствующих по позиции формальных параметров.

Переименование не оказывает влияния на подтипы параметров и результата (если он есть) переименованной подпрограммы или входа. Эти подтипы заданы в первоначальном описании подпрограммы, конкретизации настройки или описании входа (но не в описании переименования), а также для вызовов, которые используют новое имя. С другой стороны, описание переименования может вводить имена параметров и выражения по умолчанию, которые отличаются от заданных для переименованной подпрограммы; именованные сопоставления в вызовах с новым именем подпрограммы должны использовать новое имя параметра; вызовы со старым именем подпрограммы должны использовать старые имена параметров.

Процедура может быть переименована только как процедура. Функция либо операция могут быть переименованы как функция либо как операция; при переименовании функции или операции операцией спецификация подпрограммы, заданная в описании переименования, подчиняется правилам разд. 6.7 для описаний операции. Литералы перечисления могут быть переименованы как функции; аналогично'атрибуты, определенные как функции (такие, как SUCC или PRED), могут быть переименованы как функции. Вход может быть переименован только как процедура; новое имя допускается только в контексте, допускающем имя процедуры. Вход из семейства может быть переименован, но семейство входов не может быть переименовано целиком. /

Примеры:

declare
   L : PERSON renames LEFTMOST_PERSON; -- см. 3.8.1
begin
   L.AGE := L.AGE + 1;
end;

FULL : exception renames TABLE_MANAGER.TABLE_FULL; -- CM. 7.5

package TM renames TABLE.MANAGER;

function REAL_PLUS(LEFT, RIGHT : REAL   ) return REAL    renames "+";
function INT_PLUS (LEFT, RIGHT : INTEGER) return INTEGER renames "+";

function ROUGE return COLOR renames RED; —- CM. 3.5.1
function ROT    return COLOR renames RED;
function ROSSO return COLOR renames ROUGE:

function NEXT(X : COLOR) return COLOR renames COLOR'SUCC; - CM. 3.5.5

Примеры описания переименования с новыми именами параметров:

function "*" (X.Y : VECTOR) return REAL renames DOT_PRODUCT; —- CM. 6.1

Пример описания переименования с новым выражением по умолчанию:

function MINIMUMtL : LINK := HEAD) return CELL renames MIN-.CELL; — CM. 6.1

Примечание. Переименование может быть использовано для разрешения конфликта имен и введения сокращений. Переименование другим идентификатором или символом операции не скрывает старое имя; новое и старое имена (символ операции) не обязательно видимы в одних и тех же точках. Атрибуты РОЗ и VAL не могут быть переименованы, так как не могут быть написаны соответствующие спецификации; это положение справедливо для предопределенных мультипликативных операций с результатом универсального-фиксированного типа.

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

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

Для достижения эффекта переименования типа (включая задачный тип) может быть использован подтип, например:

subtype MODE is TEXT_IO.FILE_MODE ; \

Ссылки: атрибут 4.1.4, базовый тип 3.3, вид 6.1, видимость 8.3, временный вызов входа 9.7.3, вход 9.5, вызов входа 9.5, вызов подпрограммы 6.4, выражение по умолчанию 6.1, вычисление имени 4.1, дискриминант 3.7.1, допустимый 1.6, зависеть от дискриминанта 3.7.1, задачный объект 9.2, зарезервированное слово 2.9, знак операции 6.1, идентификатор 2.3, имя 4.1, исключение 11, константа 3.2.1, литерал перечисления 3.5.1, обозначение типа 3^3.2, объект 3.2, ограничение 3.3, ограниченный подтип 3.3, оператор вызова входа 9.5, оператор вызова процедуры 6.4, операция 6.7, описание 3.1, описание входа 9.5, описание объекта 3.2, описание операции 6.7, описание подпрограммы 6.1, пакет 7, параметр 6.2, переменная 3.2.1, подкомпонента 3.3, подпрограмма 6, подтип 3.3.2, правильно 1.6, предвыполнение 3.1, процедура 6.1, семейство входов 9.5, спецификация параметра 6.1, спецификация подпрограммы 6.1, тип 3.3, условный вызов входа 9.7.2, формальный параметр 6.1, функция 6.5.

Пред. | Уровень выше | След.
8.3. ВИДИМОСТЬ | Начало | 8.6. СТАНДАРТНЫЙ ПАКЕТ


8.6. СТАНДАРТНЫЙ ПАКЕТ
Пред. Глава 8. ПРАВИЛА ВИДИМОСТИ След.

8.6. СТАНДАРТНЫЙ ПАКЕТ

Предопределенные типы (например, BOOLEAN, CHARACTER и INTEGER) описаны в предопределенном пакете, называемом STANDARD; этот пакет включает также описания предопределенных для них операций, ракет STANDARD описан в приложении С. Спецификация пакета STANDARD, за исключением предопределенных числовых типов, должна быть одинаковой для всех реализации языка.

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

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

Если тип описан в видимом разделе библиотечного пакета, то из правил видимости следует, что базовая операция (например, присваивание) над этим типом непосредственно видима в точке, где сам тип невидим (либо по имени, либо непосредственно). Однако эта операция может быть применена только к тем операндам, которые являются видимыми, и описание этих операндов требует видимости либо типа, либо одного из его подтипов.

Ссылки: библиотечный модуль 10.1, видимость 8.3, вторичный модуль 10.1, главная программа 10.1, должно 1.6, зона описания 8.1, идентификатор 2.3, имя 4.1, имя блока 5.6, находится непосредственно в 8.1, неявное описание 3.1, оператор блока 5.6, оператор цикла 8.5, операция 6.7, описание 3.1, пакет 7, подтип 3.3, применяемый спецификатор совместности 10.1.1, программный модуль 6, расширенное имя 4.1.3, скрытие 8.3, спецификатор совместности 10.1.1, тип 3.3.

Пред. | Уровень выше | След.
8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ | Начало | 8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ


8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ
Пред. Глава 8. ПРАВИЛА ВИДИМОСТИ След.

8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ

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

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

В таком месте рассматриваются все видимые описания. Вхождение правильно только тогда, когда есть точно одна интерпретация самого вложенного полного контекста. Полный контекст — это описание, оператор, спецификатор представления.

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

а) любое правило, которое требует, чтобы имя или выражение имели определенный тип или такой же тип, как другое имя или выражение;

б) любое правило, которое требует, чтобы тип имени или выражения был типом определенного класса; аналогично любое правило, которое требует, чтобы определенный тип был дискретным, целым, вещественным, универсальным, символьным, логическим или нелимитируемым типом;

в) любое правило, которое требует, чтобы префикс соответствовал определенному типу;

г) любое правило, которое задает определенный тип в качестве типа результата базовой операции, и любое правило, которое устанавливает, что это тип определенного класса;

д) правила, которые требуют, чтобы тип агрегата или строкового литерала был определен исключительно охватывающим полным контекстом (см. 4.3 и 4.2). Аналогично правила, которые требуют, чтобы тип префикса атрибута, тип выражения оператора выбора или тип операнда преобразования типа были определены независимо от контекста (см. 4.1.4, 4.6, 5.4 и 6.4.1);

е) правила, данные в разд. 6.6 по разрешению вызовов совмещенных подпрограмм, в разд. 4.6 по неявным преобразованиям универсальных выражений, в разд. 3.6.1 по интерпретации дискретных диапазонов с границами, имеющими универсальный тип, в разд. 4.1.3 по интерпретации расширенного имени, чей префикс обозначает подпрограмму или оператор принятия.

Имена подпрограмм, используемые в качестве аргументов прагмы, следуют другому правилу: прагма может применяться для нескольких совмещенных подпрограмм, как пояснено в разд. 6.3.2 для прагмы INLINE, в разд. 11.7 для прагмы SUPPRESS и в разд. 13.9 для прагмы INTERFACE.

Подобно данные в спецификаторах контекста (см. 10.1.1) и спецификаторах адреса простые имена следуют другим правилам.

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

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

Спецификация параметра цикла есть описание и, следовательно, полный контекст.

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

Ссылки: агрегат 4.3, базовая операция 3.3, вход 9.5, выражение 4.4, генератор 4.8, идентификатор 2.3, имя 4.1, исключение 11, класс типа 3.3, литерал 4.2, литерал перечисления 3.5.1, литерал null 3.8, оператор 5, оператор выбора 5.4, операция 4.5, операция типа 3.3.3, описание 3.1, подпрограмма 6, подтип 3.3, правильный 1.6, прагма 2.8, преобразование типа 4.6, присваивание 5.2, проверка принадлежности 4.5.2, раздел формальных параметров G.1, совмещение 6.6, спецификатор представления 13.1, спецификация параметра цикла 5.5, статическое выражение 4.9, статический подтип 4.9.

Правила формы (а): выбор 3.7.3, 4.3.2, 5.4, выражение по умолчанию 3.7, 3.7.1, 6.1, 12.1.1, выражение результата 5.8, дискретный диапазон 3.6.1, 5.5, 9.5, индексное выражение 4.1.1, 4.1.2, 9.5, квалифицированное выражение 4.7, начальное значение 3.2.1, ограничение диапазона 3.5, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, оператор задержки 9.6, переименование объекта 8.5, правила согласования 9.5, присваивание 5.2, проверка принадлежности 4.5.2, профиль параметров и типа результата 8.5, 12.3.6, сопоставление компонент 4.3.1, 4.3.2, сопоставление параметров настройки 12.3, сопоставление параметров 6.4.1, спецификатор адреса 13.5, спецификатор представления перечислимых 13.3.

Правила формы (б): атрибут VAL 3.5.5, выражение выбора 6.4, дискретный диапазон 3.6.1, 5.5, 9.5, именуемая компонента 4.1.3, оператор прекращения 9.10, описание плавающего типа 3.5.7, описание фиксированного типа 3.5.9, описание целого типа 3.5.4, описание числа 3.2.2, присваивание 5.2, проверка принадлежности 4.4, спецификатор длины 13.2, спецификатор представления записи 13.4, условие 5.3, 5.5, 5.7, 9.7.1, форма управления промежуточной проверкой 4.4.

Правила формы (в): именуемая компонента 4.1.3, индексируемая компонента 4.1.1, отрезок 4.1.2.

Правила формы (г): агрегат 4.3, генератор 4.8, литерал null 4.2, проверка принадлежности 4.4, строковый литерал 4.2, форма управления с промежуточной проверкой 4.4, числовой литерал 2.4.

Пред. | Уровень выше | След.
8.6. СТАНДАРТНЫЙ ПАКЕТ | Начало | Глава 9. ЗАДАЧИ


Глава 9. ЗАДАЧИ
Пред. След.

Глава 9. ЗАДАЧИ

Содержание

9.1. СПЕЦИФИКАЦИИ ЗАДАЧ И ТЕЛА ЗАДАЧ
9.2. ЗАДАННЫЕ ТИПЫ И ЗАДАЧНЫЕ ОБЪЕКТЫ
9.3. ВЫПОЛНЕНИЕ И АКТИВИЗАЦИЯ ЗАДАЧИ
9.4. ЗАВИСИМОСТЬ ЗАДАЧ. ЗАВЕРШЕНИЕ ЗАДАЧ
9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ
9.6. ОПЕРАТОРЫ ЗАДЕРЖКИ, ДЛИТЕЛЬНОСТЬ И ВРЕМЯ
9.7. ОПЕРАТОРЫ ОТБОРА
9.7.2. УСЛОВНЫЕ ВЫЗОВЫ ВХОДОВ
9.8. ПРИОРИТЕТЫ
9.9. АТРИБУТЫ ЗАДАЧ И ВХОДОВ
9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ
9.11. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ
9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ

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

Под параллельным выполнением задач понимают следующее. Предполагается, что каждую задачу выполняет отдельный логический процессор. Различные задачи (на различных логических процессорах) выполняются независимо, за исключением точек их синхронизации.

Некоторые задачи могут иметь входы. Вход задачи может быть вызван другими задачами. Задача принимает вызов одного из своих входов выполнением оператора принятия этого входа. Синхронизация достигается посредством рандеву между задачей, вызывающей вход, и задачей, принимающей вызов. Некоторые входы имеют параметры; вызовы и операторы принятия таких входов, имеющих параметры, являются основным средством обмена значениями между задачами.

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

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

Ссылки: вход 9.5, настраиваемый модуль 12, оператор вызова входа 9.5, оператор задержки 9.6, оператор прекращения 9.10, оператор принятия 9.5, оператор отбора 9.7, пакет 7, подпрограмма б, программный модуль 6, рандеву 9.5, спецификация задачи 9.1, тело задачи 9.1.

9.1. СПЕЦИФИКАЦИИ ЗАДАЧ И ТЕЛА ЗАДАЧ

Задачный модуль состоит из спецификации задачи и тела задачи. Спецификация задачи, которая начинается зарезервированными словами task type, описывает задачный тип. Значение объекта задачного типа указывает задачу. Если задача имеет входы, то они описываются в спецификации задачи; эти входы также называются входами объекта. Выполнение задачи определяется соответствующим телом задачи.

Спецификация задачи без зарезервированного слова type определяет одну задачу. Описание такой задачи эквивалентно описанию анонимного задачного типа одновременно с описанием объекта этого задачного типа, а идентификатор задачного модуля именует объект. В остальной части данной главы пояснения даются в терминах описаний задачного типа; соответствующие пояснения для одной задачи следуют из упомянутого отношения эквивалентности.

описание-задачи ::== спецификация-задачи;
спецификация - задачи :: =
   task [type] идентификатор [is
      {описание - входа}
      {спецификатор - представления}
   end [простое-имя-задачи]]
тело-задачи ::=
   task body простое-имя-задачи is
      [раздел - описаний]
   begin
      последовательность - операторов
   [exception
      обработчик - исключения
      {обработчик-исключения}]
   end [простое-имя-задачи];

Простое имя в начале тела задачи должно совпадать с идентификатором задачного моду-ля. Аналогично если в конце спецификации или тела задачи появляется простое имя, то оно должно совпадать с идентификатором задачного модуля. Внутри тела задачи имя соответствующего задачного модуля может быть также использовано для ссылки на объект-задачу (указывать на задачу), тело которой выполняется в данный момент; кроме того, не допускается использование этого имени в качестве обозначения типа внутри собственного задачного модуля. [7]

При предвыполнении спецификации задачи описания входов и спецификаторы представления (если они есть) предвыполняются в том порядке, в котором они даны. Спецификаторы представления применяются только к входам, описанным в спецификации задачи (см. 13.5).

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

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

Примеры спецификации задачных типов:

task type RESOURCE is
   entry SEIZE;
   entry RELEASE;
end RESOURCE;

task type KEYBOARD_DRIVER is
   entry READ (C : out CHARACTER);
   entry WRITE (C : In   CHARACTER);
endKEYBOARD_DRIVER;

Примеры спецификации одной задачи:

task PRODUCER_CONSUMER is
   entry READ (V : out ITEM);
   entry WRITE (E : in  ITEM);
end;

task CONTROLLER is
   entry REQUEST(LEVEL)(D : ITEM); -— семейство ВХОДОВ
end CONTROLLER;

task USER;  -— не имеет входов

Пример спецификации задачи и соответствующего тела:

task PROTECTED_ARRAY is
   -— INDEX and ITEM — это глобальные типы
   entry READ (N : in INDEX; V : out ITEM);
   entry WRITE (N : In INDEX; E : in  ITEM);
end;

task body PROTECTED_ARRAY is
   TABLE : array(INDEX) of ITEM := (INDEX => NULL_ITEM);
begin
   loop
      select
         accept READ (N : in INDEX; V : out ITEM) do
            V := TABLE(N);
         end READ;
      or
         accept WRITE (N : in INDEX; E : in   ITEM) do
            TABLE(N) := E;
         end WRITE;
      end select;
   end loop;
end PROTECTED_ARRAY;

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

Ссылки: вход 9.5, главная программа 10.1, зарезервированное слово 2.9, идентификатор 2.3, обработчик исключения 11.2, объект 3.2, описание 3.1, описание входа 9.5, описание объекта 3.2.1, описание типа 3.3.1, последовательность операторов 5.1, предвыполнение 3.9, простое имя 4.1, раздел описаний 3.9, спецификатор представления 13.1, тип 3.3.

[7] 1) Кроме того, оно не может быть использовано в качестве производного от него типа или подтипа. - Прим. ред.

Пред. | Уровень выше | След.
8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ | Начало | 9.2. ЗАДАННЫЕ ТИПЫ И ЗАДАЧНЫЕ ОБЪЕКТЫ


9.2. ЗАДАННЫЕ ТИПЫ И ЗАДАЧНЫЕ ОБЪЕКТЫ
Пред. Глава 9. ЗАДАЧИ След.

9.2. ЗАДАННЫЕ ТИПЫ И ЗАДАЧНЫЕ ОБЪЕКТЫ

Задачный тип является лимитируемым типом (см. 7.4.4). Следовательно, для объектов за-дачного типа не определены ни присваивание, ни предопределенное сравнение на равенство и неравенство; более того, вид out недопустим для формального параметра задачного типа.

Задачный объект — это объект задачного типа. Значение задачного объекта указывает задачу с входами соответствующего задачного типа, а ее выполнение определено соответствующим телом задачи. Если задачный объект является объектом или подкомпонентой объекта, заданными описанием объекта, то его значение определяется предвыполнением описания объекта. Если задачный объект является объектом или подкомпонентой объекта, созданными при выполнении генератора, то его значение определяется выполнением генератора. Для всех видов параметров, если фактический параметр указывает задачу, сопоставляемый формальный параметр указывает ту же задачу; это же относится к подкомпоненте фактического параметра и к соответствующей подкомпбненте сопоставляемого формального параметра; наконец, то же справедливо и для параметров настройки.

Примеры:

CONTROL  : RESOURCE;
TELETYPE : KEYBOARDDRIVER;
POOL     : array(1 .. 10) of KEYBOARDDRIVER;
-— см. также примеры описаний одиночных задач в 9.1

Пример ссылочного типа, указывающего задачный объект:

type KEYBOARD is access KEYBOARDDRIVER;
TERMINAL : KEYBOARD := new KEYBOARDDRIVER;

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

Задачные объекты ведут себя как константы (задачный объект всегда указывает одну и ту же задачу), поскольку их значения неявно определены при описании либо при генерации, либо при сопоставлении параметров, и никакие присваивания недопустимы. Однако зарезервированное слово constant недопустимо в описании задачного объекта, так как его наличие требует явной инициализации. Задачный объект, который является формальным параметром вида in, есть константа (как и любой формальный параметр вида in).

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

Для задачных типов допустимы описания подтипов, как и для других типов, но никакие ограничения к задачному типу неприменимы.

Ссылки: вид формального параметра 6.2, вид формального параметра настройки 12.1.1, вход 9.5, генератор 4.8, зарезервированное слово 2.9, инициализация 3.2.1, константа 3.2.1, лимитируемый тип 7.4.4, личный раздел 7.2, личный тип 7.4, настраиваемый модуль 12, объект 3.2, ограничение 3.3, операция неравенства 4.5.2, операция равенства 4.5.2, описание компоненты 3.7, описание константы 3.2.1, подкомпонента 3.3, подпрограмма 6, предвыполнение 3.9, присваивание 5.2, сопоставление параметров 6.4, сопоставление параметров настройки 12.3; составной тип 3.3, ссылочный тип 3.8, тело задачи 9.1, тип 3.3, указывать 3.8.9, фактический параметр 6.4.1, фактический параметр настройки 12.3, формальный параметр 6.2, формальный параметр настройки 12.1.1.

Пред. | Уровень выше | След.
Глава 9. ЗАДАЧИ | Начало | 9.3. ВЫПОЛНЕНИЕ И АКТИВИЗАЦИЯ ЗАДАЧИ


9.3. ВЫПОЛНЕНИЕ И АКТИВИЗАЦИЯ ЗАДАЧИ
Пред. Глава 9. ЗАДАЧИ След.

9.3. ВЫПОЛНЕНИЕ И АКТИВИЗАЦИЯ ЗАДАЧИ

Тело задачи определяет выполнение всякой задачи, которая указывается задачным объектом соответствующего задачного типа. Начальный этап этого выполнения называется активизацией задачного объекта и указанной им задачи; активизация состоит из предвыполнения раздела описаний (если он есть) тела задачи. Выполнение различных задач, в частности, их активизация, производится параллельно.

Если задачный объект описан непосредственно в разделе описаний, то активизация задачного объекта начинается после предвыполнения раздела описаний (т. е. после грамматического разбора зарезервированного слова begin, следующего за разделом описаний); аналогично если такое описание помещено непосредственно в спецификацию пакета, то активизация начинается после предвыполнения раздела описаний тела пакета. То же относится и к активизации задачного объекта, являющегося подкомпонентой объекта, описанной непосредственно в разделе описаний или спецификации пакета. Первый оператор, следующий за разделом описаний, выполняется только после окончания активизации задачных объектов.

Если при активизации одной из таких задач возбуждается исключение, то эта задача становится законченной (см. 9.4); на других задачах это прямо не отражается. Если во время активизации одна из этих задач становится законченной, то после завершения активизации (успешного или нет) всех задач возбуждается исключение TASKING_ERROR; исключение возбуждается непосредственно за разделом описаний перед выполнением первого оператора (непосредственно после зарезервированного слова begin ). Исключение TASKING_ERROR возбуждается лишь однажды, даже если во время активизации сразу несколько задач становятся законченными таким способом.

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

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

Задачный, объект, являющийся объектом или подкомпонентой объекта, созданного выполнением генератора, активизируется этим выполнением. Активизация начинается после инициализации объекта, созданного генератором; если несколько подкомпонент являются задач-ными объектами, они активизируются параллельно. Ссылочное значение, указывающее этот объект, возвращается генератором только после проведения этих активизации.

Если исключение возбуждается при активизации одной из таких задач, то она становится законченной задачей; на другие задачи этот факт не оказывает прямого воздействия. Если во время своей активизации одна из задач становится законченной, то после проведения активизации (успешной или нет) всех этих задач возбуждается исключение TASKING_ERROR; исключение возбуждается в той точке текста программы, где выполняется генератор. Исключение TASKING_ERROR возбуждается лишь однажды, даже если во время активизации сразу несколько задач становятся законченными таким образом.

Если исключение возбуждается во время инициализации объекта, созданного генератором (следовательно, до начала активизации), то любая задача, указанная подкомпонентой этого объекта, становится завершенной, и, таким образом, она никогда не активизируется.

Пример:

procedure P is
   А, В : RESOURCE; -— предвыполняет заданные объекты А и В
   С    : RESOURCE; -— предвыполняет задачный объект С
begin
   -— задачи А, В, С активизируются параллельно! перед выполнением первого оператора
   ...
end;

Примечание. Вход задачи может быть вызван до активизации задачи. Если несколько задач активизируются параллельно, выполнение любой из них не предполагает ожидания конца активизации других задач. Задача может стать законченной во время ее активизации как из-за исключения, так и из-за прекращения (см. 9.10).

Ссылки: вход 9.5, генератор 4.8, завершение задачи 9.4, задачный объект 9.2, задачный тип 9.1, законченная задача 9.4, исключение 11, предвыполнение 3.9, 11.1, обработка исключения 11.4, оператор 5, параллельное выполнение 9, подкомпонента 3.3, раздел описаний 3.9, тело задачи 9.1, тело пакета 7.1.

Пред. | Уровень выше | След.
9.2. ЗАДАННЫЕ ТИПЫ И ЗАДАЧНЫЕ ОБЪЕКТЫ | Начало | 9.4. ЗАВИСИМОСТЬ ЗАДАЧ. ЗАВЕРШЕНИЕ ЗАДАЧ


9.4. ЗАВИСИМОСТЬ ЗАДАЧ. ЗАВЕРШЕНИЕ ЗАДАЧ
Пред. Глава 9. ЗАДАЧИ След.

9.4. ЗАВИСИМОСТЬ ЗАДАЧ. ЗАВЕРШЕНИЕ ЗАДАЧ

Каждая задача зависит по крайней мере от одного родителя. Родитель — это конструкция, являющаяся либо задачей, либо в данный момент выполняемым оператором блока или подпрограммой, либо библиотечным пакетом (но не описанным в другом программном модуле). Зависимость от родителя является непосредственной зависимостью в следующих двух случаях:

а) Задача, указанная задачным объектом, который является объектом или подкомпонен-той объекта, созданными при выполнении генератора, зависит от родителя, предвыполняюще-го соответствующее описание ссылочного типа.

б) Задача, указанная другим задачным объектом, зависит от родителя, выполнение которого создает задачный объект.

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

Говорят, что задача закончила свое выполнение, когда осуществилось выполнение последовательности операторов, помещенных в ее теле за зарезервированным словом begin. Аналогично говорят, что блок или подпрограмма закончили свое выполнение, когда осуществилось выполнение соответствующей последовательности операторов. В случае оператора блока также говорят, что выполнение его закончилось при достижении операторов выхода, возврата или перехода, передающих управление из блока. В случае процедуры также говорят, что ее выполнение закончилось при достижении соответствующего оператора возврата. В случае функции также говорят, что ее выполнение закончилось после вычисления результирующего выражения в операторе возврата. Наконец, выполнение задачи, оператора блока или подпрограммы закончено, если при выполнении содержащихся в них соответствующих последовательностей операторов возбуждено исключение и нет соответствующего ему обработчика, а при его наличии — по окончании выполнения соответствующего обработчика.

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

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

• Задача зависит от некоторого родителя, выполнение которого закончено (следовательно, не от библиотечного пакета).

• Каждая задача, зависящая от рассмотренного родителя, либо уже завершена, либо также ожидает открытой альтернативы завершения в операторе отбора.

Когда оба условия удовлетворены, задача становится завершенной вместе со всеми задачами, зависящими от этого же родителя.

Пример;

declare
   type GLOBAL is access RESOURCE; --CM 91
   А, В : RESOURCE;
   G    : GLOBAL;
begin
   -— активизация А и В
   declare
      type LOCAL is access RESOURCE;
      X : GLOBAL := new RESOURCE; -— активизация X.all
      L : LOCAL := new RESOURCE; — активизация L.all
      С : RESOURCE;
   begin
      -— активизация С
       G := X;  -- G и X указывают один и тот же задачный объект
   end: -— ожидание завершения С и L.all, но не X.all
end; -- ожидание завершения А, В и G.all

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

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

Для ссылочного типа, являющегося производным другого ссылочного типа, соответствующее определение ссылочного типа является определением родительского типа; зависимость в данном случае является зависимостью от родителя, который предвыполняет основные определения родительского ссылочного типа.

Описание переименования вводит новое имя для уже существующего понятия и, следовательно, не порождает дальнейшей зависимости.

Ссылки: альтернатива завершения 9.7.1, библиотечный модуль 10.1, вызов подпрограммы 6.4, генератор 4.8, главная программа 10.1, задачный объект 9.2, исключение 11, обработчик исключения 11.2, объект 3.2, оператор 5, оператор блока 5.6, оператор возврата 5.8, оператор выхода 5.7, оператор перехода 5.9, описание 3.1, описание переименования 8.5, отбор с ожиданием 9.7.1, открытая альтернатива 9.7.1, пакет 7, подкомпонента 3.3, последовательность операторов 5.1, программный модуль 6, ссылочный тип 3.8, тело задачи 9.1, тело подпрограммы 6.3, указывать 9.1, функция 6.5.

Пред. | Уровень выше | След.
9.3. ВЫПОЛНЕНИЕ И АКТИВИЗАЦИЯ ЗАДАЧИ | Начало | 9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ


9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ
Пред. Глава 9. ЗАДАЧИ След.

9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ

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

описание-входа ::=
  entry идентификатор [(дискретный-диапазон)] [раздел-формальных-параметров];

оператор-вызова-входа ::= имя-входа [раздел-фактических-параметров];

оператор-принятия ::=
  accept простое-имя-входа [(индекс-входа)]
     [раздел-формальных-параметров] [do
     последовательность-операторов
  end [простое-имя-входа]];

индекс-входа ::= выражение

Описание входа, включающее дискретный диапазон (см. 3.6.1), описывает семейство различных входов с одним и тем же формальным разделом (если он есть), а именно по одному входу для каждого значения дискретного диапазона. Термин одиночный вход используется при определении правил, применимых к любому входу, отличному от члена семейства. Задача, указанная объектом задачного типа, имеет вход (входы), который (которые) описан (описаны) в спецификации этого задачного типа.

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

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

Виды параметров, определенные для параметров формального раздела описания входа, такие же, как в описании подпрограммы, и имеют тот же смысл (см. 6.2). Синтаксически оператор вызова входа подобен оператору вызова процедуры; правила сопоставления параметров остаются теми же, что и для вызовов подпрограмм (см. 6.4.1 и 6.4.2).

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

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

При предвыполнении описания входа вначале вычисляется дискретный диапазон (если он есть), затем так же, как в описании подпрограммы, предвыполняется раздел формальных параметров (если он есть).

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

Если данный вход вызывается только одной задачей, то предоставляются две возможности:

• Если вызывающая задача перешла к оператору вызова входа раньше, чем имеющая этот вход задача достигла оператора принятия, то выполнение вызывающей задачи приостанавливается.

• Если задача достигла оператора принятия раньше любого вызова этого входа, то выполнение задачи приостанавливается до получения такого вызова.

Если вход был вызван и соответствующий оператор принятия достигнут, то его последовательность операторов (если она есть) выполняется вызванной задачей (вызывающая задача остается приостановленной). Это взаимодействие задач называется рандеву. После рандеву вызывающая задача и задача, содержащая вход, продолжают выполняться параллельно.

Если несколько задач вызывают один и тот же вход до того, как достигнут оператор принятия, то эти вызовы становятся в очередь; с каждым входом связывается одна очередь. Каждое выполнение оператора принятия удаляет из очереди один вызов. Вызовы обрабатываются в порядке поступления.

При попытке вызвать вход задачи, закончившей свое выполнение, в точке вызова вызывающей задачи возбуждается исключение TASKING_ERROR; это же исключение возбуждается в точке вызова, если вызванная задача заканчивает свое выполнение до принятия входа (см. также разд. 9,10 для случая, когда вызванная задача становится аварийной). Исключение CONSTRAINT_ERROR возбуждается, если индекс входа семейства не принадлежит заданному дискретному диапазону.

Примеры описаний входов:

entry
 READ(V : out ITEM);
entry SEIZE;
entry REQUEST(LEVEL)(D : ITEM); -- семейство входов

Примеры вызовов входов:

CONTROL.RELEASE;                      -— см. 9.2 и 9.1
PRODUCER_CONSUMER.WRITE(E);           -— CM. 9.1
POOL(5).READ(NEXT_CHAR);              -— CM. 9.1 и 9.2
CONTROLLER.REQUEST(LOW)(SOME_ITEM);   —- см. 9.1

Примеры операторов принятия:

accept SEIZE;

accept READ(V : out ITEM) do
   V := i.OCAUTEM;
end READ;

accept REQUEST(LOW)(D : ITEM) do
   ...
end REQUEST;

Примечание. Заданный в операторе принятия раздел формальных параметров не предвыполняется; он используется только для идентификации соответствующего входа.

Оператор принятия может вызывать подпрограммы, производящие вызовы входов. Оператор принятия может не содержать последовательности операторов, даже если соответствующий вход имеет параметры. Точно так же он может содержать последовательность операторов, даже если соответствующий вход не имеет параметров. Последовательность операторов в операторе принятия может включать операторы возврата. Задача может вызывать и свои собственные входы, однако это, конечно, может привести к тупиковой ситуации. Языком разрешены условные и временные вызовы входов (см. 9.7.2 и 9.7.3). Правилами языка задаче в данной момент времени разрешается находиться только в одной очереди.

Если границы дискретного диапазона семейства входов являются литералами целого типа, то индекс (в имени входа или в операторе принятия) должен быть предопределенного типа INTEGER (см. 3.6.1).

Ссылки: аварийная задача 9.10, временнбй вызов входа 9.7.3, вызов процедуры 6.4, выполнение 4.5, выражение 4.4, дискретный диапазон 3.6.1, задача 9, законченная задача 9.4, идентификатор 2.3, именуемая компонента 4.1.3, имя 4.1, индексируемая компонента 4.1.1, исключение CONSTRAINT_ERROR 11.1, исключение TASKING_ERROR 11.1, литерал перечисления 3.5.1, область 8.2, объект 3.2, оператор возврата 5-8, описание переименования 8.5, описание подпрограммы 6.1, параллельное выполнение 9, подпрограмма 6, последовательность операторов 5.1, постфикс 4.1.3, правила согласования 6.3.1, предвыполнение 3.1, 3.9, префикс 4.1, простое выражение 4.4, простое имя 4.1, процедура 6, раздел фактических параметров 6.4, совмещение 6.6, 8.7, спецификация задачи 9, тело задачи 9.1, тело подпрограммы 6.3, указывать 9.1, условный вызов входа 9.7.2, формальный раздел 6.1, целый тип 3.5.4.

Пред. | Уровень выше | След.
9.4. ЗАВИСИМОСТЬ ЗАДАЧ. ЗАВЕРШЕНИЕ ЗАДАЧ | Начало | 9.6. ОПЕРАТОРЫ ЗАДЕРЖКИ, ДЛИТЕЛЬНОСТЬ И ВРЕМЯ


9.6. ОПЕРАТОРЫ ЗАДЕРЖКИ, ДЛИТЕЛЬНОСТЬ И ВРЕМЯ
Пред. Глава 9. ЗАДАЧИ След.

9.6. ОПЕРАТОРЫ ЗАДЕРЖКИ, ДЛИТЕЛЬНОСТЬ И ВРЕМЯ

Выполнение оператора задержки вычисляет простое выражение и приостанавливает дальнейшее выполнение задачи, содержащей данный оператор задержки, по крайней мере на длительность, заданную вычисленным значением.

оператор-задержки ::= delay простое-выражение;

Простое выражение должно быть предопределенного фиксированного типа DURATION (ДЛИТЕЛЬНОСТЬ); его значение выражается в секундах; оператор задержки с отрицательным значением эквивалентен оператору задержки с нулевым значением.

Все реализации типа DURATION должны допускать представление длительности (положительные и отрицательные) по крайней мере до 86 400 с (одни сутки); минимальная представи-мая длительность, DURATION'SMALL, должна быть не больше 20 мс (по возможности значение не превышает 50 мкс. Заметим, что DURATION'SMALL не обязано соответствовать основному циклу таймера, именованному числу SYSTEM.TICK (см. 13.7).

Определение типа TIME приведено в предопределенном пакете CALENDAR. Функция CLOCK возвращает текущее значение типа TIME. Функции YEAR, MONTH, DAY и SECONDS возвращают соответствующие наименованиям значения для заданного значения аргумента типа TIME, а процедура SPLIT возвращает одновременно все четыре соответствующих значения. Наоборот, функция TIME-OF упаковывает номера года, месяца, числа дня и значение длительности в значение типа TIME. В операции " + " и " -" для сложения и вычитания значений времени и длительности, а также в операции соотношения для значений времени вкладывают традиционный смысл.

Исключение TIME_ERROR возбуждается в функции TIME-OF, если значения фактических параметров не формируют правильную дату. Это исключение возбуждается также операциями "+" и "-", если для заданных операндов они не могут возвратить дату с номером года из диапазона соответствующего подтипа или если операция " -" не может возвратить значение из диапазона типа DURATION.

package CALENDAR is

   type TIME is private;

   subtype YEAR_NUMBER   is INTEGER   range 1901 .. 2099;
   subtype MONTH_NUMBER is INTEGER   range 1 .. 12;
   subtype DAY_NUMBER   is INTEGER   range 1 .. 31;
   subtype DAY_DURATION  is DURATION range 0.0 .. 86_400.0;

   function CLOCK return TIME;
   function YEAR    (DATE : TIME) return YEAR_NUMBER;
   function MONTH (DATE : TIME) return MONTH_NUMBER;
   function DAY     (DATE : TIME) return DAY_NUMBER;
   function SECONDS (DATE : TIME) return DAY_DURATION;

   procedure SPLIT (DATE    : in TIME;
                    YEAR    : out YEAR-NUMBER;
                    MONTH   : out MONTH-NUMBER;
                    DAY     : out DAY-NUMBER;
                    SECONDS : out DAY_DURATION);

   function TIME_OF(YEAR    : YEAR_NUMBER;
                    MONTH   : MONTH_NUMBER;
                    DAY     : DAY_NUMBER;
                    SECONDS : DAY_DURATION := 0.0) return TIME;

   function "+"   (LEFT : TIME;       RIGHT : DURATION) return TIME;
   function "+"   (LEFT : DURATION; RIGHT : TIME)       return TIME;
   function "-"   (LEFT : TIME;       RIGHT : DURATION) return TIME;
   function "-"   (LEFT : TIME;       RIGHT : TIME)       return DURATION;

   function "<"   (LEFT, RIGHT TIME) return BOOLEAN;
   function "<=" (LEFT, RIGHT TIME) return BOOLEAN;
   function ">"   (LEFT, RIGHT TIME) return BOOLEAN;
   function ">=" (LEFT, RIGHT TIME) return BOOLEAN;

   TIME_ERROR : exception;  -—  может быть возбуждено функцией и операциями "+" и "-"

private
   -— зависит от реализации
end;

Примеры:

delay 3.0; -— задержка на 3.0 с
declare
   use CALENDAR;
   -— INTERVAL глобальная константа типа DURATION
   NEXT_TIME : TIME := CLOCK + INTERVAL;
begin
   loop
      delay NEXT_TIME - CLOCK;
      -— некоторые действия
      NEXT_TIME := NEXT_TIME + INTERVAL;
   end loop;
end:

Примечание. Во втором примере цикл повторяется в среднем один раз каждые INTERVAL секунд. Этот интервал между двумя последовательными итерациями только приблизителен. Однако здесь не произойдет ошибки по длительности, поскольку длительность каждой итера-ции (существенно) меньше значения INTERVAL.

Ссылки: библиотечный модуль 10.1, вызов функции 6.4, длительность С, задача 9, личный тип 7.4, оператор 5, операция 4.5, операция отношения 4.5, операция сложения 4.5, пакет 7, простое выражение 4.4, тип 3.3, фиксированный тип 3.5.9.

Пред. | Уровень выше | След.
9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ | Начало | 9.7. ОПЕРАТОРЫ ОТБОРА


9.7. ОПЕРАТОРЫ ОТБОРА
Пред. Глава 9. ЗАДАЧИ След.

9.7. ОПЕРАТОРЫ ОТБОРА

Существует три формы операторов отбора. Одна форма обеспечивает отбор с ожиданием одной или нескольких альтернатив. Две другие обеспечивают условный и временной вызовы входа.

оператор-отбора ::= отбор-с-ожиданием
   | условный-вызов-входа | временной-вызов-входа

Ссылки: временной вызов входа 9.7.3, отбор с ожиданием 9.7.1, условный вызов входа 9.7.2.

9.7.1. ОТБОР С ОЖИДАНИЕМ

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

отбор-с-ожиданием ::=
   select
      альтернатива-отбора
   {or
      альтернатива-отбора)
   [else
      последовательность-операторов]
   end select;

альтернатива-отбора ::=
   [when условие = >]
      альтернатива-отбора-с-ожиданием

альтернатива-отбора-с-ожиданием ::= альтернатива-принятия
   | альтернатива-задержки | альтернатива-завершения

альтернатива-принятия ::=
   оператор-принятия [последовательность-операторов]

альтернатива-задержки ::=
   оператор-задержки [последовательность - операторов]

альтернатива-завершения ::= terminate;

Оператор отбора с ожиданием должен содержать по крайней мере одну альтернативу принятия. В дополнение к этому оператор отбора с ожиданием может содержать либо альтернативу завершения (только одну), либо одну или несколько альтернатив задержки, либо раздел else; эти три возможности являются взаимоисключающими.

Альтернатива отбора называется открытой, если она, не начинается с зарезервированного слова when или если значение условия — TRUE. В противном случае альтернатива называется закрытой.

При выполнении оператора отбора с ожиданием в произвольном, не определенном в языке порядке вычисляются все условия, заданные после зарезервированного слова when; определяются открытые альтернативы. Для открытой альтернативы задержки вычисляется выражение длительности задержки. Для открытой альтернативы принятия входа семейства вычисляется индекс входа. Выполнение отбора с ожиданием заканчивается отбором и вычислением либо одной из открытых альтернатив, либо раздела else; правила такого отбора описываются ниже.

Первыми рассматриваются открытые альтернативы. Отбор одной из таких альтернатив производится немедленно, если возможно соответствующее рандеву, т.е. если другая задача произвела вызов соответствующего входа и ожидает его принятия. Если таким образом могут быть отобраны несколько альтернатив, то одна из них выбирается произвольно (которая именно, в языке не определено). После отбора такой альтернативы выполняются соответствующий оператор принятия и следующая за ним последовательность операторов (если она есть). Если никакое рандеву не может произойти немедленно и отсутствует раздел else, то задача ждет, пока можно будет выбрать открытую альтернативу отбора с ожиданием.

Отбор других форм альтернатив или раздела else осуществляется следующим образом.

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

• Отбирается раздел else и выполняется последовательность операторов этого раздела, если нельзя немедленно отобрать альтернативу принятия, в частности если все альтернативы закрыты.

•Отбирается открытая альтернатива завершения, если перечисленные в разд. 9.4 условия удовлетворены. Из других правил следует, что нельзя отобрать альтернативу завершения, пока существует очередь вызовов 'любого входа задачи.

Исключение PROGRAM_ERROR возбуждается, если все альтернативы закрыты и раздел else отсутствует.

Пример оператора отбора:

select
   accept DRIVER_AWAKE_SIGNAL;
or
   delay 30.0*SECONDS;
   STOP_THE_TRAIN;
end select;

Пример тела задачи с оператором отбора:

task body RESOURCE is
   BUSY : BOOLEAN := FALSE;
begin
   loop
     select
        when not BUSY=>
           accept SEIZE do
              BUSY := TRUE;
           end:
     or
        accept RELEASE do
           BUSY := FALSE;
        end;
     or
        terminate;
     end select;
   end loop;
end RESOURCE;

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

Ссылки: вход 9.5, вызов входа 9.5, выражение задержки 9.6, длительность 9.6, задача 9, индекс входа 9.5, исключение PROGRAM_ERROR 11.1, оператор задержки 9.6, оператор отбора 9.7, оператор принятия 9.5, описание 3.1, очередь вызовов входа 9.5, последовательность операторов 5.1, рандеву 9.5, условие 5.3.

Пред. | Уровень выше | След.
9.6. ОПЕРАТОРЫ ЗАДЕРЖКИ, ДЛИТЕЛЬНОСТЬ И ВРЕМЯ | Начало | 9.7.2. УСЛОВНЫЕ ВЫЗОВЫ ВХОДОВ


9.7.2. УСЛОВНЫЕ ВЫЗОВЫ ВХОДОВ
Пред. Глава 9. ЗАДАЧИ След.

9.7.2. УСЛОВНЫЕ ВЫЗОВЫ ВХОДОВ

Условный вызов входа производит вызов входа, который отменяется, если рандеву нельзя осуществить немедленно.

условный-вызов-входа ::=
select
   оператор-вызова-входа
   [последовательность-операторов]
else
   последовательность-операторов
end select;

При выполнении условного вызова входа вначале вычисляется имя входа. Затем выполняются требуемые вычисления фактических параметров, как при вызове подпрограмы (см. 6.4).

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

Если вызов входа отменен, то выполняются операторы раздела иначе. В противном случае происходит рандеву и выполняется последовательность операторов после вызова входа (если она есть).

Выполнение условного вызова входа возбуждает исключение-TASKING- ERROR, если вызванная задача уже закончила свое выполнение (см. разд. 9.10 для случая, когда вызванная задача становится аварийной).

Пример:

procedure SPIN(R : RESOURCE) is
begin
   loop
      select
         R.SEIZE;
         return;
      else
         null;
         --занято, надо подождать
      end select:
   end loop;
end;

Ссылки: аварийная задача 9.10, выполнение 4.5, выражение 4.4, задача 9, законченная задача 9.4, индекс входа 9.5, исключение TASKING_ERROR 11.1, оператор вызовов входа 9.5, оператор отбора 9.7, оператор принятия 9.5, открытая альтернатива 9.7.1, очередь вызова входа 9.5, последовательность операторов 5.1, раздел фактических параметров 6.4, рандеву 9.5, семейство входов 9.5

9.7.3. ВРЕМЕННЫЕ ВЫЗОВЫ ВХОДОВ

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

временной-вызов-входа ::=
   select
      оператор-вызова-входа
      [последовательность - операторов]
   or
      альтернатива-задержки
   end select;

При выполнении временного вызова входа вначале вычисляется имя входа. Затем выполняются требуемые вычисления фактических параметров, как при вызове подпрограммы (см. 6.4). После этого вычисляется выражение, задающее задержку, и, наконец, производится вызов входа.

Если рандеву может начаться в течение указанной длительности (или немедленно, как для условного вызова входа, если задержка отрицательная или нулевая), то оно происходит, и затем после вызова входа отменяется и выполняется возможная последовательность операторов альтернативы задержки.

Выполнение временного вызова входа возбуждает исключение TASKING_ERROR, если вызванная задача закончила свое выполнение до принятия вызова (см. также разд. 9.10 для случая, когда вызванная задача становится аварийной).

Пример:

select
   CONTROLLER. REQUEST(MEDIUM)(SOME_ITEM);
or
   delay 45.0;
   -- контроллер слишком занят, попробуйте
   -- что-либо еще
end select;

Ссылки: аварийная задача 9.10, выполнение 4.5, выражение 4.4, выражение задержки 9.6, длительность 9.6; задача 9, законченная задача 9.4, индекс входа 9.5, исключение TASKING_ERROR 11.1, оператор вызова входа 9.5, оператор задержки 9.6, оператор принятия 9.5, последовательность операторов 5.1, раздел фактических параметров 6.4, рандеву 9.5, семейство входов 9.5, условный вызов входа 9.7.2.

Пред. | Уровень выше | След.
9.7. ОПЕРАТОРЫ ОТБОРА | Начало | 9.8. ПРИОРИТЕТЫ


9.8. ПРИОРИТЕТЫ
Пред. Глава 9. ЗАДАЧИ След.

9.8. ПРИОРИТЕТЫ

Каждая задача может (но не обязательно) иметь приоритет со значением подтипа PRIORITY (типа INTEGER), описанного в предопределенном библиотечном пакете SYSTEM (см. 13.7). Меньшее значение приоритета указывает на меньшую степень важности; диапазон приоритетов определяется реализацией. Приоритет связывается с задачей, если в спецификации соответствующей задачи присутствует прагма:

pragma PRIORITY (статическое-выражение);

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

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

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

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

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

Ссылки: главная программа 10.1, задача 9, оператор вызова входа 9.5, пакет SYSTEM 13.7, подтип 3.3, прагма 2.8, раздел описаний 3.9, рандеву 9.5, спецификация задачи 9.1, статическое выражение 4.9, целый тип 3.5.4.

Пред. | Уровень выше | След.
9.7.2. УСЛОВНЫЕ ВЫЗОВЫ ВХОДОВ | Начало | 9.9. АТРИБУТЫ ЗАДАЧ И ВХОДОВ


9.9. АТРИБУТЫ ЗАДАЧ И ВХОДОВ
Пред. Глава 9. ЗАДАЧИ След.

9.9. АТРИБУТЫ ЗАДАЧ И ВХОДОВ

Для задачного объекта или значения Т определены следующие атрибуты:

T'CALLABLE | Вырабатывает значение FALSE, если выполнение указанной задачи Т либо закончено, либо завершено либо задача аварийная. В остальных случаях вырабатывает значение TRUE. Значение этого атрибута имеет предопределенный тип BOOLEAN.
T'TERMINATED | Вырабатывает значение TRUE, если указанная Т задача завершена. В остальных случаях вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN.

В дополнение к приведенным для задачного объекта Т или задачного типа Т определены атрибуты представления STORAGE-SIZE, SIZE и ADDRESS (см. 13.7.2).

Атрибут COUNT определен для входа Е задачного модуля Т. Вход может быть либо одиночным входом, либо входом семейства (в любом случае имя одиночного входа или семейства входов может быть либо простым, либо расширенным). Этот атрибут допустим только в теле Т, но не во вложенном в тело Т программном модуле.

E'COUNT | Вырабатывает число вызовов входа, присутствующих в очереди входа Е в данный момент (если атрибут вычисляется при выполнении оператора принятия входа Е, то в это число не включается вызывающая задача). Значение атрибута имеет тип универсальный-целый.

Примечание. Алгоритмы, соответствующие программы которых используют атрибут E'COUNT, обязаны учитывать возможность увеличения значения атрибута с появлением новых вызовов и уменьшения этого значения, например, при временных вызовах входа.

Ссылки: аварийная задача 9.10, атрибут 4.1.4, временной вызов входа 9.7.3, вход 9.5, завершенная задача 9.4, задача 9, задачный объект 9.2, задачный тип 9.1, законченная задача 9.4, значение логического типа TRUE 3.5.3, значение логического типа FALSE 3.5.3, квант памяти 13.7, логический тип 3.5.3, оператор принятия 9.5, очередь вызовов входов 9.5, тип универсальный целый 3.5.4, указывать 9.1.

Пред. | Уровень выше | След.
9.8. ПРИОРИТЕТЫ | Начало | 9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ


9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ
Пред. Глава 9. ЗАДАЧИ След.

9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ

Оператор прекращения переводит одну или несколько задач в аварийное состояние, предотвращая любые дальнейшие рандеву с такими задачами.

оператор-прекращения ::= abort имя-задачи {, имя-задачи};

При определении типа имени каждой задачи используется тот факт, что это задачный тип.

При выполнении оператора прекращения заданные имена задач вычисляются в порядке, который в языке не определен. Затем каждая упомянутая задача становится аварийной, если она еще не завершена; аналогично любая зависящая от упомянутой задача становится также аварийной, если она еще не завершена.

Любая аварийная задача, выполнение которой приостановлено операторами принятия, отбора или задержки, становится законченной. Любая аварийная задача, выполнение которой приостановлено при вызове входа, а соответствующее рандеву еше не началось, становится законченной и удаляется из очереди к входу. Любая аварийная задача, которая не начала свою активизацию, становится законченной (и, следовательно, завершенной). Этим заканчивается выполнение оператора прекращения.

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

Вызов входа аварийной задачи возбуждает в месте вызова исключение TASKING_ERROR. Аналогично исключение TASKING_ERROR возбуждается в любой задаче, вызвавшей вход аварийной задачи, если вызов входа все еще находится в очереди либо рандеву не окончено (вызовом входа может быть либо оператор вызова входа, либо операторы условного или временного вызова входа); исключение возбуждается не позже окончания аварийной задачи. Для любой аварийной (или законченной) задачи значение атрибута CALLABLE есть FALSE.

Если аварийное окончание задачи произошло во время изменения в задаче некоторой переменной, то значение этой переменной не определено.

Пример:

abort USER, TERMINAL.all, POOL(3);

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

Ссылки: аварийное состояние при рандеву 11.5, активизация 9.3, атрибут 4.1.4, атрибут CALLABLE 9.9, временной вызов входа 9.7.3, завершенная задача 9.4, зависимая задача 9.4, задача 9, значение логического типа FALSE 3.5.3, имя 4.1, исключение TASKING_ERROR 11.1, обработка имени 4.1, обработчик исключения 11.2, оператор 5, оператор вызова входа 9.5, оператор задержки 9.6, оператор отбора 9.7, оператор принятия 9.5, очередь вызовов входов 9.5, рандеву 9.5, условный вызов входа 9.7.2.

Пред. | Уровень выше | След.
9.9. АТРИБУТЫ ЗАДАЧ И ВХОДОВ | Начало | 9.11. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ


9.11. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ
Пред. Глава 9. ЗАДАЧИ След.

9.11. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ

Обычными средствами передачи данных между задачами являются операторы вызова и принятия входов.

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

О действиях, выполняемых программой, использующей разделяемые переменные, всегда могут быть сделаны следующие предположения:

• Если в интервале времени между двумя точками синхронизации задача считывает разделяемую переменную скалярного или ссылочного типа, то эта переменная не изменяется никакой другой задачей в течение данного интервала времени.

• Если в интервале времени между двумя точками синхронизации задача изменяет разделяемую переменную скалярного или ссылочного типа, то эта переменная не считывается и не изменяется никакой другой задачей в течение данного интервала времени.

Выполнение программы ошибочно, если какое-либо из этих предположений нарушено.

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

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

Для задания того, что каждое считывание или изменение значения разделяемой переменной является для этой переменной точкой синхронизации, может быть использована прагма SHARED, т.е. для данной переменной (но не обязательно для остальных) сделанных выше предположения справедливы. Форма этой прагмы следующая:

pragma SHARED (простое-имя-переменной);

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

Реализация должна ограничивать объекты, для которых допустима прагма SHARED, объектами, для которых каждое прямое считывание или прямое изменение реализуется неделимыми операциями.

Ссылки: активизация 9.3, глобальный 8.1, задача 9, изменение значение 6.2 канонический порядок 11.6, оператор вызова входа 9.5, оператор принятия 9.5, ошибочный 1.6, переменная 3.2.1, прагма 2.8, присваивание 5.2, простое имя 3.1, 4.1, раздел описаний 3.9, рандеву 9.5, спецификация пакета 7.1, тип 3.3, чтение значения 6.2.

Пред. | Уровень выше | След.
9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ | Начало | 9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ


9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ
Пред. Глава 9. ЗАДАЧИ След.

9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ

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

loop
   -— выработка следующего символа CHAR
   BUFFER.WRITE(CHAR);
   exit when CHAR = ASCII.EOT;
end loop;

потребляющая задача — операторы:

loop
   BUFFER.READ(CHAR);
   -— использование символаСНАР
   exit when CHAR = ASCII.EOT;
end loop;

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

task BUFFER is
   entry READ (С : out CHARACTER);
   entry WRITE (C : in   CHARACTER);
end:

task body BUFFER is
   POOL_SIZE : constant INTEGER := 100:
   POOL      : array(1 .. POOL_SIZE) of CHARACTER;
   COUNT     : INTEGER range 0 .. POOL_SIZE := 0;
   IN_INDEX, OUT_INDEX : INTEGER range 1 .. POOL_SIZE := 1;
begin
   loop
      select
         when COUNT < POOL_SIZE =>
            accept WRITE(C : in CHARACTER) do
               POOL(IN_INDEX) := C;
            end;
            IN_INDEX := IN_INDEX mod POOL_SIZE + 1;
            COUNT    := COUNT + 1;
      or when COUNT > 0 =>
            accept READ(C ; out CHARACTER) do
               C := POOL(OUT_INDEX);
            end;
            OUT_INDEX := OUT_INDEX mod POOL_SIZE + 1;
            COUNT     := COUNT - 1;
      or
         terminate;
      end select:
   end loop:
end BUFFER;

Пред. | Уровень выше | След.
9.11. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ | Начало | Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ


Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ
Пред. След.

Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ

Содержание

10.1. КОМПИЛИРУЕМЫЕ МОДУЛИ. БИБЛИОТЕЧНЫЕ МОДУЛИ
10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ
10.3. ПОРЯДОК КОМПИЛЯЦИИ
10.4. ПРОГРАММНАЯ БИБЛИОТЕКА
10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ
10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ

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

Ссылки: задача 9, компилируемый модуль 10.1, компиляция 10.1, конкретизация настройки 12.3, настраиваемое тело 12.2, описание настройки 12.1, описание пакета 7.1, описание подпрограммы 6.1, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3.

10.1. КОМПИЛИРУЕМЫЕ МОДУЛИ. БИБЛИОТЕЧНЫЕ МОДУЛИ

Текст программы может подаваться на вход компилятора в виде одной или нескольких компиляций. Каждая компиляция представляет собой последовательность компилируемых модулей.

компиляция ::= (компилируемый-модуль)

компилируемый-модуль ::=
    спецификатор-контекста библиотечный-модуль
  | спецификатор-контекста вторичный-модуль

библиотечный-модуль ::= описание-подпрограммы
  | описание-пакета | описание-настройки
  | конкретизация-настройки | тело-подпрограммы

вторичный-модуль ::=
    тело-библиотечного-модуля | субмодуль

тело-библиотечного-модуля ::=
    тело-подпрограммы | тело-пакета

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

Результат компилирования библиотечного модуля состоит в том, чтобы определить (или переопределить) его как модуль программной библиотеки. По правилам видимости каждый библиотечный модуль рассматривается как описание, приведенное непосредственно внутри пакета STANDARD.

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

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

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

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

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

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

Ссылки: библиотечный модуль 10.5, видимость 8.3, должно 1.6, допустимо 1.6, задача 9, знак операции 6.1, идентификатор 2.3, имя 4.3, конкретизация настройки 12.3, локальное описание 8.1, находится непосредственно в 8.1, окружение 10.4, операция 4.5, описание 3.1, описание настройки 12.1, описание пакета 7.1, описание переименования 8.5, описание подпрограммы 6.1, пакет STANDARD 8.6, параметр подпрограммы 6.2, подпрограмма 6, прагма 2.8, программный модуль 6, простое имя 4.1, процедура 6.1, скрытие 8, совмещение 6.6, 8.7, соответствующее тело 10.1.1, спецификатор контекста 10.1.1, тело пакета 7.1, тело подпрограммы 6.3, указывать 6.1.

10.1.1. СПЕЦИФИКАТОРЫ КОНТЕКСТА. СПЕЦИФИКАТОРЫ СОВМЕСТНОСТИ

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

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

спецификатор-совместности ::=
   with простое-имя-модуля {, простое-имя-модуля};

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

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

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

Спецификаторы совместности задают зависимости между компилируемыми модулями, т.е. компилируемый модуль зависит от других библиотечных модулей, упомянутых в спецификаторе контекста. Зависимости между модулями учитываются при определении допустимого порядка компиляции (и перекомпиляции) компилируемых модулей (см. разд. 10.3), а также при определении допустимого порядка предвыполнения компилируемых модулей (см. разд. 10.5).

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

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

Пример 1. Главная, программа.

Ниже приведен пример главной программы, состоящей из одного компилируемого модуля — процедуры печати вещественных корней квадратного уравнения. Предполагается, что в программной библиотеке уже содержится предопределенный пакет TEXT-10 и заданный пользователем пакет REAL-OPERATIONS (содержащий определения типа REAL и пакетов REAL-10 и REAL-FUNCTIONS). Такие пакеты могут быть использованы и другими главными программами.

with TEXT_IO, REAL_OPERATIONS; use REAL_OPERATIONS;

procedure QUADRATIC_EQUATION is
   А, В, С, D : REAL:
   use REAL_IO,  -- обеспечивает прямую видимость GET и PUT для REAL
       TEXT_IO,        -— обеспечивает прямую видимость NEW-LINE и PUT для строк
       REAL_FUNCTIONS; -— обеспечивает прямую видимость функции SORT
begin
   GET(A); GET(B); GET(C);
   D := B**2 - 4.0*A*C;
   if D < 0.0 then
      PUT("lmaginary Roots.");
   else
      PUT("Real Roots : XI = ");
      PUT((-B - SQRT(D))/(2.0*A)); PUT(" X2 = ");
      PUT((-B + SQRT(D))/(2.0*A));
   end if;
   NEW_LINE;
end QUADRATIC_EQUATION;

Примечание к примеру. В спецификаторах совместности компилируемого модуля надо упоминать имена только тех библиотечных подпрограмм или пакетов, видимость которых действительно необходима внутри модуля. Нет необходимости (и не следует) упоминать имена других библиотечных модулей, используемых внутри модулей, перечисленных в этих спецификаторах совместности, кроме тех, которые используются непосредственно в данном компилируемом модуле. Например, в теле пакета REAL-OPERATIONS могут потребоваться некоторые элементарные операции, определенные в других пакетах. Но эти пакеты не надо упоминать в спецификаторе совместности процедуры QUADRATIC-EQUATION, так как в ее теле элементарные операции не вызываются непосредственно.

Ссылки: библиотечный модуль 10.1, видимость 8.3, вторичный модуль 10.1, главная программа 10.1, должно 1.6, допустимо 1.6, имя 4.1, компилируемый модуль 10.1, настраиваемое тело 12.2, настраиваемый модуль 12.1, непосредственная видимость 8.3, описание пакета 7.1, описание подпрограммы 6.1, пакет 7, пакет STANDARD 9.6, пред выполнение 3.9, программный модуль 6, простое имя 4.1, процедура 6.1, скрытие 8.3, спецификатор использования 8.4, субмодуль 10.2, тело пакета 7.1, тело подпрограммы 6.3, тип 3.3, экземпляр 12.3.

10.1.2. ПРИМЕРЫ КОМПИЛИРУЕМЫХ МОДУЛЕЙ

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

procedure PROCESSOR is
   SMALL : constant := 20;
   TOTAL : INTEGER := 0;

   package STOCK is
      LIMIT : constant := 1000;
      TABLE : array (1 .. LIMIT) of INTEGER;
      procedure RESTART;
   end STOCK;

   package body STOCK is
      procedure RESTART is
      begin
         for N in 1 .. LIMIT loop
            TABLE(N) := N;
         end loop;
      end;
   begin
      RESTART;
   end STOCK;

   procedure UPDATE(X : INTEGER) is
      use STOCK;
   begin
      ...
      TABLE(X) := TABLE(X) + SMALL;
   end UPDATE;

begin
   STOCK.RESTART;   -- переинициализация TABLE
end PROCESSOR;

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

Пример 2. Несколько компилируемых модулей.

package STOCK is
   LIMIT : constant := 1000;
   TABLE : array (1 .. LIMIT) of INTEGER;
   procedure RESTART;
end STOCK;

package body STOCK is
   procedure RESTART is
   begin
      for N in 1 .. LIMIT loop
         TABLE(N) := N;
      end loop;
   end;
begin
   RESTART;
end STOCK;

with STOCK;
procedure PROCESSOR is

   SMALL : constant   := 20;
   TOTAL : INTEGER := 0;

   procedure UPDATEIX : INTEGER) is
      use STOCK;
   begin
      TABLE(X) := TABLE(X) + SMALL;
   end UPDATE;

begin
   ...
   STOCK.RESTABT; —-  nepeинициализация TABLE
   ...
end PROCESSOR

Заметим, что в последней версии примера в пакете STOCK невидимы внешние идентификаторы, отличные от предопределенных (в пакете STANDARD). В частности, в нем не используются идентификаторы SMALL и TOTAL, описанные в процедуре PROCESSOR; в противном случае пакет STOCK нельзя выделить из процедуры PROCESSOR, как это сделано выше. С другой стороны, процедура PROCESSOR зависит от пакета STOCK и упоминает его в спецификаторе совместности. Поэтому пакет STOCK можно использовать в расширенном имени и спецификаторе использования.

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

Ссылки: видимость 8.3, идентификатор 2.3, компилируемый модуль 10.1, описание 3.1, пакет 7, пакет STANDARD 8.6, программа 10, спецификатор использования 8.4, спецификатор совместности 10.1.1, спецификация пакета 7.1, тело пакета 7.1.

Пред. | Уровень выше | След.
9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ | Начало | 10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ


10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ
Пред. Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ След.

10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ

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

след-тела ::=
   спецификация-подпрограммы is separate;
 | package body простое-имя-пакета is separate;
 | task body простое-имя-задачи is separate;

субмодуль :: =
   separate (имя-родительского-модуля) соответствующее-тело

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

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

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

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

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

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

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

Ссылки: библиотечный модуль 10.1, видимость 8.3, задача 9, задачный модуль 9.1, идентификатор 2.3, имя 4.1, компилируемый модуль 10.1, локальное описание 8.1, настраиваемое тело 12.2, настраиваемый модуль 12, непосредственная видимость 8.3, непосредственное вхождение 8.1, описание 3.1, описание переименования 8.5, пакет 7, подпрограмма 6, предвыполнение 3.9, программа 10, программный модуль 6, простое имя 4.1, раздел описаний 3.9, раздельная компиляция 10.1, расширенное имя 4.1.3, скрыт описанием 8.3, совмещение 8.3, согласованный 6.3.1, соответствующее тело 3.9, спецификатор использования 8.4, спецификатор контекста 10.1.1, спецификатор совместности 10.1.1, спецификация подпрограммы 6.1, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.1.

10.2.1. ПРИМЕРЫ СУБМОДУЛЕЙ

Сначала процедура ТОР оформлена в виде компилируемого модуля без субмодулей.

with TEXT_IO;
procedure TOP is

   type REAL is digits 10;
   R, S ; REAL := 1.0;

   package FACILITY is
      PI : constant := 3.14159_26536;
      function   F (X : REAL) return REAL;
      procedure  G (Y, Z : REAL);
   end FACILITY;

   package body FACILITY is
      -— предшествуют некоторые локальные описания

   function F(X : REAL) return REAL is
   begin
      -— последовательность операторов функции F
      ...
   end F;

   procedure G(Y, Z : REAL) is
      -— использующие пакет TEXT_IO локальные процедуры
      ...
   begin
      -— последовательность операторов процедуры G
      ...
   end G;

end FACILITY;

   procedure TRANSFORM(U : in out REAL) is
      use FACILITY;
   begin
      U := F(U);
      ...
   end TRANSFORM;

begin -- TOP
   TRANSFORM(R);
   FACILITY.G(R, S);
end TOP;

Тело пакета FACILITY и процедуру TRANSFORM можно представить в виде раздельно компилируемых субмодулей модуля ТОР. Тело процедуры G также может быть представлено как субмодуль модуля FACILITY.

Пример 3:

procedure TOP is

   type REAL is digits 10;
   R, S : REAL :== 1.0;
   package FACILITY is
      PI : constant := 3.14159_26536;
      function   F (X : REAL) return REAL;
      procedure G (Y, Z : REAL);
   end FACILITY;

   package body FACILITY is separate;
   procedure TRANSFORM (U : in out REAL) is separate;

begin --  TOP
   TRANSFORM(R);
   ...
   FACILITY.G(R, S):
end TOP;

separate (TOP)
procedure TRANSFORM(L) : in out REAL) is
   use FACILITY;
begin
   U := F(U);
   ...
end TRANSFORM;

separate (TOP)
package body FACILITY is
   -— предшествуют некоторые локальные описания
   function F(X : REAL) return REAL is
   begin
      -- последовательность операторов функции F
      ...
   end F;

   procedure G (Y, Z : REAL) is separate; -- след тела G

end FACILITY;

with TEXT_IO;
separate (TOP.FACILITY)  -- полное имя пакета FACILITY
procedure G(Y, Z : REAL) is
   --использующие ТЕХТ_Ю локальные процедуры
begin
   -- последовательность операторов процедуры G
   ...
end G;

В этом примере TRANSFORM и FACILITYявляются субмодулями процедуры TOP, а G -субмодулем пакета FACILITY. Видимость в этом пакете такая же, как и в предыдущем, с одним отличием : TEXT_IO используется только в G, по этому соответствующий спецификатор совместности написан для G, а не для процедуры TOP. В остальном видимость идентификаторов в соответствующих телах программ обеих версий одинакова. Например, в соответствующем теле субмодуля G (непосредственно) видимы процедура TOP, тип REAL, переменные R и S, пакет FACILITY и содержащиеся в нем именнованое число PI и подпрограммы F и G.

Ссылки: видимость 8.3, идентификатор 2.3, именованное число 3.2, компилируемый мо-Идуль 10.1, локальное описание 8.1, пакет 7.1, переменная 3.2.1, подпрограмма 6, процедура 6, |след тела 10.2, соответствующее тело 3.9, спецификатор совместности 10.1.1, тело пакета 7.1, |тело процедуры 6.3, тип 3.3.

Пред. | Уровень выше | След.
Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ | Начало | 10.3. ПОРЯДОК КОМПИЛЯЦИИ


10.3. ПОРЯДОК КОМПИЛЯЦИИ
Пред. Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ След.

10.3. ПОРЯДОК КОМПИЛЯЦИИ

Правила, определяющие порядок компилирования модулей, являются непосредственным следствием правил видимости и, в частности, того факта, что любой библиотечный модуль, упомянутый в спецификаторе контекста компилируемого модуля, видим в нем.

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

Компилирование, при котором в компилируемом модуле обнаружена ошибка, считается неудавшимся и никак не влияет на программную библиотеку; то же самое относится и к перекомпиляции (никакой компилируемый модуль не может стать устаревшим вследствие такой перекомпиляции).

Порядок компилирования компилируемых модулей программы должен отвечать частичной упорядоченности, определенной приведенными выше правилами.

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

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

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

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

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

Примеры порядка компиляции:

а. В примере 1 (см. 10.1.1) процедура QUADRATIC-EQUATION должна компилироваться после библиотечных пакетов TEXT-10 и REAL-OPERATIONS, так как они упомянуты в спецификаторе совместности процедуры.

б. В примере 2 (см. 10.1.2) тело пакета STOCK должно компилироваться после соответствующей спецификации пакета.

в. В примере 2 (см. 10.1.2) спецификация пакета STOCK должна компилироваться до процедуры PROCESSOR. С другой стороны, процедура PROCESSOR может компилироваться как до, так и после тела пакета STOCK.

г. В примере 3 (см. 10.2.1) процедура G должна компилироваться после пакета TEXT-10, так как этот пакет упомянут в спецификаторе совместности процедуры G. В то же время пакет TEXT-10 может компилироваться как до, так и после процедуры ТОР.

д. В примере 3 (см. 10.2.1) субмодули TRANSFORM и FACILITY должны компилироваться после главной программы ТОР. Субмодуль G должен компилироваться после его родительского модуля FACILITY.

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

Ссылки: библиотечный модуль 10.1, видимость 8.3, вторичный модуль 10.1, имя 4.1, компилируемый модуль 10.1, компиляция 10.1, локальное описание 8.1, настраиваемый модуль 12, настраиваемое тело 12.2, описание настройки 12.1, описание подпрограммы 6.1, пакет 7, переменная 3.2.1, прагма INLINE 6.3.2, предвыполнение 3.9, процедура 6.1, родительский модуль 10.2, соответствующее тело 3.9, спецификатор контекста 10.1.1, спецификатор совместности 10.1.1, спецификация пакета 7.1, спецификация подпрограммы 6.1, субмодуль 10.2, тело пакета 7.1, тело подпрограммы 6.3, тело процедуры 6.3, тип 3.3.

Пред. | Уровень выше | След.
10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ | Начало | 10.4. ПРОГРАММНАЯ БИБЛИОТЕКА


10.4. ПРОГРАММНАЯ БИБЛИОТЕКА
Пред. Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ След.

10.4. ПРОГРАММНАЯ БИБЛИОТЕКА

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

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

Примечание. Для компилируемых модулей компиляции создается одна программная библиотека. Возможно существование различных программных библиотек; в языке не определены правила их именования — это обеспечивается окружением системы программирования.

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

Ссылки: компилируемый модуль 10.1, порядок компиляции 10.3, программа 10.1, программная библиотека 10.1, спецификатор использования 8.4, спецификатор контекста 10.1.1, спецификатор совместности 10.1.1, субмодуль 10.2.

Пред. | Уровень выше | След.
10.3. ПОРЯДОК КОМПИЛЯЦИИ | Начало | 10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ


10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ
Пред. Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ След.

10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ

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

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

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

Эта прагма записывается в виде

pragma ELABORATE (простое-имя-библиотечного-модуля {, простое-имя-библиотечного-модуля });

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

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

Ссылки: аргумент прагмы 2.8, библиотечный модуль 10.1, в некотором порядке 1.6, вторичный модуль 10.1, главная программа 10.1, допустим 1.6, зависимость между компилируемыми ^модулями 10.3, имя 4.1, компилируемый модуль 10.1, неправильна 1.6, простое имя 4.1, специ-|фикатор контекста 10.1.1, спецификатор совместности 10.1.1, субмодуль 10.2, раздельная компиляция 10.1.

Пред. | Уровень выше | След.
10.4. ПРОГРАММНАЯ БИБЛИОТЕКА | Начало | 10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ


10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ
Пред. Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ След.

10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ

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

Компилятор может определить, что некоторые операторы или подпрограммы никогда не будут выполняться, например, если их выполнение зависит от условия, имеющего значение FALSE. В таком случае соответствующие части объектного машинного кода могут быть опущены. Такое правило позволяет на уровне языка производить условную компиляцию.

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

Ссылки: возбуждение исключения 11.1, выражение 4.7, вычисление 4.5, исключение 11, логическое значение FALSE 3.5.3, оператор 5, описание 3.1, подпрограмма 6, предвыполнение 3.9, программа 10, статическое выражение 4.9, условие 5.3.

Пред. | Уровень выше | След.
10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ | Начало | Глава 11. ИСКЛЮЧЕНИЯ


Глава 11. ИСКЛЮЧЕНИЯ
Пред. След.

Глава 11. ИСКЛЮЧЕНИЯ

Содержание

11.1. ОПИСАНИЯ ИСКЛЮЧЕНИЙ
11.2. ОБРАБОТЧИКИ ИСКЛЮЧЕНИЙ
11.3. ОПЕРАТОРЫ ВОЗБУЖДЕНИЯ
11.4. ОБРАБОТКА ИСКЛЮЧЕНИЙ
11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ
11.6. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ
11.7. ПОДАВЛЕНИЕ ПРОВЕРОК

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

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

Ссылки: имя 4.1, обработчик исключения 11.2, оператор блока 5.6, оператор возбуждения 11.3, ошибочная ситуация 1.6, распространение исключения 11.4.1, 11.4.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3.

11.1. ОПИСАНИЯ ИСКЛЮЧЕНИЙ

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

описание-исключения ::= список-идентификаторов: exception;

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

В языке предопределены следующие исключения. Они возбуждаются при обнаружении описанных ниже ситуаций.

CONSTRAINT_ERROR | Это исключение возбуждается в любой из следующих ситуаций: при попытке нарушить ограничение диапазона, ограничение индекса или ограничение дискриминанта; при попытке использовать компоненту записи, не существующую для текущих значений дискриминанта; при попытке использовать именуемую компоненту, индексируемую компоненту, отрезок или атрибут объекта, обозначенного ссылочным значением, если этот объект не существует, поскольку ссылочное значение пустое
NUMERIC_ERROR | Это исключение возбуждается при выполнении предопределенной числовой операции, которая не может выработать верный результат (для вещественных типов в пределах предписанной точности). Сюда относится также случай использования реализацией предопределенных числовых операций для выполнения, вычисления или предвыполнения некоторой конструкции. Данные в разд. 4.5.7 правила определяют случаи, для которых от реализации не требуется возбуждения исключения в случае возникновения ошибочной ситуации (см. также 11.6).
PROGRAM_ERROR | Это исключение возбуждается при попытке вызвать подпрограмму, активизировать задачу или предвыполнить конкретизацию настройки, если тело соответствующего модуля еще не предвыполнено. Оно также возбуждается, если выполнение функции завершается через end (см. 6.5), при выполнении оператора отбора с ожиданием, когда отсутствует раздел else, a все альтернативы закрыты (см. 9.7.1). Наконец, в зависимости от реализации исключение может возбуждаться при попытке выполнить ошибочное действие и при некорректной зависимости от порядка (см. 1.6).
STORAGE_ERROR | Это исключение возбуждается в одной из следующих ситуаций: при вычислении генератора; когда не хватает динамической памяти, выделенной для задачи; когда исчерпана память для набора генерируемых объектов; при предвыполнений элемента описания или при вызове подпрограммы, если памяти недостаточно.
TASKING_ERROR | Это исключение возбуждается при возбуждении исключений во время взаимодействия задач (см. 9 и 11.5).

Примечание. Описанные выше ситуации могут возникать, не возбуждая соответствующих исключений, если была использована прагма SUPPRESS подавления проверок (см. 11.7).

Примеры описанных пользователем исключений:

SINGULAR : exception;
ERROR    : exception;
OVERFLOW, UNDERFLOW : exception;

Ссылки: вещественный тип 3.5.6, задача 9, идентификатор 2.3, имя 4.1, исключение 11, компонента записи 3.7, конкретизация 12.3, конкретизация настройки 12.3, набор 3.8, настраиваемое тело 12.2, настраиваемый модуль 12, неявное описание 12.3, обработчик исключения 11.2, объект 3.2, оператор возбуждения 11.3, оператор возврата 5.8, описание 3.1, подпрограмма 6, ссылочное значение 3.8, тело задачи 9.1, тело подпрограммы 6.3.

Контекст исключения CONSTRAINT_ERROR: агрегат 4.3.1, 4.3.2, атрибут дискретного типа 3.5.5, генератор 4.8, именованная компонента 4.1.3, индекс входа 9.5, индексированная компонента 4.1.1, квалифицированное выражение 4.7, логическая операция 4.5.1, ограничение 3.3.2, ограничение диапазона 3.5, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, оператор присваивания 5.2, 5.2.1, операция возведения в степень 4.5.6, описание объекта 3.2.1, отрезок 4.1.2, преобразование типа 4.6, предвыполнение формального параметра настройки 12.3, пустое ссылочное значение 3.8, сопоставление параметров 6.4.1, указание подтипа 3.3.2.

Контекст исключения NUMERIC_ERROR: атрибут дискретного типа 3.5.5, неявное преобразование 3.5.4, 3.5.6, 4.6, операция над числовым типом 4.5, 4.5.7, числовая операция 3.5.5, 3.5.8, 3.5.10.

Контекст исключения PROGRAM_ERROR: выход из функции 6.5, контроль предвыполнения 3.9, 7.3, 9.3, 12.2, набор 3.8, некорректная зависимость от порядка 1.6, отбор с ожиданием 9.7.1, ошибочный 1.6, предвыполнение 3.9.

Контекст исключения STORAGE_ERROR: генератор 4.8.

Контекст исключения TASKING_ERROR: активизация задачи 9.3, вызов входа 9.5, 9.7.2, 9.7.3, исключения при взаимодействии задач 11.5, оператор прекращения 9.10.

Пред. | Уровень выше | След.
10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ | Начало | 11.2. ОБРАБОТЧИКИ ИСКЛЮЧЕНИЙ


11.2. ОБРАБОТЧИКИ ИСКЛЮЧЕНИЙ
Пред. Глава 11. ИСКЛЮЧЕНИЯ След.

11.2. ОБРАБОТЧИКИ ИСКЛЮЧЕНИЙ

Ответная реакция на одно или несколько исключений определяется обработчиком исключения.

обработчик - исключения :: =
   when выбор-исключения { | выбор-исключения) => последовательность-операторов

выбор-исключения ::= имя-исключения | others

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

begin
   последовательность - операторов
exception
   обработчик - исключения
   {обработчик-исключения}
end

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

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

Пример:

begin
   -- последовательность операторов
exception
   when SINGULAR | NUMERIC.ERROR =>
      PUT(" MATRIX IS SINGULAR ");
   when others =>
      PUT(" FATAL ERROR ");
      raise ERROR;
end;

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

Ссылки: видимость 8.3, имя 4.1, исключение 11, настраиваемое тело 12.2, настраиваемый модуль 12.1, обработка исключения 11.4, оператор блока 5.6, оператор возбуждения 11.3, оператор возврата 5.8, последовательность операторов 5.1, раздел описаний 3.9, тело задачи 9.1, тело модуля 9, 9.1, тело пакета 7.1, тело подпрограммы 6.3, тело функции 6.3.

Пред. | Уровень выше | След.
Глава 11. ИСКЛЮЧЕНИЯ | Начало | 11.3. ОПЕРАТОРЫ ВОЗБУЖДЕНИЯ


11.3. ОПЕРАТОРЫ ВОЗБУЖДЕНИЯ
Пред. Глава 11. ИСКЛЮЧЕНИЯ След.

11.3. ОПЕРАТОРЫ ВОЗБУЖДЕНИЯ

Оператор возбуждения возбуждает исключение.

оператор-возбуждения ::=
   raise [имя-исключения];

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

Примеры:

raise SINGULAR;
raise NUMERIC_ERROR; -- явно возбуждается предопределенное исключение
raise;               -— только внутри обработчика исключения

Ссылки: задачный модуль 9, имя 4.1, исключение 11, настраиваемый модуль 12, пакет 7, подпрограмма 5.1, последовательность операторов 5.1.

Пред. | Уровень выше | След.
11.2. ОБРАБОТЧИКИ ИСКЛЮЧЕНИЙ | Начало | 11.4. ОБРАБОТКА ИСКЛЮЧЕНИЙ


11.4. ОБРАБОТКА ИСКЛЮЧЕНИЙ
Пред. Глава 11. ИСКЛЮЧЕНИЯ След.

11.4. ОБРАБОТКА ИСКЛЮЧЕНИЙ

После возбуждения исключения нормальное выполнение программы прекращается и управление, передается обработчику исключения. Выбор обработчика зависит от места возбуждения: при выполнении операторов или при предвыполнении описаний.

Ссылки: возбуждение исключения 11.3, исключение 11, обработчик исключения 11.2, оператор 5, описание 3.1, предвыполнение 3.1, 3.9.

11.4.1. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЫПОЛНЕНИИ ОПЕРАТОРОВ

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

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

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

Если исключение возбуждено в последовательности операторов окружения, не содержащего обработчик этого исключения, то выполнение последовательности операторов прекращается. Дальнейшие действия зависят от природы окружения:

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

б) Для оператора блока — то же исключение повторно возбуждается непосредственно после оператора блока (т. е. в самом вложенном объемлющем окружении или в операторе принятия, содержащем этот оператор блока).

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

г) Для тела задачи — задача становится законченной.

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

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

Пример:

function FACTORIAL (N : POSITIVE) return FLOAT is
begin

   if N = 1 then
      return 1.0;
   else
      return FLOAT(N) * FACTORIAL(N-I);
   end if;
exception
   when NUMERIC_ERROR => return FLOATSAPE_LARGE;
end FACTORIAL;

Если при умножении возбуждается исключение NUMERIC_ERROR, то значение FLOAT'SAFE- LARGE возвращается обработчиком исключения. Это значение будет вызывать возбуждение исключения NUMERIC_ERROR при вычислении выражения в каждом из оставшихся обращений к этой функции. Таким образом, для больших значений N эта функция всегда будет возвращать значение FLOAT'SAFE-LARGE.

Пример:

procedure P is
   ERROR : exception;
   procedure R;

   procedure Q is
   begin
      R;
      ... -— ошибочная ситуация 2
      exception
      ...
      when ERROR => -— обработчик Е2
   end Q;

   procedure R is
   begin
      ...  -— ошибочная ситуация З
   end R;

begin
   ...  —- ошибочная ситуация 1
   Q;
   ...
exception
   ...
   when ERROR =>    -- обработчик Е1
   ...
end P;

Могут возникнуть следующие случаи:

1. Если исключение ERROR возбуждено при выполнении последовательности операторов внешней процедуры P, то выполнение процедуры Р заканчивает обработчик Е1, расположенный внутри Р.

2. Если исключение ERROR возбуждено при выполнении последовательности операторов процедуры Q, то обработчик Е2, расположенный внутри Q, закончит ее выполнение. По окончании выполнения этого обработчика управление будет возвращено в точку вызова процедуры Q.

3. Если исключение ERROR возбуждено в теле процедуры R, вызываемой из процедуры Q, то выполнение процедуры R прекращается и то же самое исключение возбуждается в теле Q. Затем обработчик Е2 заканчивает выполнение процедуры Q, как и в случае 2.

Заметим, что в случае 3 возбуждение исключения в R приводит (косвенно) к передаче управления обработчику, являющемуся частью Q и, следовательно, не вложенному в R. Заметим также, что если бы внутри R был задан обработчик с выбором others, то в случае 3 вместо непосредственного завершения R выполнился бы этот обработчик.

Наконец, если бы исключение ERROR было описано в R, а не в Р, то обработчики Е1 и Е2 не могли бы обеспечивать обработку исключения ERROR, так как этот идентификатор не был бы видимым внутри тел Р и Q. В случае 3, однако, это исключение могло бы быть обработано в Q с помощью обработчика с выбором исключения others.

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

Предопределенные исключения — это исключения, которые могут распространяться базовыми и предопределенными операциями.

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

Ссылки: базовая операция типа 3.3.3, библиотечный модуль 10.1, вызов подпрограммы 6.4, выполнение 9.4, главная программа 10.1, зависимая задача 9.4, задача 9, исключение 11, исключение NUMERIC_ERROR 11.1, конкретизация настройки 12.3, настраиваемый модуль 12, обработчик исключения 11.2, окружение 11.1, оператор 5, оператор блока 5.6, оператор принятия 9.5, пакет 7, подпрограмма 6, последовательность операторов 5.1, предвыполнение 3.1, 3.9, предопределенная операция 4.5, процедура 6.1, раздел описаний 3.9, след тела 10.2, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, элемент описания 3.9.

11.4.2. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ПРЕДВЫПОЛНЕНИИ ОПИСАНИЙ

Если исключение возбуждено при предвыполнении раздела описаний данного окружения, то это предвыполнение прекращается. Дальнейшее действие зависит от природы окружения.

а) Для тела подпрограммы — то же исключение повторно возбуждается в точке вызова подпрограммы, кроме случая, когда эта подпрограмма является главной программой, — тогда ее выполнение прекращается.

б) Для оператора блока — то же исключение повторно возбуждается непосредственно после оператора блока.

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

г) Для тела задачи — задача становится законченной, а в точке активизации задачи возбуждается исключение TASKING_ERROR; как пояснено в разд. 9.3.

Если исключение возбуждается во время предвыполнения либо описания пакета, либо описания задачи, то это предвыполнение прекращается; дальнейшее действие зависит от природы описания.

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

Говорят, что повторно возбуждаемое исключение (как рассмотрено выше в пп. а) — г)) распространено либо выполнением подпрограммы или оператора блока, либо предвыполнени-ем описания пакета, описания задачи или тела пакета.

Пример исключения в разделе описания оператора блока (случай б}):

procedure P is
   ...
begin
   declare
      N: INTEGER := F;  -- ФУНКЦИЯ F может возбуждать исключение ERROR
   begin
      ...
   exception
      when ERROR =>    -- обработчик Е1
   end;

exception
   when ERROR =>    -- обработчик Е2
end P;

-- если исключение ERROR возбуждено в описании N, то
-- оно обрабатывается обработчиком Е2

Ссылки: активизация задачи 9.3, библиотечный модуль 10.1, вызов подпрограммы 6.4, главная программа 10.1, задача 9, законченная задача 9.4, исключение 11, исключение TASKING - ERROR 11.1, окружение 11.2, оператор блока 5.6, описание задачи 9.1, описание пакета 7.1, подпрограмма 6, предвыполнение 3.1, 3.9, раздел описаний 3.9, след тела 10.2, спецификация пакета 7.1, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, элемент описания 3.9.

Пред. | Уровень выше | След.
11.3. ОПЕРАТОРЫ ВОЗБУЖДЕНИЯ | Начало | 11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ


11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ
Пред. Глава 11. ИСКЛЮЧЕНИЯ След.

11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ

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

Когда задача вызывает вход другой задачи, то в точке этого вызова в вызывающей задаче возбуждается исключение TASKING_ERROR, если вызванная задача закончена до принятия вызова входа или к времени этого вызова.

Рандеву может иметь аварийное окончание в двух случаях:

а) если исключение возбуждено в операторе принятия и не обработано во внутреннем окружении. В этом случае выполнение оператора принятия прекращается, и то же исключение повторно возбуждается непосредственно после оператора принятия в вызванной задаче; исключение также распространяется на вызывающую задачу в точку вызова входа,

б) если задача, содержащая оператор принятия, закончена аварийно в результате выполнения оператора прекращения. В этом случае исключение TASKING - ERROR возбуждается в вызывающей задаче в точке вызова входа.

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

Ссылки: аварийная задача 9.10, вызов входа 9.5, задача 9, законченная задача 9.4, исключение 11, исключение TASKING_ERROR 11.1, окружение 11.2, оператор прекращения 9.10, оператор принятия 9.5, рандеву 9.5.

Пред. | Уровень выше | След.
11.4. ОБРАБОТКА ИСКЛЮЧЕНИЙ | Начало | 11.6. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ


11.6. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ
Пред. Глава 11. ИСКЛЮЧЕНИЯ След.

11.6. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ

В данном разделе описаны условия, при которых в реализации можно выполнять те или иные действия раньше или позже, чем это определено правилами языка.

В целом, если правила языка задают порядок некоторых действий [канонический порядок}, реализация может использовать альтернативный порядок при гарантии, что такое переупорядочивание не скажется на результате выполнения программы. В частности, если при выполнении программы в каноническом порядке не возбуждается никакое исключение, то также никакие исключения не должны возбуждаться при выполнении переупорядоченной программы. С другой стороны, если порядок некоторых действий не определен языком, то реализация может использовать любой порядок. (Например, аргументы предопределенной операции могут вычисляться в любом порядке, так как правила из разд. 4.5 не требуют определенного порядка выполнения.)

Реализации предоставляется дополнительная свобода для переупорядочивания действий, включающих предопределенные или базовые операции, за исключением присваивания. Эта свобода предоставляется даже в том случае, если при выполнении предопределенных операций может распространяться (предопределенное) исключение^ с учетом следующих правил:

а) С целью установления, одинаков ли результат выполнения некоторых действий в каноническом или альтернативном порядке, можно предположить, что ни одна из вызванных этими действиями предопределенных операций не распространяет (предопределенные) исключения, и при этом выполняются два следующих требования к реализации альтернативного порядка: во-первых, операция не должна вызываться в альтернативном порядке, если она не вызывается в каноническом порядке; во-вторых, самое внутреннее объемлющее окружение или оператор принятия для каждой операции должны быть одинаковы для канонического и альтернативного порядков с теми же самыми обработчиками исключений.

б) Связь знака операций с операндами в выражении определена синтаксисом. Однако для последовательности предопределенных операций с одним и тем же приоритетом (при отсутствии скобок, вводящих особые связи) эти связи могут быть изменены (и это допускается) при выполнении следующего требования: результат целого типа должен быть эквивалентен результату вычислений в каноническом порядке слева направо; результат вещественного типа должен принадлежать модельному интервалу результата, полученного после выполнения в каноническом порядке слева направо (см. 4.5.7). Такое переупорядочивание допустимо даже тогда, когда может быть устранено некоторое исключение или вставлено предопределенное исключение.

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

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

Примечание. Правило б) применимо к предопределенным операциям, но неприменимо к формам управления с промежуточной проверкой.

Выражение SPEED < 300-000.0 может быть заменено на TRUE, если значение 300-000.0 находится вне границ базового типа для SPEED, даже если неявное преобразование этого числового литерала может возбудить исключение NUMERIC_ERROR.

Пример:

declare
   N : INTEGER;
begin
   N := О;                 --  (1)
   for J in 1 .. 10 loop
      N := N + J**A(K); -— А и К являются глобальными переменными
   end loop;
   PUT(N);
exception
when others => PUT("Some error arose"); PUT(N);
end:

Вычисление А(К) может быть выполнено до цикла и, возможно, непосредственно перед оператором присваивания (1), даже если в нем может возбуждаться исключение. Следовательно, внутри обработчика исключения значение N будет либо неопределенным, либо результатом последнего присваивания. С другой стороны, вычисление А(К) не может быть выполнено до begin, поскольку в этом случае исключение будет обрабатываться другим обработчиком. По этой причине инициализация N в описании будет исключать возможность наличия неопределенного начального значения N в обработчике.

Ссылки: базовая операция типа 3.3.3, базовый тип 3.3, вещественный тип 3.5.6, исключение 11, исключение NUMERIC_ERROR 11.1, неопределенное значение 3.2.1, обработчик исключения 11.2, окружение 11.1, оператор принятия 9.5, ошибочная ситуация 11, присваивание 5.2, предопределенная операция 4.5, предопределенная подпрограмма 8.6, преобразование 4.6, распространение исключения 11.4, точность вещественных операций типа 4.5.7.

Пред. | Уровень выше | След.
11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ | Начало | 11.7. ПОДАВЛЕНИЕ ПРОВЕРОК


11.7. ПОДАВЛЕНИЕ ПРОВЕРОК
Пред. Глава 11. ИСКЛЮЧЕНИЯ След.

11.7. ПОДАВЛЕНИЕ ПРОВЕРОК

Присутствие прагмы SUPPRESS позволяет реализации опускать некоторые проверки во время выполнения программы. Эта прагма имеет следующий вид:

pragma SUPPRESS (идентификатор [, [ON =>] имя]);-

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

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

Если в прагму включено имя, то возможность подавления проверки в дальнейшем ограничена: прагма действует только для операций над объектом с этим именем или над всеми объектами базового типа для указанного в прагме имени типа или подтипа, для вызовов подпрограмм с этим именем, для активизации задач указанного именем задачного типа и для конкретизации указанного настраиваемого модуля.

Следующие проверки соответствуют ситуациям, в которых может быть возбуждено исключение CONSTRAINT_ERROR. В этих проверках имя (если оно указано) должно обозначать объект или тип

ACCESS_CHECK | Проверяется именуемая компонента, индексируемая компонента, отрезок или атрибут объекта, указанный ссылочным значением на неравенство значению null этого ссылочного значения.
DISCRIMINANT_CHECK | Проверяется, что дискриминант составного значения удовлетворяет ограничению дискриминанта. Также при ссылке на компоненты записи проверяется их существование для текущих значений дискриминанта.
INDEX_CHECK | Проверяется, что границы значений индексов массива равны соответствующим границам ограничения индекса. Также при ссылке на компоненту массива по каждой размерности проверяется, что данное значение индекса находится в диапазоне, определенном границами индекса массива; при ссылке на отрезок массива проверяется, что заданный дискретный диапазон совместим с диапазоном, определенным границами индексов массива.
LENGTH_CHECK | Проверяется, что каждой компоненте массива соответствует подходящая компонента при выполнении присваивания массиву, преобразовании типа и выполнении логических операций над массивами логических компонент.
RANGE_CHECK | Проверяется, что некоторое значение удовлетворяет ограничению диапазона. Также при предвыполнении указания подтипа проверяется совместимость ограничения (если оно имеется) с обозначением типа. Для агрегата проверяется принадлежность индекса или дискриминанта соответствующему подтипу. Наконец, осуществляются проверки любых ограничений, создаваемых при конкретизации настройки.

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

DIVISION_CHECK | Проверяется, что второй операнд операций /, rem и mod не равен нулю.
OVERFLOW_CHECK | Проверяется, что в результате выполнения числовой операции не возникает переполнения.

Следующие проверки соответствуют ситуациям, в которых возбуждается исключение PROGRAM - ERROR. Допустимыми именами в соответствующих прагмах являются имена задач-ных модулей, настраиваемых модулей или подпрограмм.

ELABORATION_CHECK | Когда вызывается подпрограмма, выполняется активизация задачи или предвыполняется конкретизация настройки, то проверяется, что тело соответствующего программного модуля уже предвыполнено.

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

STORAGE_ERROR | Проверяется, что выполнение генератора не потребует объема памяти, большего, чем необходимо для выбора, или что требуемый под задачу или для подпрограммы объем памяти достаточен.

Если возникает ошибочная ситуация в отсутствие проверок во время выполнения программы, то программа считается ошибочной (результаты выполнения не определяются в языке).

Примеры:

pragma SUPPRESS (RANGE_CHECK);

pragma SUPPRESS (INDEX_CHECK, ON => TABLE);

Примечание. Для некоторых реализации может оказаться невозможным или слишком дорогим подавление некоторых проверок, тогда соответствующая прагма SUPPRESS может быть проигнорирована. Следовательно, наличие такой прагмы внутри данного модуля не гарантирует, что соответствующее исключение не будет возбуждено; эти исключения также могут распространяться вызванными модулями.

;i Ссылки: агрегат 4.3, активизация 9.3, атрибут 4.1.4, вызов подпрограмм????? |4.8, дискретный диапазон 3.6, дискриминант 3.7.1, задача 9, задачный модуль 9, задачный тип 1'9.1, идентификатор 2.3, именуемый тип 3.7, индекс 3.6, индексируемая компонента 4.1.1, исключение CONSTRAINT_ERROR 11.1, исключение NUMERIC_ERROR 11.1, исключение PROGRAM_ERROR 11.1, компонента записи 3.7, компонента массива 3.6, конкретизация наст-ройки 12.3, массив 3.6, набор 3.8, настраиваемое тело 11.1, настраиваемый модуль 12, обозначение 3.8, обозначение типа 3.3.2, объект 3.2, ограничение 3.3, ограничение диапазона 3.5, ограничение дискриминанта 3.7.2, ограничение индекса 3.6.1, оператор блока 5.6, операция 3.3.3, отрезок 4.1.2, ошибочная ситуация 11, ошибочный 1.6, предвыполнение 3.1, 3.9, подпрограмма 6, подтип 3.3, прагма 2.8, программный модуль 6, простое имя 4.1, раздел описаний 3.9, размерность 3.6, распространение исключения 11.4, расширенное имя 4.1.3, совместимый 3.3.2, составной тип 3.3, спецификация пакета 7.1, ссылочное значение 3.8, ссылочный тип 3.8, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, тип 3.3, числовая операция 3.5.5, 3.5.8, 3.5.10, числовой тип 3.5.

Пред. | Уровень выше | След.
11.6. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ | Начало | Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ


Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ
Пред. След.

Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ

Содержание

12.1. ОПИСАНИЕ НАСТРОЙКИ
12.2. НАСТРАИВАЕМЫЕ ТЕЛА
12.3. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ
12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА

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

Настраиваемый модуль задается описанием настройки, которое имеет раздел формальных параметров настройки, описывающий эти параметры. Конкретный экземпляр настраиваемого модуля получается в результате конкретизации настройки путем сопоставления формальным параметрам фактических. Экземпляр настраиваемой подпрограммы — это подпрограмма. Экземпляр настраиваемого пакета — пакет.

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

Ссылки: конкретизация настройки 12.3, настраиваемый пакет 12.1, настраиваемая подпрограмма 12.1, описание 3.1, описание настройки 12.1, пакет 7, подпрограмма 6, программный модуль 6, раздел формальных параметров настройки 12.1, фактический параметр настройки 12.3, формальный параметр настройки 12.1, экземпляр 12.3.

12.1. ОПИСАНИЕ НАСТРОЙКИ

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

описание-настройки ::= спецификация-настройки;
спецификация-настройки ::=
   раздел-формальных-параметров-настройки спецификация-подпрограммы
 | раздел-формальных-параметров-настройки спецификация-пакета

раздел-формальных-параметров-настройки :: =
  generic {описание-параметра-настройки}

описание параметра-настройки ::=
  список-идентификаторов :[in [out]] обозначение-типа [:= выражение];
  | type идентификатор is определение-настраиваемого-типа;
  | описание-личного-типа
  | with спецификация-подпрограммы [is имя];
  [ with спецификация-подпрограммы [is <>];

определение*-настраиваемого-типа ::=
  (<>) | range <> | digits <> | delta <>
  | определение-индексируемого-типа
  | определение-ссылочного-типа

Для ссылки на соответствующие формальные параметры настройки используются такие термины: формальный объект настройки (или, короче, формальный объект}, формальный тип настройки (или, короче, формальный тип) и формальная подпрограмма настройки (или, короче, формальная подпрограмма}.

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

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

Предвыполнение описания настройки не имеет другого эффекта.

Примеры разделов формальных параметров:

generic   -- без параметров

generic
   SIZE : NATURAL; -— формальный объект

generic
   LENGTH : INTEGER := 200;           -— формальный объект с выражением по умолчанию
   AREA   : INTEGER := LENGTH*LENGTH; -— формальный объект с выражением по умолчанию

generic
  type ITEM is private; -- формальный тип
  type INDEX is (<>);                      -— формальный тип
  type ROW is array (INDEX range <>) of ITEM; -— формальный тип
  with function "<"(X, Y : ITEM) return BOOLEAN; -— формальная подпрограмма

Примеры описаний настройки с настраиваемыми подпрограммами:

generic
   type ELEM is private;
   procedure EXCHANGE (U, V : in out ELEM);

generic
   type ITEM is private;
   with function "*"(U, V : ITEM) return ITEM is <>;
   function SQUARING(X : ITEM) return ITEM;

Пример описания настройки с настраиваемым пакетом:

generic
   type ITEM     is private;
   type VECTOR is array (POSITIVE range <>) of ITEM;
   with function SUM(X, Y : ITEM) return ITEM;
package ON_VECTORS is
   function SUM  (А. В : VECTOR) return VECTOR;
   function SIGMA (A    : VECTOR) return ITEM;
   LENGTH_ERROR : exception;
end;

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

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

Ни формальные параметры настройки, ни их атрибуты в качестве частей статических выражений недопустимы (см. 4.9).

Ссылки: атрибут 4.1.4, выражение 4.4, зарезервированное слово 2.9, идентификатор 2.3, имя 4.1, конкретизация настройки 12.3, обозначение 6.1, обозначение типа 3.3.2, объект 3.2, ограничение 3.3, описание 3.1, определение индексируемого типа 3.6, определение личного типа 7.4, определение ссылочного типа 3,8, параметр подпрограммы 6.2, подпрограмма 6, понятие 3.1, процедура 6.1, предвыполнение не имеет другого эффекта 3.1, совмещение 6.6, 8.7, спецификация пакета 7.1, спецификация подпрограммы 6.1, список идентификаторов 3.2, статическое выражение 4.9, тип 3.3, указание подтипа 3.3.2, функция 6.5, экземпляр 12.3.

12.1.1. ФОРМАЛЬНЫЕ ОБЪЕКТЫ НАСТРОЙКИ

Первая форма описания формального параметра настройки задает формальные объекты настройки. Тип формального объекта настройки — это базовый тип обозначения типа, данного в описании формального параметра настройки. Описание формального параметра настройки с несколькими идентификаторами эквивалентно последовательности единичных описаний, как поясняется в разд. 3.2.

Формальный объект настройки имеет вид in или in out. При отсутствии в описании формального параметра настройки явного указания вида подразумевается вид in. Если описание формального параметра настройки задано выражением, то оно является выражением по умолчанию для этого формального параметра. Выражение по умолчанию допустимо только для параметров вида in (указанного либо явно, либо неявно). Тип выражения по умолчанию должен быть таким же, как и у соответствующего формального параметра настройки.

Формальный объект настройки вида in — это константа, значение которой является копией значения сопоставленного ему фактического параметра конкретизации настройки, как описано в разд. 12.3. Тип формального объекта настройки вида in не должен быть лимитируемым типом; подтип 'такого формального объекта настройки — это подтип в обозначении типа, данного в описании параметра настройки.

Формальный объект настройки вида in out — это переменная, обозначающая объект, задаваемый в конкретизации настройки фактическим параметром настройки, как описано в разд. 12.3. Ограничения, применяемые к формальному объекту настройки, те же, что и для соответствующего фактического параметра.

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

Ссылки: анонимный тип 3.3.1, базовый тип 3.3, вид 6.1, идентификатор 2.3, имя 4.1, конкретизация настройки 12.3, лимитируемый тип 7.4.4, обозначение типа 3.3.2, объект 3.3, ограничение 3.3, описание 3.1, описание константы 3.2, описание параметра настройки 12.1, описание типа 3.2, переменная 3.2.1, подтип 3.2, присваивание 5.2, простое имя 4.1, сопоставление фактического параметра настройки 12.3, фактический параметр настройки 12.3, формальный объект настройки 12.1, формальный параметр настройки 12.1.

12.1.2. ФОРМАЛЬНЫЕ ТИПЫ НАСТРОЙКИ

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

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

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

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

а) Для описания личного типа разрешены операции, определенные в разд. 7.4.2 (в частнос-|ти, для личного, но нелимитируемого типа — присваивание, равенство и неравенство).

б) Для определения индексируемого типа разрешены операции, определенные в разд. 3.6.2 (например, они включают формирование индексируемых компонент и отрезков).

в) Для определения ссылочного типа разрешены операции, определенные в разд. 3.8.2 (например, могут быть использованы генераторы).

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

г) Для дискретного типа: (о)

Разрешенные операции — общие для перечисленных и целых типов; они определены в разд. 3.5.5.

д) Для целого типа: range < >

Разрешенные операции над целыми типами определены в разд. 3.5.5.

е) Для плавающего типа: digits < >

Разрешенные операции определены в разд. 3.5.8.

ж) Для фиксированных типов; delta < >

Разрешенные операции определены в разд. 3.5.10.

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

При конкретизации настройки каждая из этих операций — соответствующая базовая операция или предопределенная операция для сопоставленного фактического типа. Для операции это правило сохраняется даже в случае переопределения ее для фактического типа или некоторого его родительского типа.

Примеры формальных типов настройки:

type ITEM is private;
type BUFFER(LENGTH : NATURAL) is limited private;
type ENUM is <>;
type INT     is range <>;
type ANGLE is delta <>;
type MASS  is digits <>;
type TABLE is array (ENUM) of ITEM;

Пример раздела формальных параметров настройки с описанием формального целого типа:

generic
   type RANK Is range <>;
   FIRST   : RANK := RANK'PIRST;
   SECOND : RANK :== FIRST + 1; — операция «+» для типа RANK

Ссылки: генератор 4.8, дискретный диапазон 3.6, дискретный тип 3.6, индексируемая компонента 4.1.1, класс типа 3.3, конкретизация 12.3, лимитируемый личный тип 7.4.4, мультипликативная операция 4.5, 4.5.5, неравенство 4.5.2, обозначение типа 3.3.2, ограничение 3.3, операция 4.5, операция типа 3.3, описание 3.1, описание настраиваемого модуля 12.1, описание параметра настройки 12.1, определение индексируемого типа 3.6, определение личного типа 7.4, определение настраиваемого типа 12.1, отрезок 4.1.2, перечислимый тип 3.5.1, плавающий тип 3.5.7, присваивание 5.2, равенство 4.5.2, раздел дискриминантов 3.7.1, раздел формальных параметров настройки 12.1, родительский тип 3.4, скалярный тип 3.5, сопоставление фактических параметров настройки 12.3.2, 12.3.3, 12.3.4, 12.3.5, стандартный пакет 8.6 С, тело настраиваемого модуля 12.2, указание подтипа 3.3.2, универсальный фиксированный тип 3.5.9, фактический тип настройки 12.3, фиксированный тип 3.5.9, формальная подпрограмма настройки 12.1.3, формальный тип настройки 12.1, целый тип 3.5.4.

12.1.3. ФОРМАЛЬНЫЕ ПОДПРОГРАММЫ НАСТРОЙКИ

Описание параметра настройки, включающее спецификацию подпрограммы, описывает формальную подпрограмму настройки.

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

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

Примеры формальных подпрограмм настройки:

with function INCREASE(X : INTEGER) return INTEGER;
with function SUM(X, Y : ITEM) return ITEM;

with function "+"(X, Y : ITEM) return ITEM is <>;
with function IMAGE(X : ENUM) return STRING is ENUM'IMAGE;

with procedure UPDATE is DEFAULT_UPDATE;

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

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

Ссылки: анонимный тип 3.2.1, базовый тип 3.3, бокс 12.1.2, зарезервированное слово 2.9, знак операции 6.1, идентификатор 2.3, конкретизация настройки 12.3, область действия 8.2, обозначение 6.1, обозначение типа 3,2.2, ограничение 3.3, описание параметров настройки 12.1, описание переименования 8.5, описание подпрограммы 6.2, подпрограмма 6, подтип 3.3.2, сопоставление фактических подпрограмм настройки 12.3.6, спецификация подпрограммы 6.1, тип 3.3, фактический параметр настройки 12.3, формальная подпрограмма настройки 12.1, формальная функция настройки 12.1.

Пред. | Уровень выше | След.
11.7. ПОДАВЛЕНИЕ ПРОВЕРОК | Начало | 12.2. НАСТРАИВАЕМЫЕ ТЕЛА


12.2. НАСТРАИВАЕМЫЕ ТЕЛА
Пред. Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ След.

12.2. НАСТРАИВАЕМЫЕ ТЕЛА

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

Для каждого описания настраиваемой подпрограммы должно быть соответствующее тело.

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

Пример настраиваемого тела процедуры:

procedure EXCHANGE(U, V : in out ELEM) is -—см. пример в 12.1
   Т : ELEM; -- формальный тип настройки
begin
   Т := U;
   U := V;
   V := Т;
end EXCHANGE;

Пример тела настраиваемой функции:

function SQUARING(X : ITEM) return ITEM is -—  см. пример в 12.1
begin
   return X*X; -— формальная операция «*»
end;

Пример тела настраиваемого пакета:

package body ON_VECTORSis -- см. пример в 12.1

   function SUM(A, В : VECTOR) return VECTOR is
      RESULT : VECTOR(A'RANGE); -— формальный тип VECTOR
      BIAS   : constant INTEGER := B'FIRST - A'FIRST;
   begin
      if A'LENGTH /= B'LENGTH then
         raise LENGTH_ERROR;
      end if;
      for N in A'RANGE loop
         RESULT(N) := SUM(A(N), B(N + BIAS));    -— формальная функция SUM
      end loop;
      return RESULT;
   end;

   function SIGMA(A : VECTOR) return ITEM is
      TOTAL : ITEM := A(A'FIRST);              -— формальный тип ITEM
   begin
      for N in A'FIRST + 1 .. A'LAST loop
         TOTAL := SUM(TOTAL, A(N));            -— формальная функция SUM
      end loop;
      return TOTAL;
   end;

end;

Ссылки: конкретизация настройки 12.3, настраиваемая подпрограмма 12.1,настраиваемое тело 12.1, настраиваемый пакет 12.1, пакет 7, подпрограмма 6, Предвыполнение 3.9, тело 3.9, тело пакета 7.1, тело подпрограммы 6.3, экземпляр 12.3.

Пред. | Уровень выше | След.
Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ | Начало | 12.3. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ


12.3. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ
Пред. Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ След.

12.3. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ

Экземпляр настраиваемого модуля описывается конкретизацией настройки.

конкретизация - настройки ::=
   package идентификатор is new имя-настраиваемого-пакета [раздел - фактических - параметров - настройки];
|  procedure идентификатор is new имя- настраиваемой -процедуры [раздел - фактических - параметров - настройки];
|  function обозначение is new имя-настраиваемой-функции [раздел - фактических - параметров - настройки];

раздел-фактических-параметров-настройки ::= (сопоставление-параметров-настройки {, сопоставление-параметров-настройки}

сопоставление-параметров-настройки ::= [формальный-параметр-настройки = >] фактический-параметр-настройки

формальный-параметр-настройки ::= простое-имя-параметра | знак-операции

фактический-параметр-настройки :: = выражение имя-переменной | имя-подпрограммы имя-входа
      | обозначение-типа

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

Каждый фактический параметр настройки должен быть сопоставлен с соответствующим формальным параметром. Выражение может быть сопоставлено с формальным объектом вида in; имя переменной может быть сопоставлено с формальным объектом вида in out; имя подпрограммы или имя входа может сопоставляться с формальной подпрограммой; обозначение типа может сопоставляться с формальным типом. Детальные правила, определяющие единственные допустимые сопоставления, даны в разд. 12.3.1 — 12.3.6.

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

а) Имя обозначает настраиваемый модуль: соответствующее вхождение обозначает экземпляр.

б) Имя обозначает формальный объект настройки вида in: соответствующее в экземпляре имя обозначает константу, значение которой — копия значения сопоставленного фактического параметра настройки.

в) Имя обозначает формальный объект настройки вида in out: соответствующее в экземпляре имя обозначает переменную, указанную сопоставленным фактическим параметром настройки.

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

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

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

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

з) Имя обозначает локальное понятие, описанное в настраиваемом модуле: соответствующее в экземпляре имя обозначает понятие, описанное соответствующим локальным описанием в экземпляре.

и) Имя обозначает глобальное понятие, описанное вне настраиваемого модуля: соответствующее в экземпляре имя обозначает это же глобальное понятие.

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

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

При предвыполнении конкретизации настройки осуществляются следующие действия. Сначала вычисляется каждое выражение, заданное в качестве явного фактического параметра настройки, и каждое выражение, входящее как составная часть в имя переменной или входа, заданное в качестве явного фактического параметра настройки; в языке не определен порядок вычисления этих выражений. Затем вычисляются выражения или имена по умолчанию для тех параметров, для которых опущены сопоставления параметров (если они есть) настройки; эти вычисления производятся в порядке следования описаний формальных параметров настройки. Наконец, предвыполняется неявно сгенерированный экземпляр. Предвыпо-лнение конкретизации настройки может также вызывать проверки некоторых ограничений, как описано ниже.

Рекурсивная конкретизация настройки недопустима в следующем смысле: если данный настраиваемый модуль включает конкретизацию другого настраиваемого модуля, то экземпляр, сгенерированный этой конкретизацией, не должен включать экземпляр первого настраиваемого модуля (независимо от того, генерируется ли этот экземпляр непосредственно или косвенно через промежуточную конкретизацию).

Примеры конкретизации настройки (см. 12.1}:

procedure SWAP is new EXCHANGE(ELEM => INTEGER);
procedure SWAP is new EXCHANGE(CHARACTER); --  совмещение идентификатора SWAP
function SQUARE is new SQUARING (INTEGER); --  по умолчанию используется «*» над INTEGER
function SQUARE is new SQUARING (ITEM => MATRIX, "*" => MATRIX_PRODUCT);
function SQUARE is new SQUARING (MATRIX, MATRIX_PRODUCT); -- что эквивалентно предыдущему
package INT_VECTORS is new ON_VECTORS(INTEGER, TABLE, "+");

Примеры использования конкретизированных модулей:

   SWAP(A, 8);
   А := SQUARE(A);
   Т : TABLE(1 .. 5) := (10, 20, 30, 40, 50);
   N : INTEGER := INT_VECTORS.SIGMA(T); --  150 (CM. 12.2)

   use INT_VECTORS;
   М : INTEGER := SIGMA(T); -— 150

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

Если две совмещенные подпрограммы описаны в спецификации настраиваемого пакета и различаются только (формальным) типом параметров и результата, то существуют'правильные конкретизации, для которых все вызовы этих подпрограмм вне экземпляра будут неоднозначными. Например:

generic
   type A is (<>);
   type В is private;

package G is
   function NEXT(X : A) return A;
   function NEXT(X : B) return B;
end;

package P is new G(A => BOOLEAN. B => BOOLEAN);  -—  все вызовы P.NEXT неоднозначны

Ссылки: вид in 12.1.1, вид in out 12.1.1, видимость 8.3, вызов подпрограммы 6.4, выражение 4.4, вычисление 4.5, глобальное описание 8.1, дискриминант 3.7.1, знак операции 6.1, идентификатор 2.3, имя 4.1, имя входа 9.5, имя подпрограммы 6.1, локальное описание 8.1, неявное описание 3.1, обозначение 6.1, обозначение типа 3.3.2, описание 3.1, описание подтипа 3.3.2, операция типа 3.3, описание формального параметра настройки 12.1, пакет 7, переменная 3.2.1, подпрограмма 6, понятие 3.1, предвыполнение 3.1, 3.9, простое имя 4.1, совмещение 6.6, 8.7, формальная подпрограмма настройки 12.1, формальный объект настройки 12.1, формальный параметр настройки 12.1, формальный тип настройки 12.1.

12.3.1. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ОБЪЕКТОВ

Формальному параметру настройки вида tn данного типа сопоставляется выражение этого же типа. Если настраиваемый модуль имеет формальный объект настройки вида in, то проверяется принадлежность значения выражения подтипу, заданному обозначением типа, как и для явного описания константы (см. 3.2.1). При отрицательном результате проверки возбуждается исключение CONSTRAINT-ERROR.

Формальному параметру настройки вида in out данного типа сопоставляется имя переменной этого же типа. Переменная не должна быть формальным параметром вида out или его подкомпонентой. Имя должно обозначать такую переменную, для которой допустимо переименование (см. 8.5).

Примечание. Тип фактического параметра настройки вида in не должен быть лимитируемым типом. Ограничения формального параметра настройки вида in out являются ограничениями соответствующего фактического параметра настройки (см. 12.2.1).

Ссылки: вид in 12.1.1, вид in out 12.1.1, вид out 6.2, возбуждение исключения 11, выражение 4.4, имя 4.1, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, лимитируемый тип 7.4.4, настраиваемый модуль 12.1, обозначение типа 3.3.2, ограничение 3.3, переменная 3.2.1, подкомпонента 3.3, сопоставление фактических параметров настройки 12.3, тип 3.3, удовлетворять 3.3, фактический параметр настройки 12.3, формальный объект настройки 12.1.1, формальный параметр 6.1, формальный параметр настройки 12.1.

12.3.2. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ЛИЧНЫХ ТИПОВ

Формальный личный тип настройки сопоставляется с типом или подтипом (фактическим подтипом), удовлетворяющим следующим условиям:

•Если формальный тип не является лимитируемым, то фактический тип не должен быть лимитируемым. (С другой стороны, если формальный тип является лимитируемым, то соответствующий фактический тип может быть лимитируемым и нелимитируемым.)

•Если формальный тип имеет раздел дискриминантов, то фактический тип должен быть типом с таким же числом дискриминантов; тип дискриминанта в данной позиции в разделе дискриминантов фактического типа должен совпадать с типом дискриминанта в той же позиции раздела дискриминантов формального типа; фактический подтип должен быть неограниченным. (С другой стороны, если формальный тип не имеет дискриминантов, для фактического типа дискриминанты допустимы.)

Ниже рассматривается вхождение имени формального типа в том месте, где оно использовано как указание неограниченного подтипа. Фактический подтип не должен быть неограниченным индексируемым типом или неограниченным типом с дискриминантами, если любое вхождение находится на месте, где для индексируемого типа или типа с дискриминантами требуется либо ограничение, либо выражения по умолчанию для дискриминантов (см. 3.6.1 и 3.7.2). Такое же требование предъявляется ко всем вхождениям имени подтипа формального типа, а также к вхождениям имени любого типа или подтипа, производного (непосредственно или косвенно) для этого формального типа.

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

Ссылки: возбуждение исключения 11, выражение по умолчанию для дискриминанта 3.7.1, дискриминант 3.7.1, имя 4.1, индексируемый тип 3.1, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, лимитируемый тип 7.4.4, личный тип 7.4, настраиваемое тело 12.2, неограниченный индексируемый тип 3.6, неограниченный подтип 3.3, обозначение подтипа 3.3.2, ограничение 3.3, подтип 3.3, предвыполнение 3.9, производный тип 3.4, раздел дискриминантов 3.7.1, сопоставление фактических параметров настройки 12.3, спецификация настройки 12.1, тип 3.3, тип с дискриминантами 3.3, фактический тип настройки 12.3, формальный тип настройки 12.1.2.

12.3.3. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ СКАЛЯРНЫХ ТИПОВ

Формальному типу настройки, определенному символами (о), сопоставляется любой дискретный подтип (т.е. любой перечислимый или целый подтип). Формальному типу настройки, определенному символами range о, сопоставляется любой целый подтип. Формальному типу настройки, определенному символами digits о, сопоставляется любой плавающий подтип. Формальному типу настройки, определенному символами delta о, сопоставляется любой фиксированный подтип. Никакие другие сопоставления для этих формальных типов настройки невозможны.

Ссылки: бокс 12.1.2, дискретный тип 3.5, определение настраиваемого типа 12.1, перечислимый тип 3.5.1, плавающий тип 3.5.7, скалярный тип 3.5, сопоставление фактических параметров настройки 12.3, фактический тип настройки 12.1.2, фиксированный тип 3.5.9, формальный тип настройки 12.1.2, целый тип 3.5.4.

12.3.4. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ИНДЕКСИРУЕМЫХ ТИПОВ

Формальному индексируемому типу сопоставляется фактический индексируемый подтип, удовлетворяющий следующим условиям:

•Формальный и фактический индексируемые типы должны иметь одинаковые размерности; формальный тип и фактический подтип должны быть либо оба ограниченными, либо оба неограниченными.

•Для каждой позиции индекса тип индекса фактического индексируемого типа должен совпадать с типом индекса формального индексируемого типа.

•Типы компонент фактического и формального индексируемых типов должны быть одинаковыми. Если тип компоненты отличен от скалярного, то подтипы компонент фактического и формального индексируемых типов должны быть либо оба ограниченными, либо оба неограниченными.

Если настраиваемый модуль имеет формальный индексируемый тип, то при предвыполнении соответствующей конкретизации проверяются совпадения ограничений (если они есть) на тип компоненты фактического индексируемого типа с ограничениями для формального индексируемого типа; для любой данной позиции индекса индексируемых подтипов или дискретных диапазонов проверяется совпадение границ. При несовпадениях возбуждается исключение CONSTRAINT-ERROR.

Пример:

--  задание настраиваемого пакета
generic
   type ITEM    is private;
   type INDEX   is (<>»;
   type VECTOR is array (INDEX range <>) of ITEM;
   type TABLE   is array (INDEX) of ITEM;

package P is
   ...
end;

—-  даны типы
type MIX     is array (COLOR range <>) of BOOLEAN;
type OPTION is array (COLOR) of BOOLEAN;

—- теперь тип MIX может быть сопоставлен типу VECTOR, a
—- OPTION — типу TABLE

package R is new P(ITEM    => BOOLEAN, INDEX => COLOR, VECTOR => MIX,      TABLE => OPTION);

—- теперь тип MIX не может быть сопоставлен типу TABLE,
—- а тип OPTION — типу VECTOR

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

Ссылки: индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINT-ERROR 11.1, компонента массива 3.6, конкретизация настройки 12.3, неограниченный индексируемый тип 3.6, ограничение 3.3, ограничение индекса 3.6.1, ограниченный индексируемый тип 3.6, оператор возбуждения исключения 11.3, определение индексируемого типа 3.6, подтип 3.3, предвыполнение 3.9, сопоставление фактических параметров настройки 12.3, формальный тип 12.1, формальный тип настройки 12.1.2.

12.3.5. ПРАВИЛО СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ССЫЛОЧНЫХ ТИПОВ

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

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

Пример:

--  формальным типам настраиваемого пакета

generic
   type NODE is private;
   type LINK is accees NODE;
package P is
   ...
end:
-- могут быnь сопоставлены фактические типы

type CAR;
type CAR_NAME is access CAR;
type CAR is record
   PRED, SUCC : CAR_NAME;
   NUMBER     : LICENSE_NUMBER;
   OWNER      : PERSON;
end record;

-- в следующей конкретизации настройки
package R is new P(NODE => CAR, LINK => CAR_NAME);

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

Ссылки: значение ссылочного типа 3.8, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, объект 3.2, ограничение 3.3, оператор возбуждения исключения 11.3, определение ссылочного типа 3.8, предвыполнение 3.9, сопоставление фактических параметров настройки 12.3, ссылочный тип 3.8, указывать 3.8, формальный тип настройки 12.1.2.

12.3.6. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ПОДПРОГРАММ

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

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

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

Пример:

--  дана спецификация настраиваемой функции
generic
   type ITEM is private;
   with function "*" (U, V : ITEM) return ITEM is <>;
function SQUARING(X : ITEM) return ITEM;

-- и функция
function MATRIX_PRODUCT(A, В : MATRIX) return MATRIX;

--  возможна следующая конкретизация
function SQUARE is new SQUARING(MATRIX, MATRIX„PRODUCT):

-- следующие конкретизации эквивалентны
function SQUARE is new SQUARING(ITEM => INTEGER, "*" => "*");

function SQUARE is new SQUARING(INTEGER, "*");

function SQUARE is new SQUARING(INTEGER);

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

Формальной подпрограмме сопоставляется атрибут типа, если этот атрибут — функция с сопоставимой спецификацией. Литерал перечисления данного'типа сопоставляется с формальной функцией без параметров и результатом данного типа.

Ссылки: атрибут 4.1.4, видимость 8.3, вход 9.5, имя 4.1, конкретизация настройки 12.3, обозначение 6.1, ограничитель бокс 12.1.2, подпрограмма 6, подтип 3.3, профиль типа параметров и результата 6.3, сопоставление фактических параметров настройки 12.3, спецификация подпрограммы 6.1, фактический тип настройки 12.3, формальная подпрограмма настройки 12.1, формальный тип настройки 12.1.2, функция 6.5.

Пред. | Уровень выше | След.
12.2. НАСТРАИВАЕМЫЕ ТЕЛА | Начало | 12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА


12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА
Пред. Глава 12. НАСТРАИВАЕМЫЕ МОДУЛИ След.

12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА

В следующем примере использован настраиваемый пакет для одной из возможных организаций стеков. Размер каждого стека и тип его элементов являются параметрами настройки.

generic
   SIZE : POSITIVE;
   type ITEM is private;
package STACK is

   procedure PUSH (E : in   ITEM);
   procedure POP (E : out ITEM);

   OVERFLOW, UNDERFLOW : exception;

end STACK;

package body STACK is

   type TABLE is array (POSITIVE range <>) of ITEM;
   SPACE : TABLE(1 .. SIZE);
   INDEX : NATURAL := 0;

   procedure PUSH(E : in ITEM) is
   begin
      if INDEX >= SIZE then
         raise OVERFLOW;
      end if;
      INDEX := INDEX + 1;
      SPACE(INDEX) := E;
   end PUSH;

procedure POP(E : out ITEM) is
   begin
      if INDEX = 0 then
         raise UNDERFLOW;
      and if;
      E := SPACE(INDEX);
      INDEX := INDEX - 1:
   end POP;

end STACK;

Экземпляры настраиваемого пакета могут быть получены так:

package STACK_INT   is new STACK(SIZE => 200, ITEM => INTEGER);

package STACK_BOOL is new STACK(100, BOOLEAN);

После этого могут быть вызваны процедуры конкретизированных пакетов:

STACK_INT.PUSH(N);

STACK_BOOL.PUSH(TRUE);

Возможна другая организация стека (тело пакета опущено):

generic
   type ITEM is private;
package ON_STACKS is
   type STACK(SIZE : POSITIVE) is limited private;
   procedure PUSH (S : in out STACK; E : in   ITEM);
   procedure POP (S : in out STACK; E : out ITEM);
   OVERFLOW, UNDERFLOW : exception;
private
   type TABLE is array (POSITIVE range <>) of ITEM;

   type STACK(SIZE : POSITIVE) is record
      SPACE : TABLE(1 .. SIZE);
      INDEX : NATURAL := 0;
   end record;
end:

При использовании такого пакета сначала должна быть осуществлена конкретизация, после чего можно описать стеки с элементами соответствующего типа:

declare
   package STACK_REAL is new ON_STACKS(REAL);
    use STACK_REAL;
   S : STACK(100);
begin
   ...
   PUSH(S, 2.54);
   ...
end;

Пред. | Уровень выше | След.
12.3. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ | Начало | Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ


Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ
Пред. След.

Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ

Содержание

13.1. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ
13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ
13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ
13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ
13.5. СПЕЦИФИКАТОРЫ АДРЕСА
13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ
13.7. СИСТЕМНЫЙ ПАКЕТ
13.8. ВСТАВКИ МАШИННЫХ КОДОВ
13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ
13.10. НЕКОНТРОЛИРУЕМОЕ ПРОГРАММИРОВАНИЕ

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

13.1. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ

Спецификаторы представления задают способ представления типов в объектной машине для более эффективного представления или для интерфейса с внеязыковой сферой (например, с периферийным оборудованием).

спецификатор-представления :: = спецификатор-представления-типа | спецификатор-адреса

спецификатор-представления-типа ::= спецификатор-длины
  | спецификатор-представления-перечисления
  | спецификатор-представления-записи

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

Спецификатор адреса применяется либо к объекту, либо к подпрограмме, пакету или за-дачному модулю, либо к входу. Для любого из этих понятий допустимо не более одного спецификатора адреса.

Спецификатор представления и описание понятия, к которому применяется спецификатор, должны оба находиться непосредственно в одном и том же разделе описаний, спецификации пакета или спецификации задачи; описание должно помещаться до спецификатора. В отсутствие спецификатора представления для данного описания реализация определяет представление по умолчанию. Место нахождения такого подразумеваемого определения представления по умолчанию — не позже конца непосредственно объемлющего раздела описаний, спецификаций пакета или задачи. Для описания из раздела описаний место нахождения подразумеваемого определения по умолчанию — до любого вложенного тела.

В случае типа некоторые вхождения его имени неявно предполагают, что представление типа уже должно быть определено. Следовательно, такие вхождения требуют определения по умолчанию любого способа представления, еще не определенного предшествующим спецификатором представления типа. Аналогичные вхождения имени подтипа этого типа или имени любого типа или подтипа с подкомпонентами данного типа также требуют определения по умолчанию. Требуемое вхождение — это любое вхождение, отличное от вхождения в описание типа или подтипа, спецификацию подпрограммы, описание входа, описание субконстанты, прагму или спецификатор представления для самого типа. В любом случае вхождение в выражение является всегда требуемым.

Спецификатор представления для данного понятия не должен помещаться после вхождения имени понятия, если вхождение требует определения представления этого понятия по умолчанию.

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

Результат предвыполнения спецификатора аспектов представления — определение соответствующих представления.

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

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

pragma PACK (простое имя- типа);

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

Прагма PACK — единственная определенная в языке прагма, связанная с представлением. Реализация может вводить дополнительные прагмы; они должны быть перечислены в приложении F. (В отличие от спецификаторов представления прагма, которая не принята в реализации, игнорируется.)

Примечание. Для формального типа настройки недопустим спецификатор представления.

Ссылки: атрибут представления 13,7.2, 13.7.3, вход 9.5, выражение 4.4, выражение по умолчанию 3.2.1, должно 1.6, допустим 1.6, задачный модуль 9, имя 4.1, компонента 3.3, наследуемая подпрограмма 3.4, находится непосредственно в 8.1, неправильная 1.6, объект 3.2, описание 3.1, описание подтипа 3.3.2, описание субконстанты 7.4, описание типа 3.3.1, пакет 7, подкомпонента 3.3, подпрограмма 6, подтип 3.3, понятие 3.1, прагма 2.8, производный тип 3.4, раздел описаний 3.9, родительский тип 3.4, спецификатор адреса 13.5, спецификатор длины 13.2, спецификация задачи 9.1, спецификация пакета 7.1, спецификатор представления записи 13.4, спецификатор представления перечисления 13.3, тело 3.9, тип 3.3, формальный тип настройки 12.1.2.

Пред. | Уровень выше | След.
12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА | Начало | 13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ


13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ

Спецификатор длины задает объем памяти:

спецификатор длины ::= for атрибут use простое-выражение;

Выражение должно быть некоторого числового типа; оно вычисляется, при пред выполнении спецификатора длины (кроме случая, когда оно является статическим). Префикс атрибута должен обозначать либо тип, либо первый именованный подтип. Далее этот префикс обозначается буквой Т. В спецификаторе длины в качестве обозначений атрибутов допустимы только SIZE, STORAGE_SIZE и SMALL. Результат применения спецификатора длины зависит от обозначения атрибута.

а) Спецификация размера: Т'SIZE

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

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

б) Спецификация размера набора: T'STORAGE_SIZE

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

в) Спецификация объема памяти для активизации задачи: T'STORAGE_SIZE

Префикс Т должен обозначать задачный тип. Выражение должно быть некоторого целого типа (но не обязательно статическим); его значение определяет число квантов памяти, выделяемых для активизации (но не для кода) задачи данного типа.

г) Спецификация наименьшего для фиксированных типов: Т'SMALL

Префикс Т должен обозначать первый именованный подтип фиксированного типа. Выражение должно быть статическим некоторого вещественного типа; его значение должно быть не больше, чем дельта этого первого поименованного подтипа. Результат применения спецификатора длины — использование этого наименьшего значения для представления значений фиксированного базового типа. (Спецификатор длины, таким образом, также влияет на выделенный для объектов этого типа объем памяти.)

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

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

Размещенные объекты набора не обязаны занимать одинаковые размеры памяти, если указанный тип — это неограниченный индексируемый тип или неограниченный тип с дискриминантами. Заметим также, что сам генератор может требовать некоторый объем памяти для размещения внутренних таблиц и связей. Следовательно, спецификатор длины для набора ссылочного типа не всегда позволяет точно управлять максимальным числом генерируемых объектов.

Примеры:

-- предполагаемые описания:

type MEDIUM is range 0 .. 65000;
type SHORT  is delta  0.01 range -100.0 .. 100.0;
type DEGREE is delta  0.1   range -360.0 .. 360.0;

BYTE : constant := 8;
PAGE : constant := 2000;

-- спецификаторы длины:

for COLOR'SIZE   use UBYTE; -— см. 3.5.1
for MEDIUM'SIZE  use 2*BYTE;
for SHORT'SIZE   use 15;

for CAR_NAME'STORAGE_SIZE use -- примерно 2000 машин
   2000*((CAR'SIZE/SYSTEM.STORAGE_UNIT) +1);

for KEYBOARD_DRIVER_STORAGE_SIZE use 1*PAGE;

for DEGREE'SMALL use 360.0/2**(SYSTEM.STORAGE_UNIT - 1);

Примечание к примерам. В спецификаторе длины для SHORT минимально необходимы пятнадцать разрядов, так как определение типа требует SHORT'SMALL = 2.0**(-7) и SHORT'MANTISSA = 14. Спецификатор длины для DEGREE вводит модельные числа, которые занимают в точности весь диапазон типа.

Ссылки: активизация задачи 9.3, атрибут 4.1.4, вещественный тип 3.5.5, выражение 4.4, вычисление 4.5, генератор 4.8, дельта фиксированного типа 3.5.9, должен 1.6, допустим 1.6, задача 9, задачный тип 9.1, именуемый тип 3.7, индексируемый тип 3.6, квант памяти 13.7, подкомпонента 3.3, набор 3.8, наименьшее фиксированного типа 3.5.10, неограниченный индексируемый тип 3.6, объект 3.2, ограничение 3.3, пакет SYSTEM 13.7, первый именованный подтип 13.1, подтип индекса 3.6, понятие 3.1, предвыполнение 3.9, производный тип 3.4, составной тип 3.3, спецификация задачи 9.1, ссылочный тип 3.8, статический подтип 4.9, статическое выражение 4.9, статическое ограничение 4.9, тип 3.3, указывать 3.8, фиксированный тип 3.5.9, целый тип 3.5.4, числовой тип 3.5.

Пред. | Уровень выше | След.
Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ | Начало | 13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ


13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ

Спецификатор представления перечисления задает внутренние коды для литералов перечислимого типа, указанного в спецификаторе.

спецификатор-представления-перечисления ::=
   for простое-имя-типа use агрегат;

Используемый в спецификаторе агрегат записывается как одномерный агрегат, в кото ром подтип индекса — перечислимый тип, а тип компоненты — универсальный-целый тип.

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

Пример:

type MIX_CODE is (ADD, SUB, MUL, LDA, STA, STZ);
for MIX_CODE use
   (ADD => 1, SUB => 2, MUL => 3, LDA => 8, STA => 24, STZ => 33);

Примечание. Атрибуты SUCC, PRED и PCS определены даже для перечислимых типов с разрывным представлением; их определение соответствует (логическому) описанию типа, и на них не влияет спецификатор представления перечисления. В примере из-за того, что значения даны с пропуском, эти функции реализуются менее эффективно, чем это могло быть в отсутствие спецификатора представления. Это же справедливо и при использовании таких типов для индексации.

Ссылки: агрегат 4.3, агрегат массива 4.3.2, атрибут перечислимого типа 3.5.5, выбор 3.7.3, индекс 3.6, индексируемый тип 3.6, компонента 3.3, литерал 4.2, литерал перечисления 3.5.1, описание типа 3.3.1, отношение упорядоченности для перечислимого типа 3.5.1, перечислимый тип 3.5.1, подтип индекса 3.6, простое имя 4.1, спецификатор представления 13.1, статическое выражение 4.9, тип 3.3, универсальный-целый тип 3.5.4, функция 6.5.

Пред. | Уровень выше | След.
13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ | Начало | 13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ


13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ

Спецификатор представления записи задает представление записи в памяти, т.е. порядок, позицию и размер компонент записи (включая дискриминанты, если они есть).

спецификатор-представления-записи ::=
   for простое-имя-типа use
      record [спецификатор-выравнивания]
         (спецификатор - компоненты)
      end record;

спецификатор-выравнивания ::=
   at mod статическое-простое-выражение;

спецификатор-компоненты ::=
   имя-компоненты at статическое-простое-выражение range статический-диапазон;

Простое выражение, заданное в спецификаторе выравнивания после зарезервированных слов at mod или в спецификаторе компоненты после зарезервированного слова at, должно быть статическим некоторого целого типа. Если в спецификаторе компоненты границы диапазона спецификатора компоненты определяются простыми выражениями, то каждая граница должна быть определена как статическое выражение любого целого типа; не обязательно, чтобы обе границы были одного и того же целого типа.

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

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

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

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

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

Пример:

WORD : constant := 4; -- квант памяти — это байт; в слове 4 байт
type STATE       is (A, M, W, Р);
type MODE        is (FIX, DEC, EXP, SIGNIF);

type BYTE_MASK  is array (0 .. 7) of BOOLEAN;
type STATE_MASK is array (STATE) of BOOLEAN;
type MODE_MASK  is array (MODE) of BOOLEAN;

type PROGRAM_STATUS_WORD is
   record
      SYSTEM_MASK      : BYTE_MASK;
      PROTECTION_KEY   : INTEGER range 0 .. 3;
      MACHINE_STATE    : STATE_MASK;
      INTERRUPT_CAUSE  : INTERRUPTION_.CODE;
      ILC              : INTEGER range 0 .. 3;
      CC               : INTEGER range 0 .. 3;
      PROGRAM_MASK     : MODE_MASK;
      INST_ADDRESS     : ADDRESS;
   end record;

for PROGRAM_STATUS_WORD use
   record at mod 8;
      SYSTEM_MASK     at 0*WORD range 0  .. 7;
      PROTECTION_KEY  at 0*WORD range 10 .. 11;    -- биты 8, 9 не использует
      MACHINE_STATE   at 0*WORD range 12 .. 15;
      INTERRUPT-CAUSE at 0+WORD range 16 .. 31;
      ILC             at 1*WORD range 0  .. 1;     -- второе слово
      СС              at 1*WORD range 2  .. 3;
      PROGRAM_MASK    at 1*WORD range 4  .. 7;
      INST_ADDRESS    at 1*WORD range 8  .. 31;
   end record;

for PROGRAM_STATUS_WORD'SIZE use 8*SYSTEM.STORAGE_UNIT:

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

Ссылки: атрибут 4.1.4, вариант 3.7.3, диапазон 3.5, дискриминант 3.7.1, должен 1.6, допустим 1.6, именованное число 3.2, именуемый тип 3.7, квант памяти 13.7, компонента записи 3.7, константа 3.2.1, ограничение 3.3, пакет SYSTEM 13.7, подкомпонента 3.3, простое выражение 4.4, простое имя 4.1, статическое выражение 4.9, статическое ограничение 4.9, целый тип 3.5.4.

Пред. | Уровень выше | След.
13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ | Начало | 13.5. СПЕЦИФИКАТОРЫ АДРЕСА


13.5. СПЕЦИФИКАТОРЫ АДРЕСА
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.5. СПЕЦИФИКАТОРЫ АДРЕСА

Спецификатор адреса задает адрес в памяти для понятия.

спецификатор - адреса :: =
   for простое-имя use at простое-выражение;

Выражение после зарезервированного слова at должно быть типа ADDRESS, определенного в пакете SYSTEM (см. 13.7). Этот пакет должен быть именован в спецификаторе совместности компилируемого модуля, в котором помещается спецификатор адреса. Условия, определяющие интерпретацию значения типа ADDRESS как адреса, уровня прерывания или чего-либо другого, зависят от реализации. Ниже перечислены допустимые толкования простого имени и смысл соответствующего адреса:

а) имя объекта: требуемый адрес — адрес объекта (переменной или константы);

б) имя подпрограммы, пакета или задачного модуля: требуемый адрес — адрес машинного кода, связанного с телом программного модуля;

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

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

Пример:

for CONTROL use at 16#0020#; -— предполагается, что SYSTEM.ADDRESS
                             -- это некоторый целый тип

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

Ссылки: библиотечный модуль 10,1, вход 9.5, выражение 4.4, задачный модуль 9, задачный объект 9.2, зарезервированное слово 2.9, имя 4.1, компилируемый модуль 10.1, константа 3.2.1, объект 3.2, ошибочна 1.6, пакет 7, пакет SYSTEM 13.7, переменная 3.2.1, подпрограмма 6, понятие 3.1, прагма 2.8, предопределенный тип ADDRESS 13.7, применим 10.1.1, программный модуль 6, простое выражение 4.4, простое имя 4.1, спецификатор совместности 10.1.1, тело задачи 9.1, тело подпрограммы 6.3, тип 3.3.

13.5.1. ПРЕРЫВАНИЯ

Спецификатор адреса для входа сопоставляет вход с некоторым устройством, которое может вызвать прерывание; такой вход в этом разделе называется входом по прерыванию. Если прерывание сопровождается управляющей информацией, то она передается соответствующему входу по прерыванию как один или несколько параметров входа вида in; допустимы параметры только такого вида.

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

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

Пример:

task INTERRUPT_HANDLER is
   entry DONE;
   for DONE use at 16#40#; -- предполагается, что SYSTEM. ADDRESS
                           -— это некоторый целый тип
end INTERRUPT_HANDLER;

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

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

Одним из возможных результатов указания спецификатора адреса для входа по прерыванию является спецификация (непосредственно или косвенно) приоритета прерывания. Допустимы прямые вызовы входов по прерыванию.

Ссылки: альтернатива завершения 9.7.1, альтернатива отбора 9.7.1, альтернатива принятия 9.7.1, вид 6.1, временной вызов входа 9.7.3, вход 9.5, выход входа 9.5, допустим 1.6, задача 9, оператор отбора 9.7, оператор принятия 9.5, пакет SYSTEM 13.7, параметр подпрограммы 6.2, предопределенный тип ADDRESS 12.7, приоритет задачи 9.8, условный вызов входа 9.7.2.

Пред. | Уровень выше | След.
13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ | Начало | 13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ


13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ

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

Пример:

PACKED_DESCRIPTOR and DESCRIPTOR --  это два различных
-— типа с одинаковыми характеристиками, но различным представлением

type DESCRIPTOR is record
   -- компоненты DESCRIPTOR
end record;

type PACKED_DESCRIPTOR is new DESCRIPTOR;

for PACKED_DESCRIPTOR use
   record
      -— спецификаторы компонент для всех или некоторых компонент
end record;

Изменение представления может быть теперь достигнуто присваиванием с явным преобразованием типа:

D : DESCRIPTOR;
Р : PACKED_DESCRIPTOR;

Р := PACKED_DESCRIPTOR(D); —- упаковка D
D := DESCRIPTOR(P);        -— распаковка Р

Пред. | Уровень выше | След.
13.5. СПЕЦИФИКАТОРЫ АДРЕСА | Начало | 13.7. СИСТЕМНЫЙ ПАКЕТ


13.7. СИСТЕМНЫЙ ПАКЕТ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.7. СИСТЕМНЫЙ ПАКЕТ

Для каждой реализации имеется предопределенный библиотечный пакет SYSTEM, который включает определения некоторых характеристик, зависящих от конфигурации. Спецификация пакета зависит от реализации и должна быть приведена в приложении F. Видимый раздел этого пакета должен содержать по крайней мере следующие описания:

package SYSTEM is
   type ADDRESS is определен-реализацией;
   type NAME is определенный-реализацией-перечислимого-типа;
   SYSTEM-NAME  : constant NAME := определен - реализацией;
   STORAGE-UNIT : constant      := определен-реализацией;
   MEMORY-SIZE  : constant      := определен-реализацией;
   -- зависящие от системы именованные числа:
   MIN-INT      : constant      := определен-реализацией;
   МАХ-INT      : constant      := определен-реализацией;
   MAX-DIGITS   : constant      := определен-реализацией;
   MAX-MANTISSA : constant      := определен-реализацией;
   FINE-DELTA   : constant      := определен-реализацией;
   TICK         : constant      := определен-реализацией;
   -- другие зависящие от системы описания:
   subtype PRIORITY is INTEGER range определен-реализацией;
end SYSTEM;

Тип ADDRESS — это тип адресов, задаваемых спецификаторами адреса; к этому же типу принадлежат значения, вырабатываемые атрибутом ADDRESS. Значения перечислимого типа NAME — это имена альтернативных машинных конфигураций, обрабатываемых реализацией;

одно из них — константа SYSTEM-NAME. Именованное число STORAGE-UNIT равно числу разрядов в кванте памяти, а именованное число MEMORY-SIZE — числу квантов памяти, доступных в конфигурации; эти именованные числа имеют универсальный-целый тип.

Альтернативная форма пакета SYSTEM с другими значениями SYSTEM-NAME, STORAGE-UNIT и MEMORY-SIZE может быть получена использованием соответствующих прагм. Эти прагмы допустимы только в начале компиляции до первого компилируемого модуля (если он есть) компиляции.

pragma SYSTEM-NAME (литерал-перечисления);

В результате выполнения этой прагмы заданный идентификатором литерал перечисления будет использован для определения константы SYSTEM-NAME. Эта прагма допустима, только если этот идентификатор соответствует одному из литералов типа NAME.

pragma STORAGE-UNIT (числовой-литерал);

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

pragma MEMORY-SIZE (числовой-литерал);

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

Компиляция любой из этих прагм вызовет неявную перекомпиляцию пакета SYSTEM. Следовательно, любой компилируемый модуль, в спецификаторе контекста которого упоминается пакет SYSTEM, становится устаревшим. Реализация может ввести дополнительные ограничения на использование этих прагм. Например, реализация может допустить их только в начале первой компиляции, когда создается новая программная библиотека.

Примечание. Согласно правилам видимости, описание из пакета SYSTEM видимо в компилируемом модуле только в том случае, если этот пакет упомянут в спецификаторе совместности, примененном (непосредственно или косвенно) к данному компилируемому модулю.

Ссылки: атрибут 4.1.4, библиотечный модуль 10.1, видимость 8.3, видимый раздел 7.2, должен 1.6, идентификатор 2.3, именованное число 3.2, компилируемый модуль 10.1, литерал перечисления 3.5.1, описание 3.1, описание числа 3.2.2, пакет 7, перечислимый тип 3.5.1, прагма 2.8, применим 10.1.1, программная библиотека 10.1, спецификатор адреса 13.5, спецификатор совместности 10.1.1, спецификация пакета 7.1, тип 3.3, числовой литерал 2.4.

13.7.1. ЗАВИСЯЩИЕ ОТ СИСТЕМЫ ИМЕНОВАННЫЕ ЧИСЛА

Перечисленные ниже именованные числа описаны в пакете SYSTEM. Числа FINE-DELTA и TICK принадлежат универсальному-вещественному типу, остальные — универсальному-целому типу.

MIN-INT | Наименьшее (наибольшее по модулю отрицательное) значение из всех определенных целых типов.
МАХ-I NT | Наибольшее (положительное) значение из всех предопределенных целых типов.
MAX-DIGITS | Наибольшее допустимое значение числа значащих десятичных цифр в ограничении для плавающего типа.
MAX-MANTISSA | Наибольшее возможное число двоичных цифр в мантиссе модельных чисел фиксированного подтипа.
FINE-DELTA | Наименьшая дельта, допустимая в ограничении для фиксированного типа, которое имеет ограничение диапазона -1.0..1.0.
TICK | Базовый период времени, выраженный в секундах.

Ссылки: дельта из ограничения фиксированного типа 3.5.9, допустим 1.6, именованное число 3.2, модельное число 3.5.6, ограничение диапазона 3.5, ограничение для плавающего типа 3.5.7, ограничение для фиксированного типа 3.5.9, пакет 7, пакет SYSTEM 13.7, тип 3.3, универсальный-вещественный тип 3.5.6, универсальный-целый тип 3.5.4, целый тип 3.5.4.

13.7.2. АТРИБУТЫ ПРЕДСТАВЛЕНИЯ

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

Для любого объекта, программного модуля, метки или входа X:

X'ADDRESS | Вырабатывает адрес первого кванта памяти, отведенной под X. Для подпрограммы, пакета, задачного модуля или метки это значение ссылается на машинный код, связанный с соответствующим телом или оператором. Для входа, для которого задан спецификатор адреса, это значение ссылается на соответствующее аппаратное прерывание. Значение этого атрибута принадлежит типу ADDRESS, определенному в пакете SYSTEM.

Для любого типа или подтипа Х или для любого объекта X:

X'SIZE | Примененный к объекту вырабатывает число битов, отводимых в памяти для размещения объекта. Примененный к типу или подтипу вырабатывает минимальное число битов, необходимое реализации для размещения любого возможного объекта этого типа или подтипа. Значение этого атрибута имеет тип универсальный-целый.

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

Для любого компонента С записи R:

R.C'POSITION | Вырабатывает величину смещения первого кванта памяти, занятого полем С, относительно первого кванта памяти, занятого записью R. Величина смещения измеряется числом квантов. Значение этого атрибута принадлежит универсальному-целому типу.
R.C'FIRST_BIT | Вырабатывает величину смещения первого бита, занятого полем С, относительно первого кванта памяти. Величина смещения измеряется числом битов. Значение этого атрибута имеет универсальный-целый тип.
R.C'LAST_BIT | Вырабатывает величину смещения последнего бита, занятого полем С, относительно первого кванта памяти, занятого С. Величина смещения измеряется числом битов. Значение этого атрибута имеет универсальный-целый тип.

Для любого ссылочного типа или подтипа Т:

Т'STORAGE_SIZE | Вырабатывает общее число квантов памяти, выделенных для набора, связанного с базовым типом Т. Значение атрибута имеет универсальный-целый тип.

Для любого задачного типа или объекта задачного типа Т:

Т'STORAGE_SIZE | Вырабатывает число квантов памяти, выделенных для каждой активизации задачи типа Т или активизации объекта Т задачного типа. Значение этого атрибута имеет универсальный-целый тип.

Примечание. Для объекта Х задачного типа атрибут X'SIZE вырабатывает число разрядов, используемых для размещения объекта X; атрибут X'STORAGE_SIZE вырабатывает число квантов памяти, выделенных для активизации задачи, указанной X. Для формального параметра Х в случае передачи параметра копированием Х'ADDRESS вырабатывает адрес локальной копии; в случае передачи параметра ссылкой Х'ADDRESS вырабатывает адрес фактического параметра.

Ссылки: активизация 9.3, атрибут 4.1.4, базовый тип 3.3, вход 9.5, задача 9, задачный модуль 9, задачный объект 9.2, задачный тип 9.2, квант памяти 13.7, компонента 3.3, метка 5.1, набор 3.8, объект 3.2, объект именуемого типа 3.7, оператор 5, пакет 7, передача параметров 6.2, подпрограмма 6, подтип 3.3, предопределенный пакет SYSTEM 13.7, предопределенный тип ADDRESS 13.7, программный модуль 6, спецификатор адреса 13.5, ссылочный подтип 3.8, ссылочный тип 3.8, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3, тип 3.3, универсальный-целый тип 3.5.4, фактический параметр 6.2, формальный параметр 6.1, 6.2.

13.7.3. АТРИБУТЫ ПРЕДСТАВЛЕНИЯ ВЕЩЕСТВЕННЫХ ТИПОВ

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

Атрибуты, применимые к плавающим и фиксированным типам:

T'MACHINE_ROUNDS | Вырабатывает значение TRUE, если каждая предопределенная арифметическая операция над значениями базового типа Т либо возвращает точный результат, либо осуществляет округление. В противном случае вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN.
T'MACHINE_OVERFLOWS | Вырабатывает значение TRUE, если каждая предопределенная операция над значениями базового типа Т либо возвращает точный результат, либо возбуждает исключение NUMERIC_ERROR при перевыполнении (см. 4.5.7); в противном случае вырабатывает значение FALSE. Значение этого атрибута имеет предопределенный тип BOOLEAN.

Следующие атрибуты дают характеристики машинного представления значений плавающего типа в терминах канонической формы, определенной в разд. 3.5.7:

T'MACHINE_RADIX | Вырабатывает значение основания системы счисления, используемого в машинном представлении базового типа Т. Значение этого атрибута имеет универсальный-целый тип.
T'MACHINE_MANTISSA | Вырабатывает число цифр в мантиссе машинного представления базового типа Т. (Цифра — это расширенная цифра из диапазона 0 .. Т'MACHINE_RADIX - 1.) Значение этого атрибута имеет универсальный-целый тип.
T'MACHINE_EMAX | Вырабатывает наибольшее значение порядка в машинном представлении базового типа Т. Значение этого атрибута имеет универсальный-целый тип.
T'MACHINE_EMIN | Вырабатывает наименьшее (наибольшее по модулю отрицательное) значение порядка в машинном представлении базового типа Т. Значение этого атрибута имеет универсальный-целый тип.

Примечание. В большинстве машин наибольшее представимое в машине число типа Т равно

F'MACHINE_RADIX..(F'MACHINE_EMIN - 1)

а наименьшее положительное представимое число в машине равно

F'MACHINE_RADIX ** (F'MACHINE_EMIN - 1)

Ссылки: арифметическая операция 4.5, атрибут 4.1.4, базовый тип 3.3, вещественный тип 3.5.6, исключение NUMERIC_ERROR 11.1, логическое значение TRUE 3.5.3, логическое значение FALSE 3.5.3, модельное число 3.5.6, основание системы счисления 3.5.7, плавающий тип 3.5.7, подтип 3.3, предопределенный логический тип 3.5.3, предопределенная операция 3.3.3, тип 3.3, универсальный-целый тип 3.5.4, фиксированный тип 3.5.9, числовой тип 3.5.

Пред. | Уровень выше | След.
13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ | Начало | 13.8. ВСТАВКИ МАШИННЫХ КОДОВ


13.8. ВСТАВКИ МАШИННЫХ КОДОВ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.8. ВСТАВКИ МАШИННЫХ КОДОВ

Машинные коды могут быть включены в программу с помощью вызова процедуры, последовательность операторов которой состоит из операторов кода.

оператор-кода ::= обозначение-типа'агрегат-записи;

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

Каждая машинная команда записывается как агрегат именуемого типа, агрегат определяет эту команду. Базовый тип обозначения типа в операторе кода должен быть описан в предопределенном пакете MACHINE_CODE; этот пакет должен быть упомянут в спецификаторе контекста, помещаемом для компилируемого модуля, в который входит оператор кода. Реализация не обязана обеспечивать такой пакет.

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

Реализация может определить машинно-зависимые прагмы, специфицирующие соглашения об использовании регистров и вызовов. Такие прагмы должны быть описаны в приложении F.

Пример:

М : MASK;
procedure SET_MASK; pragma INLINE(SET_MASK);

procedure SET_MASK is
   use MACHINE_CODE;
begin
   SI_FORMAT'(CODE => SSM, В => M'BASE_REG, D => M'DISP);
   --  M'BASE_REG and M'DISP —это заданные реализацией предопределенные атрибуты
end;

Ссылки: агрегат именуемого типа 4.3.1, библиотечный модуль 10.1, допустим 1.6, именуемый тип 3.7, комментарий 2.7, компилируемый модуль 10.1, обработчик исключения 11.2, оператор 5, пакет 7, помеченный оператор 5.1, последовательность операторов 5.1, прагма 2.8, прагма INLINE 6.3.2, применим 10.1.1, процедура 6.6.1, спецификатор использования 8.4, спецификатор совместности 10.1.1, статическое выражение 4.9, тело процедуры 6.3, элемент описания 3.9.

Пред. | Уровень выше | След.
13.7. СИСТЕМНЫЙ ПАКЕТ | Начало | 13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ


13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ

Из программы, написанной на языке Ада, может быть вызвана подпрограмма, написанная на другом языке; все связи с этими подпрограммами обеспечиваются через параметры и результаты функций. Для каждой такой подпрограммы должна быть задана следующая прагма:

pragma INTERFACE (имя -языка, имя- подпрограммы};

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

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

Пример:

package FORT_LIB is
   function SORT (X : FLOAT) return FLOAT;
   function EXP (X : FLOAT) return FLOAT;
private
   pragma INTERFACE(FORTRAN, SORT);
   pragma INTERFACE(FORTRAN, EXP);
end FORT_LIB;

Примечание. Соглашения, использованные в других языковых процессорах, которые вызывают Ада-программы, не являются частью определения языка Ада. Эти соглашения должны быть определены в описании других языковых процессоров.

Прагма INTERFACE не определена для настраиваемых подпрограмм. Ссылки: библиотечный модуль 10.1, вызов подпрограммы 6.4, должен 1.6, допустимый 1.6, имя 4.1, компилируемый модуль 10.1, описание 3.1, описание подпрограммы 6.1, параметр подпрограммы 6.2, подпрограмма 6, прагма 2.8, раздел описаний 3.9, результат функции 6.5, след тела 10.2, совмещенная подпрограмма 6.6, спецификация пакета 7.1, тело подпрограммы 6.3, элемент описания 3.9.

Пред. | Уровень выше | След.
13.8. ВСТАВКИ МАШИННЫХ КОДОВ | Начало | 13.10. НЕКОНТРОЛИРУЕМОЕ ПРОГРАММИРОВАНИЕ


13.10. НЕКОНТРОЛИРУЕМОЕ ПРОГРАММИРОВАНИЕ
Пред. Глава 13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ След.

13.10. НЕКОНТРОЛИРУЕМОЕ ПРОГРАММИРОВАНИЕ

Для неконтролируемого освобождения памяти и неконтролируемого преобразования типов используются предопределенные настраиваемые библиотечные подпрограммы: UNCHECKED_DEALLOCATION и UNCHECKED_CONVERSION.

generic
   type OBJECT is limited private;
   type NAME   is access OBJECT;
procedure UNCHECKED_DEALLOCATION(X : in out NAME):

generic
   type SOURCE is limited private;
   type TARGET is limited private;
function UNCHECKED_CONVERSION(S : SOURCE) return TARGET;

13.10.1. НЕКОНТРОЛИРУЕМОЕ ОСВОБОЖДЕНИЕ ПАМЯТИ

В результате вызова процедуры, полученной конкретизацией настраиваемой процедуры UNCHECKED_DEALLOCATION, производится неконтролируемое освобождение памяти, занимаемой объектом, указанным значением ссылочного типа. Например:

procedure FREE is new UNCHECKED_DEALLOCATION(имя_типa_oбъeкra, имя_ссылочного_гипа);

Такая процедура FREE дает следующий результат:

а) после выполнения FREE(X) значением Х является null;

б) если Х уже равно null, то FREE(X) не имеет другого результата; -

в) если Х не равно null, то FREE(X) обозначает, что указанный значением Х объект не требуется, и поэтому занимаемая им память может использоваться для других целей.

Если Х и Y указывают на один и тот же объект, то после вызова FREE(X) доступ к этому объекту (или попытка доступа к нему) через Y ошибочен; язык не определяет, что происходит в результате такого доступа.

Примечание. Согласно правилам видимости, настраиваемая процедура UNCHECKED_DEALLOCATION невидима в компилируемом модуле, если только ее имя не указано в спецификаторе совместности этого компилируемого модуля.

Если Х указывает на объект задачного типа, то вызов FREE(X) никак не влияет на задачу, указанную значением этого объекта. Это же относится и к любой подкомпоненте задачного типа объекта X.

Ссылки: библиотечный модуль 10.1, видимость 8.3, вызов процедуры 6.4, задача 9, задач-ный объект 9.2, значение ссылочного типа null 3.3, компилируемый модуль 10.1, конкретизация настройки 12.3, настраиваемый модуль 12, настраиваемая процедура 12.1, объект 3.2, ошибочно 1.6, подкомпонента 3.3, применим 10.1.1, процедура 6, спецификатор совместности 10.1.1, ссылочный тип 3.8, указывать 3.8, 9.1.

13.10.2. НЕКОНТРОЛИРУЕМОЕ ПРЕОБРАЗОВАНИЕ ТИПА

Неконтролируемое преобразование типа можно осуществить вызовом функции, полученной конкретизацией настраиваемой функции UNCHECKED_CONVERSION.

Неконтролируемое преобразование типа состоит в возврате значения параметра в качестве значения целевого типа, т.е. поразрядное изображение, определяющее исходное значение, возвращается неизменным, как поразрядное изображение значения целевого типа. Реализация может наложить ограничения на неконтролирумое преобразование типа, например ограничения, зависящие от предполагаемых размеров объектов исходного и целевого типов. Такие ограничения должны быть отражены в приложении F.

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

Примечание. Согласно правилам видимости, настраиваемая функция UNCHECKED_CONVERSION невидима в компилируемом модуле, если она не упомянута в спецификаторе совместности этого компилируемого модуля.

Ссылки: компилируемый модуль 10.1, конкретизация 12.3, настраиваемая функция 12.1, ошибочный 1.6, параметр подпрограммы 6.2, применим 10.1.1, спецификатор совместности 10.1.1, тип 3.3.

Пред. | Уровень выше | След.
13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ | Начало | Глава 14. ВВОД-ВЫВОД


Глава 14. ВВОД-ВЫВОД
Пред. След.

Глава 14. ВВОД-ВЫВОД

Содержание

14.1. ВНЕШНИЕ ФАЙЛЫ И ФАЙЛОВЫЕ ОБЪЕКТЫ
14.2. ФАЙЛЫ ПОСЛЕДОВАТЕЛЬНОГО И ПРЯМОГО ДОСТУПА
14.3. ВВОД-ВЫВОД ТЕКСТОВ
14.4. ИСКЛЮЧЕНИЯ ПРИ ВВОДЕ-ВЫВОДЕ
14.5. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА
14.6. ВВОД-ВЫВОД НИЗКОГО УРОВНЯ
14.7. ПРИМЕР ВВОДА-ВЫВОДА

Ввод-вывод в языке обеспечивается предопределенными пакетами. Настраиваемые пакеты SEQUENTIAL_IO и DIRECT_IO определяют операции ввода-вывода, которые применимы для файлов с элементами данного типа. В пакете TEXT_IO даны дополнительные операции ввода-вывода текстов. В пакете IO_EXCEPTIONS определены исключения, необходимые при работе трех указанных пакетов. Наконец, пакет LOW_LEVEL_IO позволяет осуществлять непосредственное управление периферийными устройствами.

Ссылки: пакет DIRECT_IO 14.2, 14.2.4, пакет IO_EXCEPTIONS 14.5, пакет LOW_LEVEL_IO 14.6, пакет SEQUENTIAL_IO 14.2, 14.2.2, пакет TEXT_IO 14.3.

14.1. ВНЕШНИЕ ФАЙЛЫ И ФАЙЛОВЫЕ ОБЪЕКТЫ

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

Операции ввода и вывода выражены операциями над объектами некоторого файлового типа, а не непосредственно в терминах внешних файлов. Далее в этой главе термин файл будет всегда использоваться для ссылки на объект файлового типа; в остальных случаях будет использоваться термин внешний файл. Значения, передаваемые данному файлу, должны быть все одного и того же типа.

Ввод и вывод для последовательных файлов из элементов некоторого типа определены настраиваемым пакетом SEQUENTIAL_IO. Общая структура этого пакета дана ниже.

with IO_EXCEPTIONS;
generic
   type ELEMENT_TYPE is private;
package SEQUENTIAL_IO is
   type FILE_TYPE is limited private;

   type FILE_MODE is (IN_FILE, OUT_FILE);
   ...
   procedure OPEN (FILE : in out FILE_TYPE; ...);
   ...
   procedure READ  (FILE : in FILE_TYPE; ITEM : out ELEMENT_TYPE);
   procedure WRITE (FILE : in FILE_TYPE; ITEM : in ELEMENT_TYPE);
   ...
end SEQUENTIAL_IO;

Для определения последовательного ввода-вывода элементов данного типа должна быть описана конкретизация этого настраиваемого модуля с фактическим параметром данного типа. Конкретизация настройки содержит описание файлового типа (названного FILE_TYPE) для файлов таких элементов, а также операции над этими файлами — например, процедуры OPEN, READ и WRITE.

Ввод-вывод для файлов прямого доступа определен аналогичным способом в настраиваемом пакете DIRECT_IO. Ввод-вывод в текстовой форме определен в (ненастраиваемом) пакете TEXT_IO.

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

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

Открытый файл имеет текущий вид, который является значением одного из перечисленных типов: ,,

type FILE_MODE is (IN_FILE, INOUT_FILE, OUT_FILE);         -— ДЛЯ DIRECT_IO
type FILE_MODE is (IN_FILE, OUT.FILE);  -— ДЛЯ SEQUENTIAL_IO И TEXT_IO

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

Некоторые из операций управления файлами являются общими для всех трех пакетов ввода-вывода. Эти операции над последовательными файлами и файлами прямого доступа описаны в разд. 14.2.1. Дополнительные особенности ввода-вывода текстов описаны в разд. 14.3.1.

В пакете IO_EXCEPTIONS определены все исключения, которые могут быть возбуждены при вызове подпрограммы ввода-вывода; ситуации их возбуждения описаны либо при описании подпрограмм ввода и вывода (и в разд. 14.4), либо в приложении F для ошибочных ситуаций, зависящих от реализации.

Примечание. Каждая конкретизация настраиваемых пакетов SEQUENTIAL_IO и DIRECT_IO задает разные типы FILE_TYPE; уникальным является тип FILE_TYPE в пакете TEXT_IO.

Устройство с двусторонней связью часто может быть промоделировано двумя файлами с последовательным доступом, связанными с этим устройством; один — вида IN_FILE, а другой — вида OUT_FILE. Реализация может ограничить число файлов, которые могут быть связаны с данным внешним файлом. В этом случае результат такого разделения внешнего файла несколькими объектами файлового типа зависит от реализации.

Ссылки: вид файла 14.2.3, индекс 14.2, исключение 11, конкретизация настройки 12.3, открытый файл 14.1, пакет DIRECT_IO 14.1, 14.2, пакет EXCEPTIONS 14.5, пакет SEQUENTIAL_IO 14.2, 14.2.2, пакет TEXT_IO 14.3, перечислимый тип 3.5.1, последовательный ввод-вывод 14.2.2, последовательный доступ 14.2, процедура CREATE 14.2.1, процедура DELETE 14.2.1, процедура OPEN 14.2.1, процедура READ 14.2.4, процедура WRITE 14.2.4, процедура для файлов прямого доступа 14.2, прямой доступ 14.2, строка 3.6.3, текущий индекс 14.2, текущий размер 14, файл ' последовательного доступа 14.2.

Пред. | Уровень выше | След.
13.10. НЕКОНТРОЛИРУЕМОЕ ПРОГРАММИРОВАНИЕ | Начало | 14.2. ФАЙЛЫ ПОСЛЕДОВАТЕЛЬНОГО И ПРЯМОГО ДОСТУПА


14.2. ФАЙЛЫ ПОСЛЕДОВАТЕЛЬНОГО И ПРЯМОГО ДОСТУПА
Пред. Глава 14. ВВОД-ВЫВОД След.

14.2. ФАЙЛЫ ПОСЛЕДОВАТЕЛЬНОГО И ПРЯМОГО ДОСТУПА

Для внешних файлов определены два сорта доступа: последовательный доступ и прямой доступ. В настраиваемых пакетах SEQUENTIAL_IO и DIRECT_IO описаны соответствующие файловые типы и связанные с ними операции. Объект файлового типа, используемый для последовательного доступа, называется последовательным файлом, а используемый для прямого доступа — прямым файлом.

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

При прямом доступе файл рассматривается как набор элементов, занимающих последовательные позиции в линейном порядке; значение может быть передано в элемент файла (или из него), находящийся в любой выбранной позиции. Позиция элемента задается его индексом, который является положительным числом определяемого реализацией целого типа COUNT. Индекс первого элемента в файле (если он есть) равен единице; индекс последнего элемента (если он есть) называется текущим размером; текущий размер файла, не содержащего ни одного элемента, равен нулю. Текущий размер — это характеристика внешнего файла.

Открытый прямой файл имеет текущий индекс, который будет использован следующей операцией для чтения или записи. По открытии прямого файла значение текущего индекса устанавливается равным единице. Текущий индекс прямого файла — это характеристика не внешнего файла, а связанного с ним объекта файлового типа.

Для прямых файлов допустимы все три вида файла. Для последовательных файлов допустимы только виды IN_FILE и OUT_FILE.

Ссылки: вид файла 14.1, тип 14.3, файл вида IN_FILE 14.1, файл вида OUT_FILE 14.1.

14.2.1. УПРАВЛЕНИЕ ФАЙЛАМИ

В этом разделе описаны процедуры и функции, предназначенные для управления внешними файлами; их описания повторены в каждом из трех пакетов последовательного, прямого и текстового ввода-вывода. Процедуры CREATE, OPEN и RESET при вводе-выводе текстов имеют дополнительные эффекты, описанные в разд. 14,3.1.

procedure OPEN( FILE : in out FILE_TYPE;
                MODE : in FILE_MODE;
                NAME : in STRING;
                FORM : in STRING := "");

Устанавливает новый внешний файл с данным именем и формой и связывает его с данным файлом (FILE). После этого данный файл открывается. Текущий вид файла устанавливается в заданный вид доступа (MODE). По умолчанию для последовательного и текстового ввода-вывода устанавливается вид OUT_FILE, а для прямого ввода-вывода — INOUT_FILE. Для прямого доступа размер созданного файла зависит от реализации. Пустая строка под именем (NAME) задает внешний файл, который не доступен после окончания главной программы (временный файл). Пустая строка для формы (FORM) задает параметры по умолчанию, определяемые реализацией для внешнего файла.

Если данный файл уже открыт, то возбуждается исключение STATUS_ERROR. Если указанная в качестве параметра NAME строка не допускает идентификацию внешнего файла, то возбуждается исключение NAME_ERROR. Если для заданного вида файла окружение не может обеспечить создание внешнего файла с заданными именем и формой, то возбуждается исключение USE_ERROR (в отсутствие возбуждения исключения NAME_ERROR).

procedure CREATE(FILE : in out FILE_TYPE;
                 MODE in FILE_MODE :=вид по умолчанию;
                 NAME in STRING := "";
                 FORM in STRING := "");

Связывает данный файл с существующим внешним файлом, имеющим данные имя и форму, а текущий вид данного файла устанавливается параметром MODE. Данный файл открывается.

Если данный файл уже открыт, то возбуждается исключение STATUS_ERROR. Если строка, заданная параметром NAME, не допускает идентификацию внешнего файла, то возбуждается исключение NAME_ERROR; в частности, это исключение возбуждается, если внешнего файла с указанным именем не существует. Если для заданного вида файла окружение не может обеспечить открытие внешнего файла с данными именем и формой, то возбуждается исключение USE_ERROR (в отсутствие возбуждения исключения NAME_ERROR).

procedure CLOSE(FILE : in out FILE_TYPE);

Уничтожает связь между данным файлом и соответствующим ему внешним файлом. Данный файл закрывается.

Если данный файл не открыт, то возбуждается исключение STATUS_ERROR.

procedure DELETE(FILE : in out FILE_TYPE);

Уничтожает внешний файл, связанный с данным файлом. Данный файл закрывается, внешний файл прекращает существование.

Если данный файл не открыт, то возбуждается исключение STATUS_ERROR. Если уничтожение внешнего файла не может быть обеспечено окружением, то возбуждается исключение USE_ERROR (все такие случаи должны быть описаны в приложении F).

procedure RESET(FILE : in out FILE_TYPE; MODE : in FILE_MODE);
procedure RESET(FILE : in out FILE_TYPE);

Устанавливает данный файл в состояние, позволяющее возобновить чтение или запись значений его элементов с начала файла; в частности, для прямого доступа это означает, что текущий индекс становится равным единице. Если задан параметр MODE, то в соответствии с ним устанавливается текущий вид данного файла.

Если файл не открыт, то возбуждается исключение STATUS_ERROR. Если для внешнего файла окружение не может осуществить возврат к началу файла или установку данного вида, то возбуждается исключение USE_ERROR.

function MODE(FILE : in FILE_TYPE) return FILE_MODE;

Возвращает текущий вид данного файла.

Если файл не открыт, то возбуждается исключение STATUS_ERROR.

function NAME(FILE : in FILE_TYPE) return STRING;

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

Если данный файл не открыт, то возбуждается исключение STATUS_ERROR.

function FORM(FILE : in FILE_TYPE) return STRING;

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

Если данный файл не открыт, то возбуждается исключение STATUS_ERROR.

function IS_OPEN(FILE : in FILE_TYPE) return BOOLEAN;

Если файл открыт (т.е. связан с внешним файлом), то возвращает значение TRUE, в противном случае — FALSE.

Ссыпки: вид 14.1, внешний файл 14.1, закрытый файл 14.1, исключение NAME_ERROR 14.4, исключение STATUS_ERROR 14.4, исключение USE_ERROR 14.4, OUT_FILE 14.1, открытый файл 14.1, поименованная строка 14.1, прямой доступ 14.2, текущий вид 14.1, текущий размер 14.1, тип FILE_MODE 14.1, тип FILE_TYPE 14.1, файл 14.1, файл вида INOUT_FILE 14.2.4, форма файла 14.1.

14.2.2. ПОСЛЕДОВАТЕЛЬНЫЙ ВВОД-ВЫВОДА

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

procedure READ(FILE : in FlLE_TYPE; ITEM : out ELEMENT_TYPE);

Оперирует над файлом вида IN_FILE. Читает элемент данного файла и возвращает значение этого элемента через параметр ITEM.

Если вид файла не IN_FILE, то возбуждает исключение MODE_ERROR. Если из файла нельзя больше читать ни одного элемента, то возбуждает исключение END_ERROR. Если прочитанный элемент не может быть интерпретирован как значение типа ELEMENT_TYPE, то возбуждается исключение DATA_ERROR; однако для реализации допустимо опускать такую проверку в случае, если она слишком сложна.

procedure WRITE_FILE : in FILE_TYPE; ITEM : in ELEMENT_TYPE);

Оперирует над файлом вида OUT_FILE. Записывает в данный файл значение параметра ITEM.

Если вид файла не OUT_FILE, то возбуждается исключение MODE_ERROR. Если внешний файл уже заполнен до конца, то возбуждается исключение USE_ERROR.

function END_OF_FILE(FILE : in FILE_TYPE) return BOOLEAN;

Оперирует над файлом вида IN_FILE. Если из файла больше нельзя читать ни одного элемента, то возвращает значение TRUE, в противном случае — FALSE.

Если вид файла не IN_FILE, то возбуждается исключение MODE_ERROR. Ссылки: вид IN_FILE 14.1, вид OUT_FILE 14.1, вид файла 14.1, внешний файл 14.1, исключение DATA_ERROR 14.4, исключение END_ERROR 14.4, исключение MODE_ERROR 14.1, ис-. ключение STATUS_ERROR 14.4, исключение USE_ERROR 14.4, тип ELEMENT_TYPE 14.1, фай/i ; 14.1, файловый тип 14.1, элемент 14.1.

14.2.3. СПЕЦИФИКАЦИЯ ПАКЕТА ПОСЛЕДОВАТЕЛЬНОГО ВВОДА-ВЫВОДА

with IO_EXCEPTIONS;
generic
   type ELEMENT_TYPE is private;
package SEQUENTIAL_IO is

   type FILE_TYPE is limited private;

   type FILE_MODE is (IN_FILE, OUT_FILE);

   -- управление файлами

   procedure CREATE(FILE : in out FILE_TYPE;
                    MODE : in FILE_MODE := OUT_FILE;
                    NAME : in STRING := "";
                    FORM : in STRING := "");

   procedure OPEN  (FILE : in out FILE_TYPE;
                    MODE : in FILE_MODE;
                    NAME : in STRING;
                    FORM : in STRING := "");

   procedure CLOSE (FILE : in out FILE_TYPE);
   procedure DELETE(FILE : in out FILE_TYPE);
   procedure RESET (FILE : in out FILE_TYPE; MODE : in FILE_MODE);
   procedure RESET (FILE : in out FILE_TYPE);

   function MODE   (FILE : in FILE_TYPE) return FILE_MODE;
   function NAME   (FILE : in FILE_TYPE) return STRING;
   function FORM   (FILE : in FILE_TYPE) return STRING;

   function IS_OPEN(FILE : in FILE_TYPE) return BOOLEAN;

   -- операции ввода и вывода

   procedure READ  (FILE : in FILE_TYPE; ITEM : out ELEMENT_TYPE);
   procedure WRITE (FILE : in FILE_TYPE; ITEM : in ELEMENT_TYPE);

   function END_OF_FILE(FILE : in FILE_TYPE) return BOOLEAN;

   -- исключения

   STATUS_ERROR : exception renames IO_EXCEPTIONS.STATUS_ERROR;
   MODE_ERROR   : exception renames IO_EXCEPTIONS.MODE_ERROR;
   NAME_ERROR   : exception renames IO_EXCEPTIONS.NAME_ERROR;
   USE_ERROR    : exception renames IO_EXCEPTIONS.USE_ERROR;
   DEVICE_ERROR : exception renames IO_EXCEPTIONS.DEVICE_ERROR;
   END_ERROR    : exception renames IO_EXCEPTIONS.END_ERROR;
   DATA_ERROR   : exception renames IO_EXCEPTIONS.DATA_ERROR;

private
   -- зависит от реализации
end SEQUENTIAL_IO;

Ссылки: вид IN_FILE 14.1, вид OUT_FILE 14.1, исключение DATA_ERROR 14.4, исключение DEVICE_ERROR 14.4, исключение END_ERROR 14.4, исключение MODE_ERROR 14.4, исключение NAME_ERROR 14.4, исключение STATUS_ERROR 14.4, исключение USE_ERROR 14.4, пакет исключений Ю-EXCEPTIONS 14.4, пакет SEQUENTIAL_IO 14.2, 14.2.2, процедура CLOSE 14.2.1, процедура CREATE 14.2.1, процедура DELETE 14.2.1, процедура OPEN 14.2.1, процедура READ 14.2.2, процедура RESET 14.2.1, процедура WRITE 14.2.2, тип FILE_MODE 14.1, тип FILE_TYPE 14.1, функция END-OF_FILE 14.2.2, функция FORM 14.2.1, функция IS-OPEN 14.2.1, функция MODE 14.2.1, функция NAME 14.2.1.

14.2.4. ПРЯМОЙ ВВОД-ВЫВОД

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

procedure READ(FILE : in FILE_TYPE; ITEM    out ELEMENT_TYPE;
                                    FROM : in POSITIVE_COUNT);

procedure READ(FILE : in FILE_TYPE; ITEM    out ELEMENT_TYPE);

Оперируют над файлами вида IN_FILE или INOUT_FILE. Первая из операций предварительно устанавливает текущий индекс данного файла равным значению параметра FROM. Затем (для обеих подпрограмм) через параметр ITEM возвращает значение элемента файла, позиция которого задана текущим индексом файла; наконец, увеличивает текущий индекс на единицу.

Если вид данного файла — OUT_FILE, то возбуждается исключение MODE_ERROR. Если используемое при чтении значение индекса оказалось больше размера внешнего файла, то возбуждается исключение END_ERROR. Если прочитанный элемент нельзя интерпретировать как значение типа ELEMENT_TYPE, то возбуждается исключение DATA_ERROR; однако для реализации допустимо опускать такую проверку в случае, если она слишком сложна.

procedure WRITE(FILE : in FILE_TYPE; ITEM : in ELEMENT_TYPE;
                                     TO   : in POSITIVE_COUNT);
procedure WRITE(FILE : in FILE_TYPE; ITEM : in ELEMENT_TYPE);

Оперируют над файлами вида INOUT_FILE или OUT_FILE. Первая из операций предварительно устанавливает индекс данного файла равным значению параметра ТО. Затем (для обеих подпрограмм) элементу данного файла, позиция которого указана текущим индексом, присваивается значение параметра ITEM; наконец, увеличивается текущий индекс на единицу.

Если вид данного файла — IN_FILE, то возбуждается исключение MODE_ERROR. Если внешний файл заполнен до конца, то возбуждается исключение USE_ERROR.

procedure SET_INDEX( FILE : in FILE_TYPE; TO : in POSITIVE_COUNT);

Оперирует над файлом любого вида. Устанавливает текущий индекс данного файла равным значению параметра ТО (которое может превышать текущий размер файла).

function INDEX(FILE : in FILE_TYPE) return POSITIVE_COUNT;

Оперирует над файлом любого вида. Возвращает текущий индекс данного файла.

function SIZE(FILE : in FILE_TYPE) return COUNT;

Оперирует над файлом любого вида. Возвращает текущий размер внешнего файла, связанного с данным файлом.

function END_OF_FILE(FILE : in FILE_TYPE) return BOOLEAN;

Оперирует над файлом вида IN_FILE или INOUT_FILE. Если значение текущего индекса больше размера внешнего файла, то возвращает значение TRUE, в противном случае — FALSE. Если вид данного файла — OUT_FILE, то возбуждается исключение MODE_ERROR. Ссылки: вид IN_FILE 14.1, вид INOUT_FILE 14.1, вид файла 14.1, внешний файл 14.1, индекс 14.2, исключение DATA_ERROR 14.4, исключение END_ERROR 14.4, исключение MODE_ERROR 14.4, исключение STATUS_ERROR 14.4, исключение USE_ERROR 14.4, открытый файл 14.1, текущий индекс 14.2, текущий размер 14.2, тип ELEMENT_TYPE 14.1, тип COUNT 14.2, тип POSITIVE_COUNT 14.3, тип FILE_TYPE 14.1, файл 14.1, элемент 14.1.

14.2.5. СПЕЦИФИКАЦИЯ ПАКЕТА ПРЯМОГО ВВОДА-ВЫВОДА

with IO_EXCEPTIONS;
generic
   type ELEMENT_TYPE is private;
package DIRECT_IO is

   type FILE_TYPE is limited private;

   type    FILE_MODE is (IN_FILE, INOUT_FILE, OUT_FILE);
   type    COUNT     is range 0 .. implementation defined;
   subtype POSITIVE_COUNT is COUNT range 1 .. COUNT'LAST;

   -- управление файлами

   procedure CREATE(FILE : in out FILE_TYPE;
                    MODE : in FILE_MODE := INOUT_FILE;
                    NAME : in STRING := "";
                    FORM : in STRING := "");

   procedure OPEN  (FILE : in out FILE_TYPE;
                    MODE : in FILE_MODE;
                    NAME : in STRING;
                    FORM : in STRING := "");

   procedure CLOSE (FILE : in out FILE_TYPE);
   procedure DELETE(FILE : in out FILE_TYPE);
   procedure RESET (FILE : in out FILE_TYPE; MODE : in FILE_MODE);
   procedure RESET (FILE : in out FILE_TYPE);

   function MODE   (FILE : in FILE_TYPE) return FILE_MODE;
   function NAME   (FILE : in FILE_TYPE) return STRING;
   function FORM   (FILE : in FILE_TYPE) return STRING;

   function IS_OPEN(FILE : in FILE_TYPE) return BOOLEAN;

   -- операции ввода и вывода

   procedure READ (FILE : in FILE_TYPE; ITEM : out ELEMENT_TYPE; FROM :
    POSITIVE_COUNT);
   procedure READ (FILE : in FILE_TYPE; ITEM : out ELEMENT_TYPE);

   procedure WRITE(FILE : in FILE_TYPE; ITEM : in  ELEMENT_TYPE; TO :
    POSITIVE_COUNT);
   procedure WRITE(FILE : in FILE_TYPE; ITEM : in ELEMENT_TYPE);

   procedure SET_INDEX(FILE : in FILE_TYPE; TO : in POSITIVE_COUNT);

   function INDEX(FILE : in FILE_TYPE) return POSITIVE_COUNT;
   function SIZE (FILE : in FILE_TYPE) return COUNT;

   function END_OF_FILE(FILE : in FILE_TYPE) return BOOLEAN;

   -- исключения

   STATUS_ERROR : exception renames IO_EXCEPTIONS.STATUS_ERROR;
   MODE_ERROR   : exception renames IO_EXCEPTIONS.MODE_ERROR;
   NAME_ERROR   : exception renames IO_EXCEPTIONS.NAME_ERROR;
   USE_ERROR    : exception renames IO_EXCEPTIONS.USE_ERROR;
   DEVICE_ERROR : exception renames IO_EXCEPTIONS.DEVICE_ERROR;
   END_ERROR    : exception renames IO_EXCEPTIONS.END_ERROR;
   DATA_ERROR   : exception renames IO_EXCEPTIONS.DATA_ERROR;

private
   -- зависит от реализации
end DIRECT_IO;

Ссылки: вид OUT_FILE 14.2.1, вид IN_FILE 14.2.4, вид по умолчанию 14.2.5, исключение DATA_ERROR 14.4, исключение DEVICE_ERROR 14.4, исключение END_ERROR 14.4, исключение MODE_ERROR 14.4, исключение NAME_ERROR 14.4, исключение STATUS_ERROR 14.4, исключение USE_ERROR 14.4, пакет Ю-EXCEPTION 14.4, процедура CLOSE 14.2.1, процедура CREATE 14.2.1, процедура DELETE 14.2.1, процедура OPEN 14.2.1, процедура SET-INDEX 14.2.4, процедура READ 14.2.4, процедура WRITE 14.2.4, 14.2.1, тип ELEMENT_TYPE 14.2.4, тип COUNT

14.2. тип FILE_MODE 14.2.5, тип FILE_TYPE 14.2.4, файл ввода-вывода 14.2.4, 14.2.1, функция END-OF_FILE 14.2.4, функция FROM 14.2.1, функция INDEX 14.2.4, функция IS-OPEN 14.2.1, функция MODE 14.2.1, функция NAME 14.2.1, функция SIZE 14.2.4.

Пред. | Уровень выше | След.
Глава 14. ВВОД-ВЫВОД | Начало | 14.3. ВВОД-ВЫВОД ТЕКСТОВ


14.3. ВВОД-ВЫВОД ТЕКСТОВ
Пред. Глава 14. ВВОД-ВЫВОД След.

14.3. ВВОД-ВЫВОД ТЕКСТОВ

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

Возможности управления файлами, описанные в разд. 14.2.1 и 14.2.2, применимы и для текстового ввода-вывода. Однако вместо процедур READ и WRITE используются процедуры GET и PUT, которые осуществляют ввод и вывод значений соответствующих типов для текстовых файлов. Эти значения передаются процедурами PUT и возвращаются процедурами GET через параметр ITEM. Существует несколько совмещенных процедур с такими именами, но с

различными типами параметра ITEM. Процедуры GET анализируют вводимые последовательности символов как лексемы (см. гл. 2) и возвращают соответствующие значения; процедуры PUT выводят данные значения в виде соответствующих лексем. Процедуры GET и PUT могут также вводить и выводить отдельные символы, рассматриваемые не как лексемы, а как значения символьного типа.

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

Для всех процедур GET и PUT, оперирующих над текстовыми файлами, а также для многих других подпрограмм существуют формы как с параметром файлового типа, так и без него. Каждая процедура GET оперирует над файлом ввода; каждая процедура PUT — над файлом вывода. Если файл не задан, то работа производится над файлом ввода по умолчанию или над файлом вывода по умолчанию.

В начале выполнения программы файлами ввода и вывода по умолчанию являются так называемые стандартный файл ввода и стандартный файл вывода. Эти файлы всегда открыты и имеют текущие виды IN_FILE и OUT_FILE соответственно, они связаны с двумя определяемыми реализацией внешними файлами. Существуют процедуры для замены текущего файла ввода по умолчанию и текущего файла вывода по умолчанию.

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

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

Символы строчки пронумерованы начиная с единицы; номер символа называется номером столбца. Для признака конца строчки также определен номер столбца; его значение на единицу больше числа символов в строчке. Строчки страницы и страницы файла пронумерованы аналогично. Текущий номер столбца — это номер следующего (передаваемого) символа или признака конца строчки. Текущий номер строчки — это номер текущей строчки в текущей странице. Текущий номер страницы — это номер текущей страницы в файле. Все эти номера являются значениями подтипа POSITIVE_COUNT типа COUNT (нулевое значение типа COUNT по соглашению используется для специальных целей).

type COUNT is range 0.. определяется-реализацией;
subtype POSITIVE_COUNT is COUNT range 1 .. COUNT'LAST;

Для файла вывода могут быть заданы максимальная длина строчки и максимальная длина страницы. Если они заданы, а значение не помещается на текущей строчке, то автоматически до вывода значения будет начата новая строчка; если далее эта новая строчка не может быть размещена на текущей странице, то автоматически до вывода будет начата новая страница. Имеются функции для определения максимальной длины строчки и максимальной длины страницы. После открытия файла вида OUT_FILE оба этих значения равны нулю; это значит, что длина страницы и длина строчки считаются неограниченными. (Следовательно, весь файл вывода состоит из одной строчки, если только не используются подпрограммы явного управления структурой строчек и страниц файла.) Для этих целей служит константа UNBOUNDED.

Ссылки: вид OUT_FILE 14.1, вид IN_FILE 14.1, внешний файл 14.1, последовательный доступ 14.1, процедура GET 14.3.5, процедура PUT 14.3.5, стандартный файл ввода 14.3.2, стандартный файл вывода 14.3.2, текущий файл по умолчанию 14.3.2, тип COUNT 14.3.10, файл 14.1, читать 14.2.2.

14.3.1. УПРАВЛЕНИЕ ФАЙЛАМИ

Для текстовых файлов допустимы только виды IN_FILE и OUT_FILE. К ним также применимы приведенные в разд. 14.2.1 подпрограммы управления внешними файлами и приведенная в разд. 14.2.2 функция END-OF_FILE для последовательного ввода-вывода. Имеется также вариант функции END-OF_FILE, который выдает результат для текущего файла ввода по умолчанию. Указанные процедуры для текстовых файлов характеризуются следующим:

•Процедуры CREATE и OPEN: после открытия файла вида OUT_FILE длина страницы и длина строчки не ограничены (имеют по соглашению значение 0). После открытия файла вида IN_FILE или OUT_FILE текущие номера столбца, строчки и страницы устанавливаются равными единице.

•Процедура CLOSE: если файл имеет текущий вид OUT_FILE, а текущая страница еще не завершена, то результат эквивалентен вызову подпрограммы NEW-PAGE; затем выводится признак конца файла.

•Процедура RESET: если файл имеет текущий вид OUT_FILE, а текущая страница еще не завершена, то результат эквивалентен вызову подпрограммы NEW-PAGE; затем выводится признак конца файла. Если новый вид файла — OUT_FILE, то длина строчки и длина страницы становятся неограниченными. Для всех видов файла текущие номера столбца, строчки и страницы устанавливаются равными единице.

При попытке изменить вид текущего файла ввода по умолчанию или текущего файла вывода по умолчанию процедура RESET возбуждает исключение MODE_ERROR.

Ссылки: вид файла 14.1, вид IN_FILE 14.1, вид OUT_FILE 14.1, внешний файл 14.1, длина страницы 14.3, длина строчки 14.3, исключение MODE_ERROR 14.4, признак конца файла 14.3, процедура CREATE 14.2.1, процедура OPEN 14.2.1, процедура RESET 14.2.1, текущий номер столбца 14.3, текущий номер страницы 14.3, текущий номер строчки 14.3, текущий файл ввода по умолчанию 14.3, файл 14.1, функция END-OF_FILE 14.2.4, 14.3.

14.3.2. ФАЙЛЫ ВВОДА И ВЫВОДА ПО УМОЛЧАНИЮ

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

procedure SET_INPUT(FILE : in FILE.TYPE);

Оперирует над файлом вида IN_FILE. Устанавливает текущим файлом ввода по умолчанию файл, заданный параметром FILE.

Если данный файл не открыт, то возбуждается исключение STATUS_ERROR. Если вид данного файла отличен от IN_FILE, то возбуждается исключение MODE_ERROR.

procedure SET_OUTPUT(FILE : in FILE_TYPE);

Оперирует над файлом вида OUT_FILE. Устанавливает текущим файлом вывода по умолчанию файл, заданный параметром FILE.

Если данный файл не открыт, то возбуждается исключение STATUS_ERROR. Если вид данного файла отличен от OUT_FILE, то возбуждается исключение MODE_ERROR.

function STANDARD_INPUT return FILE_TYPE;

Возвращает стандартный файл ввода (см. 14.3).

function STANDARD_OUTPUT return FILE_7YPE;

Возвращает стандартный файл вывода (см. 14.3).

function CURRENT_INPUT return FILE_TYPE;

Возвращает текущий файл ввода по умолчанию.

function CURRENT_OUTPUT return FILE_TYPE;

Возвращает текущий файл вывода по умолчанию.

Примечание. Стандартные файлы ввода и вывода не могут быть открыты, закрыты, переустановлены и уничтожены, потому что в соответствующих процедурах параметр FILE имеет вид In out.

Ссылки: исключение MODE_ERROR 14.4, исключение STATUS_ERROR 14.4, процедура GET 14.3.5, процедура PUT 14.3.5, текущий файл по умолчанию 14.3, тип FILE_TYPE 14.1, файл по умолчанию 14.3.

14.3.3. СПЕЦИФИКАЦИИ ДЛИН СТРОЧЕК И СТРАНИЦ

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

Во всех случаях, если заданный файл не открыт, то возбуждается исключение STATUS_ERROR; если вид этого файла отличен от OUT_FILE, то возбуждается исключение MODE_ERROR.

procedure SET_LINE_LENGTH(FILE : in FILE_TYPE; TO : in COUNT);
procedure SET_LINE_LENGTH(TO   : in COUNT);

Устанавливает максимальную длину строчки заданного файла вывода равной числу символов, задаваемому значением параметра ТО. Нулевое значение параметра ТО задает неограниченную длину строчки.

Если заданное значение длины строчки не подходит для связанного с ней внешнего файла, то возбуждается исключение USE_ERROR.

procedure SET_PAGE_LENGTH <FILE : in FILE.7YPE; TO : in COUNT);
procedure SET_PAGE_LENGTH (TO : in COUNT);

Устанавливает максимальную длину страницы заданного файла вывода равной числу строчек, задаваемому значением параметра ТО. Нулевое значение параметра ТО задает неограниченную длину страницы.

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

function LINE_LENGTH(FILE : in FILE_TYPE) return COUNT;
function LINE_LENGTH return COUNT;

Возвращает максимальную длину строчки, установленную для заданного файла вывода, или нуль, если длина строчки не ограничена.

function PAGE_LENGTH(FILE : in FILE_JYPE) return COUNT;
function PAGE_LENGTH return COUNT;

Возвращает максимальную длину страницы, установленную для данного файла, или нуль, если длина страницы не ограничена.

Ссылки: вид OUT_FILE 14.4.1, внешний файл 14.1, длина страницы 14.3, длина строчки 14.3, исключение MODE_ERROR 14.4, исключение STATUS_ERROR 14.4, исключение USE_ERROR 14.4, максимальная длина страницы 14.3, максимальная длина строчки 14.3, неограниченная длина страницы 14.3, открытый файл 14.1, признак конца строчки 14.3, страница 14.3, строчка 14.3, текущий файл вывода по умолчанию 14.3, тип COUNT 14.3, тип FILE_TYPE 14.1, файл 14.1.

14.3.4. ОПЕРАЦИИ НАД СТОЛБЦАМИ, СТРОЧКАМИ И СТРАНИЦАМИ

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

procedure SKIP_LINE(FILE     : in FILE_TYPE; SPACING : in POSITIVE_COUNT := 1);
procedure SKIP_LINE(SPACING : in POSITIVE_COUNT := 1);

Оперирует над файлом вида OUT_FILE.

Если SPACING равно единице, то выводит признак конца строчки, а текущий номер столбца устанавливается равным единице. Затем увеличивает текущий номер строчки на единицу, кроме случая, когда текущий номер строчки уже был равен или превышал максимальную длину страницы; в этом случае сначала выводит признак конца страницы, затем увеличивает текущий номер страницы на единицу, а текущий номер строчки устанавливает равным единице.

Если SPACING больше единицы, то указанные действия повторяются SPACING раз.

Если вид файла не OUT_FILE, то возбуждается исключение MODE_ERROR.

procedure NEW_LINE(FILE : in FILE_TYPE; SPACING : in POSITIVE_COUNT := 1);
procedure NEW_LINE(SPACING : in POSITIVE_COUNT := 1);

Оперирует над файлом вида IN_FILE.

Если SPACING равен единице, то считывает из файла и пропускает (игнорирует) все символы до признака конца строчки, а текущий номер столбца устанавливает равным единице. Если непосредственно за признаком конца строчки не следует признак конца страницы, то увеличивает текущий номер строчки на единицу. В противном случае, когда за признаком конца строчки непосредственно следует признак конца страницы, пропускает признак конца страницы, увеличивает текущий номер страницы на единицу, а текущий номер строчки устанавливает равным единице.

Если SPACING больше единицы, указанные действия повторяются SPACING раз.

Если вид файла не IN_FILE, то возбуждается исключение MODE_ERROR. При попытке прочитать признак конца файла возбуждается исключение END_ERROR.

function END_OF_LINE(FILE : in FILE_TYPE) return BOOLEAN;
function END_OF_LINE return BOOLEAN;

Оперирует над файлом вида IN_FILE. Возвращает значение TRUE, если текущий элемент файла — это признак конца строчки или признак конца файла; в противном случае возвращает значение FALSE.

Если вид файла не IN_FILE, то возбуждается исключение MODE_ERROR.

procedure NEW_PAGE(FILE : in FILE_TYPE);
procedure NEW_PAGE;

Оперирует над файлом вида OUT_FILE. Если текущая строчка не завершена или текущая страница пустая (т.е. текущие номера строчки или столбца оба равны единице), то выводит признак конца строчки. Затем выводит признак конца страницы, который завершает текущую страницу. Увеличивает номер текущей страницы на единицу, а текущие номера столбца и строчки устанавливает равными единице.

Если вид файла не OUT_FILE, то возбуждается исключение MODE_ERROR.

procedure SKIP_PAGE(FILE: in FILE_TYPE);
procedure SKIP_PAGE;

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

Если вид файла не IN_FILE, то возбуждается исключение MODE_ERROR. При попытке прочитать признак конца файла возбуждается исключение END_ERROR.

function END_OF_PAGE(FILE : in FILE_TYPE) return BOOLEAN;
function END_OF_PAGE return BOOLEAN;

Оперирует над файлом вида IN_FILE. Возвращает значение TRUE, если очередными элементами файла является последовательность из признаков конца строчки и страницы или если очередным элементов является признак конца файла; в противном случае возвращает значение FALSE.

Если вид файла отличен от IN_FILE, то возбуждается исключение MODE_ERROR.

function END_OF_FILE(FILE : in FILE_TYPE) return BOOLEAN;
function END_OP_FILE return BOOLEAN;

Оперирует над файлом вида IN_FILE. Возвращает значение TRUE, если очередным элементом файла является признак конца файла или последовательность из признаков конца строчки, страницы и файла; в противном случае возвращает значение FALSE.

Если вид файла отличен от IN_FILE, то возбуждается исключение MODE_ERROR. Следующие подпрограммы предназначены для управления текущей позицией чтения или

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

procedure SET_COL(FILE : in FILE_TYPE; TO : in POSITIVE_COUNT);
procedure SET_COL(TO  : in POSITIVE_COUNT);

Для файла вида OUT_FILE:

Если значение параметра ТО больше текущего номера столбца, то выводит пробелы, причем после вывода каждого пробела увеличивает текущий номер столбца на единицу. Это повторяется до тех пор, пока текущий номер столбца не станет равным значению параметра ТО. Если значение параметра ТО было равно текущему номеру столбца, то никаких действий не производит. Если значение параметра ТО меньше текущего номера столбца, то сначала выполняет действия, эквивалентные вызову процедуры NEW_LINE( SPACING = 1), затем выводит (ТО — 1) пробелов и текущий номер столбца устанавливает равным значению параметра ТО.

Если при ограниченной длине строчки (т.е. LINE_LENGTH для этого файла имеет ненулевое значение) значение параметра ТО оказалось больше LINE-LENGTH, то возбуждается исключение LAYOUT_ERROR.

Для файла вида IN_FILE:

Читает и пропускает (игнорирует) отдельные символы, признаки конца строчки и страницы до тех пор, пока номер столбца очередного, подлежащего чтению символа не станет равным значению параметра ТО. Если текущий номер столбца с самого начала равен этому значению, то никаких действий не производит. При передаче каждого символа или признака конца должным образом корректирует текущие номера столбца, строчки и страницы, как при работе процедуры GET (см. 14.3.5). (Короткие строчки будут пропущены целиком, пока не встретится строчка, содержащая символ в указанной позиции от начала строчки.)

При попытке чтения признака конца файла возбуждается исключение END_ERROR.

procedure SET_LINE(FILE : in FILE_TYPE; TO : in POSITIVE_COUNT);
procedure SET_LINE(TO   : in POSITIVE_COUNT);

Для файла вида OUT_FILE:

Если значение параметра ТО больше текущего номера строчки, то эта процедура эквивалентна повторным вызовам NEW_LINE (SPACING = 1) до тех пор, пока текущий номер строчки не станет равным значению параметра ТО. Если значение параметра ТО было равно текущему номеру строчки, то никаких действий не производит. Если значение параметра ТО меньше текущего номера строчки, то эта процедура эквивалентна вызову NEW-PAGE, за которым следует вызов NEW_LINE с параметром SPACING, равным (ТО — 1).

Если при ограниченной длине страницы (т.е. PAGE-LENGTH для этого файла имеет ненулевое значение) значение параметра ТО оказалось больше PAGE-LENGTH, то возбуждается исключение LAYOUT_ERROR.

Для файла вида IN_FILE:

Результат эквивалентен повторным вызовам процедуры SKIP_LINE (SPACING = 1) до тех пор, пока текущий номер строчки не примет значение параметра ТО. Если текущий номер строчки с самого начала был равен значению параметра ТО, то никаких действий не производит. (Короткие страницы будут пропущены целиком, пока не встретится страница, содержащая строчку в указанной позиции от начала страницы.)

При попытке чтения признака конца файла возбуждается исключение END_ERROR.

function COL(FILE : in FILE_TYPE) return POSITIVE_COUNT;
function COL return POSITIVE_COUNT;

Возвращает текущий номер столбца. Если этот номер больше значения COUNT'LAST, это возбуждается исключение LAYOUT_ERROR.

function LINE(FILE : in FILE_TYPE) return POSITIVE_COUNT;
function LINE return POSITIVE_COUNT;

Возвращает текущий номер строчки.

Если этот номер больше значения COUNT'LAST, то возбуждается исключение LAYOUT_ERROR.

function PAGE(FILE : in FILE_TYPE) return POSITIVE_COUNT;
function PAGE return POSITIVE_COUNT;

Возвращает текущий номер страницы.

Если этот номер больше значения COUNT'LAST, то возбуждается исключение LAYOUT_ERROR.

Номера столбца, строчки или страницы, вообще говоря, могут превысить значение COUNT'LAST (в результате ввода или вывода достаточно большого числа символов, строчек или страниц). При этом никакое исключение не возбуждается. Однако при вызове функции COL, LINE или PAGE если соответствующий номер оказался больше COUNT'LAST, то возбуждается исключение LAYOUT_ERROR.

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

Ссыпки: вид IN_FILE 14.1, длина страницы 14.3, исключение END_ERROR 14.4, исключение LAYOUT_ERROR 14.4, исключение MODE_ERROR 14.4, исключение STATUS_ERROR 14.4, максимальная длина страницы 14.3, номер строчки 14.3, открытый файл 14.1, признак конца страницы 14.3, признак конца строчки 14.3, признак конца файла 14.3, процедура GET 14.3.5, страница 14.3, строчка 14.3, текущий номер столбца 14.3, текущий номер страницы 14.3, текущий номер строчки 14.3, текущий файл по умолчанию 14.3, тип POSITIVE_COUNT 14.3, файл 14.1.

14.3.5. ПРОЦЕДУРЫ ОБМЕНА

В разд. 14.3.5—14.3.10 описаны процедуры GET и PUT для элементов типов CHARACTER, STRING, числового и перечислимого. В данном разделе описаны возможности этих процедур, общие для большинства таких типов. Процедуры GET и PUT для элементов типов CHARACTER и STRING передают отдельные символьные значения, а для числовых и перечислимых типов передают лексемы.

Первым параметром всех процедур GET и PUT является файл. Если он опущен, то подразумевается, что используется текущий файл (ввода или вывода) по умолчанию. Каждая процедура GET оперирует над файлом вида IN_FILE. Каждая процедура PUT оперирует над файлом вида OUT_FILE.

Все процедуры GET и PUT меняют для заданного файла текущие номера столбца, строчки и страницы: каждая передача символа увеличивает на единицу текущий номер столбца. Каждый вывод признака конца строчки устанавливает текущий номер столбца равным единице и добавляет единицу к текущему номеру строчки. Каждый вывод признака конца страницы устанавливает текущие номера столбца и строчки равными единице и добавляет единицу к текущему номеру страницы. При вводе каждый пропуск признака конца строчки устанавливает текущий номер столбца равным единице и добавляет единицу к текущему номеру строчки;

каждый пропуск признака конца страницы устанавливает текущие номера столбца и строчки равными единице и добавляет единицу к текущему номеру страницы. Аналогичным образом определяется семантика процедур GET_LINE, PUT_LINE и SET-COL

Некоторые процедуры GET и PUT для числовых и перечислимых типов имеют параметры, задающие формат; он указывает длины полей; эти параметры принадлежат неотрицательному подтипу FIELD типа INTEGER.

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

Процедуры GET для числовых типов имеют параметр WIDTH, задающий формат. Если он имеет нулевое значение, то процедура GET выполняется так же, как для перечислимых типов,

но вместо синтаксиса литералов перечисления используется синтаксис числовых литералов. При ненулевом значении параметра WIDTH вводится ровно WIDTH символов или, если ранее встретился признак конца строчки, все символы до признака конца строчки; в это число включаются и все ведущие пропуски. Для числовых литералов используется расширенный синтаксис, в котором допускается знак числа (но не пропуски или признаки конца строчки или страницы внутри литерала).

Любая процедура PUT для элемента числового или перечислимого типа выводит значение элемента соответственно как числовой литерал, идентификатор или символьный литерал. Перед ними могут быть выведены пробелы, если этого требуют параметры формата WIDTH или FORE (это описано ниже), и для отрицательных значений — знак минус; в случае перечислимого типа пробелы выводятся не перед литералом, а после него. Если формат в процедуре PUT задает недостаточную ширину, то он игнорируется.

Следующие две ситуации могут возникнуть при выполнении процедуры PUT для числового или перечислимого типа в случае ограниченной длины строчки используемого файла вывода (т.е. длина строчки имеет ненулевое значение). Если число выводимых символов не превышает максимальной длины строчки, но при выводе этих символов, начиная с текущего столбца, они не помещаются в текущей строчке, то перед их выводом выполняются действия, эквивалентные вызову NEW_LINE с параметром SPACING, равным единице. Если же число выводимых символов больше максимальной длины строчки, то возбуждается исключение LAYOUT_ERROR, при этом символы не выводятся.

Если используемый в процедурах GET, GET_LINE, PUT и PUT_LINE файл не открыт, то возбуждается исключение STATUS_ERROR. Если в процедурах GET и GET_LINE вид используемого файла отличен от IN_LINE или в процедурах PUT и PUT_LINE вид используемого файла отличен от OUT_FILE, то возбуждается исключение MODE_ERROR.

В процедуре GET при попытке пропуска признака конца файла возбуждается исключение END_ERROR. Если вся введенная процедурой GET последовательность символов не является лексемой соответствующего типа, то возбуждается исключение DATA_ERROR; в частности, оно возбуждается, если не было введено ни одного символа; для числового типа если был введен знак, то это правило относится к следующему за ним числовому литералу. В случае процедуры PUT, выводящей элемент типа STRING, если длина строки файла недостаточна для вывода заданного элемента, то возбуждается исключение LAYOUT_ERROR.

Примеры:

В примерах этого раздела и в разд. 14.3.7 и 14.3.8 кавычки и строчная буква Ь не вводятся и не выводятся; они даны только для того, чтобы показать расположение и пробелы.

N : INTEGER;
   ...
GET(N);

-— символы на входе | вводимая последовательность | значение N
bb-12535Ь | -12535 | -12535
bb12_535Е1Ь | 12_535Е1 | 125350
bb12_535Е; | 12535Е | (нет) DATA_ERROR Возбуждено

Пример игнорирования параметра ширины:

PUT(ITEM => -23, WIDTH => 2);   -- "-23"

Ссылки- вид 14.1, вид файла IN_FILE 14.1, вид файла OUT_FILE 14.1, исключение DATA_ERROR 14.4, исключение END_ERROR 14.4, исключение LAYOUT_ERROR 14.4, исключение MODE_ERROR 14.4, исключение STATUS_ERROR 14.4, максимальная длина строчки 14.3, номер столбца 14.3, номер страницы 14.3, номер строчки 14.3, параметр FORE 14.3.8, параметр WIDTH 143.5, 14.3.7, 14,3.9, признак конца страницы 14.1, признак конца строчки 14.1, пропуск 14.3.9, просмотреть 14.3.7, 14.3.8, 14.3.9, процедура GET 14.3.6, 14.3.7, 14.3.8, 14.3.9, процедура NEW_LINE 14.3.4, процедура PUT 14.3.6, 14.3.7, 14.3.8, 14.3.9, текущий файл по умолчанию 14.3, файл 14.1.

14.3.6. ВВОД-ВЫВОД СИМВОЛОВ И СТРОК

Для элемента типа CHARACTER определены следующие процедуры:

procedure GET(FILE : in FILE_TYPE; ITEM : out CHARACTER);
procedure GET(ITEM : out CHARACTER);

В заданном файле ввода процедуры пропускают признаки конца строчки и страницы и читают следующий за ними символ; значение этого символа возвращают параметру ITEM вида out.

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

procedure PUT(FILE : in FILE_TYPE; ITEM : in CHARACTER);
procedure PUT(ITEM : in CHARACTER);

Если длина строчки заданного файла вывода ограничена (т. е. не равна нулю по соглашению), а текущий номер столбца превышает эту длину, то выполняют действия, эквивалентные вызову процедуры NEW_LINE с параметром SPACING, равным единице. Затем в любом случае в файл выводят заданный символ.

Для элемента типа STRING определены следующие процедуры:

procedure GET(FILE : In FILE_TYPE; ITEM : out STRING);
procedure GET(ITEM : out STRING);

Определяют длину (число символов) данной строки; затем для последовательных символов строки соответствующее число раз выполняют операцию GET (в частности, для пустой строки никаких действий не выполняют).

procedure PUT(FILE : in FILE_TYPE; ITEM : in STRING);
procedure PUT(ITEM : in STRING);

Определяют длину (число символов) данной строки; затем для последовательных символов строки соответствующее число раз выполняют операцию PUT (в частности, для пустой строки никаких действий не выполняют).

procedure GET_LINE(FILE : in FILE_TYPE; ITEM : out STRING; LAST : out NATURAL);
procedure GET_LINE(ITEM : out STRING; LAST : out NATURAL);

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

в этом случае выполняют действия, эквивалентные действиям процедуры SKIP_LINE с пара- метром SPACING, равным единице. Чтение также заканчивается при достижении конца строки, заданной параметром ITEM. Символы, которые не были заменены, остаются неопределенными.

Если символы прочитаны, то в параметр LAST возвращается индекс последнего замененного символа так, что индексированная компонента ITEM (LAST) — это значение последнего замененного символа (индекс первого замененного символа равен атрибуту ITEM'FIRST). Если не было прочитано ни одного символа, то в LAST выдается значение индекса, на единицу меньшее атрибута ITEM'FIRST.

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

procedure PUT_LINE(FILE : in FILE.TYPE; ITEM : in STRING);
procedure PUT_LINE(ITEM : in STRING);

Вызывают процедуру PUT для заданной строки, затем процедуру NEW_LINE с параметром SPACING, равным единице.

Примечание. Внешние кавычки строкового литерала, являющегося параметром процедуры PUT, не выводятся. Каждый сдвоенный символ кавычки, приведенный внутри такого литерала, выводится как один символ кавычки; это следует из правил для строковых литералов (см. 2.6).

Строка, считываемая процедурой GET или записываемая процедурой PUT, в файле может занимать несколько строчек.

Ссылки: длина строки 14.3, длина строчки 14.3, 14.3.5, исключение END_ERROR 14.4, признак конца страницы 14.3, процедура GET 14.3.5, процедура NEW_LINE 14.3.4, процедура PUT 14.3.4, строчка 14.3, текущий номер столбца 14.3, файл 14.1.

14.3.7. ВВОД-ВЫВОД ДЛЯ ЦЕЛЫХ ТИПОВ

Описанные ниже процедуры определены в настраиваемом пакете INTEGER_IO. Он должен быть конкретизован с соответствующим целым типом (указанным в спецификации параметром настройки NUM).

Значения выводятся в виде десятичных литералов или литералов с основанием, без подчеркиваний и порядка, с предшествующим знаком минус для отрицательных чисел. Формат, определяющий ширину поля (включая ведущие пробелы и знак минус), может быть задан необязательным параметром WIDTH. Его значение принадлежит неотрицательному целому подтипу FIELD. Значения основания принадлежат целому подтипу NUMBER-BASE.

subtype NUMBER_BASE is INTEGER range 2 .. 16;

В процедурах вывода могут использоваться ширина поля и основание по умолчанию; они задаются переменными, описанными в настраиваемом пакете INTEGER_IO:

DEFAULT_WIDTH : FIELD := NUM_WIDTH;
DEFAULT_BASE   : NUMBER_BASE ;= 10;

Определены следующие процедуры:

procedure GET(FILE : In FILE_TYPE; ITEM : out NUM; WIDTH : in FIELD := 0);
procedure GET(ITEM : out NUM; WIDTH : in FIELD := 0);

При нулевом значении параметра WIDTH пропускают все ведущие пропуски, признаки конца строчки и страницы, читают знак плюс или минус (если он есть), затем производят чтение в соответствии с синтаксисом целого литерала (он может быть литералом с основанием). При нулевом значении WIDTH вводят ровно WIDTH символов, или если раньше встретится признак конца строки, то вводят лишь символы до этого признака конца (возможно, ни одного); в это количество включаются и все ведущие пропуски.

В параметр ITEM типа NUM возвращают значение, соответствующее введенной последовательности.

Если введенная последовательность не соответствует правилам синтаксиса или если полученное значение не принадлежит подтипу NUM, то возбуждается исключение DATA_ERROR.

procedure PUT(FILE  :    in FILE_TYPE;
              ITEM  :    in NUM;
              WIDTH :    in FIELD := DEFAULT_WIDTH;
              BASE  :    in NUMBER_BASE := DEFAULT_BASE);

procedure PUT(ITEM  :    in NUM;
              WIDTH :    in FIELD := DEFAULT_WIDTH;
              BASE  :    in NUMBER_BASE := DEFAULT_BASE);

Значение параметра ITEM выводят в виде целого литерала без подчеркиваний, порядка и ведущих нулей (если значение равно нулю, выводят один нуль), с предшествующим знаком минус, если значение отрицательное.

Если число символов выводимой последовательности меньше значения WIDTH, то она дополняется ведущими пробелами.

Если параметр BASE (заданный явно указанным значением или переменной DEFAULT_BASE) имеет значение десять, то числа выводятся по синтаксису десятичного литерала, в противном случае — по синтаксису литерала с основанием и всеми прописными буквами.

procedure GET(FROM : in STRING; ITEM : out NUM; LAST : out POSITIVE);

Читает с начала строки, заданной параметром FROM, целое значение по тем же правилам, что и процедура GET, которая читает целое значение из файла; при этом рассматривает конец строки как признак конца файла. Через параметр ITEM возвращает значение типа NUM, соответствующее введенной последовательности. Через параметр LAST возвращает значение индекса, соответствующее последнему читаемому символу (следовательно, этот символ имеет значение индексированной компоненты FROM(LAST)).

Если введенная последовательность не соответствует правилам синтаксиса или если полученное значение не принадлежит подтипу NUM, то возбуждается исключение DATA_ERROR.

procedure PUT(TO   :   out STRING;
              ITEM :    in NUM;
              BASE :    in NUMBER_BASE := DEFAULT_BASE);

Через параметр ТО выводит значение параметра ITEM по тем же правилам, что и при выводе в файл; в качестве значения параметра WIDTH используется длина указанной строки.

Примеры:

package INT_IO is new INTEGER_IO(SMALUNT); use INT_IO;
-— в результате конкретизации
-— получается формат по умолчанию:
—— DEFAULT_WIDTH = 4, DEFAULT_BASE = 10

PUT(126);                              -- "b126"
PUT(-126, 7);                          -- "ЬЬЬ-126"
PUT(126, WIDTH => 13, BASE => 2);      -- "bbb2#1111110#"

Ссылки: десятичный литерал 2.4.1, исключение DATA_ERROR 14.4, исключение LAYOUT_ERROR 14.4, литерал с основанием 2.4.2, пакет INTEGER_IO 14.3.10, параметр WIDTH 14.3.5, подтип FIELD 14.3.5, признак конца строчки 14.3, пропуск 14.3.5, просмотреть 14.3.5, процедура GET 14.3.5, процедура PUT 14.3.5, тип FILE_TYPE 14.1, целый литерал 2.4.

14.3.8. ВВОД-ВЫВОД ДЛЯ ВЕЩЕСТВЕННЫХ ТИПОВ

Следующие процедуры определены в настраиваемых пакетах FLOAT_IO и FIXED_IO, которые должны быть конкретизованы с соответствующим плавающим или фиксированным типом (указанным в спецификации параметром NUM).

Значения выводятся как десятичные литералы без подчеркиваний. Формат каждого выводимого значения состоит из поля FORE, десятичной точки, поля AFT, а также (при ненулевом значении параметра ЕХР) буквы Е и поля ЕХР. Таким образом, возможны два формата:

FORE . AFT
и
FORE . AFT E ЕХР

без всяких пробелов между этими полями. Поле FORE может включать предшествующие пробелы и знак минус для отрицательных значений. Поле AFT состоит из одних лишь десятичных цифр (оно может оканчиваться нулями). Поле ЕХР состоит из знака (плюс или минус) и порядка (возможно, с предшествующими нулями).

Для плавающих типов длины этих полей по умолчанию определены переменными, описанными в пакете FLOAT_IO:

DEFAULT_FORE : FIELD := 2;
DEFAULT_APT  : FIELD := NUM'DIGITS-1;
DEFAULT_EXP  : FIELD := 3;

Для фиксированных типов длины по умолчанию для этих полей задаются переменными, описанными в пакете FIXED_IO:

DEFAULT_FORE : FIELD := NUM'FORE;
DEFAULT_AFT  : FIELD := NUM'AFT;
DEFAULT_EXP  : FIELD := 0;

Определены следующие процедуры:

procedure GET(FILE : in FILE_TYPE; ITEM : out NUM; WIDTH : in FIELD := 0);
procedure GET(ITEM : out NUM; WIDTH   : in FIELD := 0);

При нулевом значении параметра WIDTH опускают все ведущие пропуски, признак конца строчки или признак конца страницы, читают знак плюс или минус (если он есть); затем производят чтение в соответствии с синтаксисом вещественного литерала (он может быть литералом с основанием). При ненулевом значении параметра WIDTH вводят или ровно WIDTH символов, или, если раньше встретился признак конца строчки, лишь символы, читаемые до этого признака конца (возможно, ни одного символа); в это количество включаются и все предшествующие пропуски.

Через параметр ITEM возвращают значение типа NUM, соответствующее введенной последовательности.

Если введенная последовательность не удовлетворяет требованиям синтаксиса или если полученное значение не принадлежит подтипу NUM, то возбуждается исключение DATA_ERROR.

procedure PUT(FILE : in FILE_TYPE;
              ITEM : in NUM;
              FORE : in FIELD := DEFAULT_FORE;
              AFT  : in FIELD := DEFAULT_AFT;
              EXP  : in FIELD := DEFAULT_EXP);

procedure PUT(ITEM : in NUM;
              FORE : in FIELD := DEFAULT_FORE;
              AFT  : in FIELD := DEFAULT_AFT;
              EXP  : in FIELD := DEFAULT_EXP);

Выводят значение параметра ITEM в виде десятичного литерала в формате, определяемом параметрами FORE, AFT и ЕХР. Если значение ITEM отрицательное, то в целую часть включен знак минус. При нулевом значении параметра ЕХР целая часть представляется таким количеством цифр, которое требуется для представления целой части значения ITEM. При необходимости значение FORE игнорируется. Если в значении ITEM нет целой части, то целая часть представляется цифрой 0.

Если значение ЕХР больше нуля, то целая часть представляется одной цифрой, отличной от нуля, за исключением случая, когда значение ITEM равно 0.0.

В обоих случаях, если целая часть, включая знак минус, содержит менее FORE символов, она дополняется до этого количества ведущими нулями. Дробная часть состоит из AFT цифр или при AFT, равном нулю, из одной цифры. Значение округляется; остаток, равный половине последнего разряда, может быть округлен как с избытком, так и с недостатком.

При нулевом значении ЕХР число выводится без порядка. Если ЕХР больше нуля, то при . выводе порядка выводится столько цифр, сколько необходимо для представления порядка значения ITEM (для представления целой части этого значения используется один символ); первым символом является знак плюс или минус. Если для представления порядка, включая знак, используется менее ЕХР символов, то это представление дополняется до требуемого количества символов ведущими нулями. Для значения ITEM, равного 0.0, порядок равен нулю.

procedure GET(FROM : in STRING; ITEM : out NUM; LAST : out POSITIVE);

Читает с начала строки, заданной параметром FROM, вещественное значение по тем же правилам, что и процедура GET, читающая вещественное значение из файла; при этом конец строки рассматривается как признак конца файла. Через параметр ITEM возвращает значение типа NUM, соответствующее введенной последовательности. Через параметр LAST возвращает значение индекса, соответствующее последнему читаемому символу (следовательно, этот символ имеет значение индексируемой компоненты FROM (LAST)).

Если введенная последовательность не соответствует правилам синтаксиса или если полученное значение не принадлежит подтипу NUM, то возбуждает исключение DATA_ERROR.

procedure PUT(TO   : out STRING;
              ITEM : in NUM;
              AFT  : in FIELD   := DEFAULT_AFT;
              EXP  : in INTEGER := DEFAULT_EXP);

Через параметр ТО выводит значение параметра ITEM по тем же правилам, что и при выводе в файл; при этом в качестве FORE использует такое значение, чтобы общее число выводимых символов, включая предшествующие пробелы, соответствовало длине строки параметра ТО.

Примеры:

package REAL_IO is new FLOAT_IO(REAL); use REAL_IO;
-- в "результате конкретизации
-- получается формат по умолчанию: DEFAULTEXP = 3
X : REAL :=-123.4567; -— 8 цифр (СМ. 3.5.7)

PUT(X); --формат по умолчанию             "-1.2345670Е+02"
PUT(X, FORE => 5, AFT => 3, ЕХР => 2); -- "ЬЬЬ-1.235Е+2"
PUT(X, 5, 3, 0);                       -- "Ь-123.457"

Примечание. Если положительное число, выводимое процедурой PUT в строку, заполняет строку целиком, без использования ведущих пробелов, то при выводе такого же отрицательного числа будет возбуждено исключение LAYOUT_ERROR.

Ссылки: атрибут AFT 3.5.10, атрибут FORE 3.5.10, вещественный литерал 2.4, десятичный литерал 2.4.1, признак конца строчки 14.3.5, исключение DATA_ERROR 14.4, исключение LAYOUT_ERROR 14.4, литерал с основанием 2.4.2, пакет FIXED_IO 14.3.10, пакет FLOAT_IO 14.3.10, параметр WIDTH 14.3.5, подтип FIELD 14.3.5, пропуск 14.3.5, просмотреть 14.3.5, процедура GET 14.3.5, процедура PUT 14.3.5, тип FILE_TYPE 14.1.

14.3.9. ВВОД-ВЫВОД ДЛЯ ПЕРЕЧИСЛИМЫХ ТИПОВ

Описанные ниже процедуры определены в настраиваемом пакете ENUMERATION_IO, который должен быть конкретизован с соответствующим перечислимым типом (указанным в спецификации параметром настройки ENUM).

При выводе значений для представления идентификаторов используются либо строчные, либо прописные буквы. Это задается параметром SET, который принадлежит перечислимому типу TYPE-SET:

type TYPE_SET is (LOWER_CASE, UPPER_CASE);

Формат (в который включаются и заключительные пробелы) может быть задан необязательным параметром ширины поля. Ширина поля по умолчанию и представление букв задаются описанными в настраиваемом пакете ENUMERATION_IO переменными:

DEFAULT_WIDTH   : FIELD := 0;
DEFAULT_SETTING : TYPE_SET := UPPER_CASE;

Определены следующие процедуры:

procedure GET(FILE : in FILE_TYPE; ITEM : out ENUM);
procedure GET(ITEM : out ENUM);

После игнорирования предшествующих пропусков, признака конца строчки и признака конца страницы читают или идентификатор (строчные и прописные буквы считаются эквивалентными), или символьный литерал (включая апострофы); чтение производится в соответствии с синтаксисом соответствующих лексем. Через параметр ITEM возвращают значение, соответствующее введенной последовательности.

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

procedure PUT(FILE  : in FILE_TYPE;
              ITEM  : in ENUM;
              WIDTH : in FIELD := DEFAULT_WIDTH;
              SET   : in TYPE_SET := DEFAULT_SETTING);

procedure PUT(ITEM  :in ENUM;
              WIDTH : in FIELD := DEFAULT_WIDTH;
              SET   : in TYPE_SET := DEFAULT_SETTING);

Выводят значение параметра ITEM как литерал перечисления (либо идентификатор, либо символьный литерал). Необязательный параметр SET указывает, какие буквы — строчные или прописные — следует использовать для представления идентификаторов (для символьных литералов он игнорируется). Если число выводимых символов меньше значения параметра WIDTH, то после них выводятся пробелы, дополняющие число символов до WIDTH.

procedure GET(FROM : in STRING; ITEM : out ENUM; LAST : out POSITIVE);

Читает с начала строки, заданной параметром FROM, значение перечислимого типа по тем же правилам, что и процедура GET, читающая значение перечислимого типа из файла; при этом конец строки рассматривается как признак конца файла. Через параметр ITEM возвращает значение типа ENUM, соответствующее введенной последовательности. Через параметр LAST возвращает значение индекса, соответствующее последнему читаемому символу (следовательно, этот символ имеет значение индексируемой компоненты FROM (LAST)).

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

procedure PUT(TO   : out STRING;
              ITEM : in ENUM;
              SET  : in TYPE_SET := DEFAULT_SETTING);

Выводит в строку, заданную параметром ТО, значение параметра ITEM по тем же правилам, что и при выводе в файл; в качестве значения параметра WIDTH используется длина указанной строки.

Хотя спецификация пакета ENUMERATION_IO допускает конкретизацию с соответствующим целым типом, это не является целью данного пакета; язык не определяет результата такой конкретизации.

Примечание. Процедуры PUT для символов и для перечислимых значений имеют определенные различия:

TEXT_IO.PUT('A');   -— выводит символ А

package CHAR_IO is new TEXT_IO.ENUMERATION_IO(CHARACTER);
CHAR_IO.PUT('A');  -— выводит символ 'А', заключенный в одинарные кавычки

Тип BOOLEAN является перечислимым типом, поэтому пакет ENUMERATION_IO может быть настроен на этот тип.

Ссылки: исключение DATA_ERROR 14.4, пакет ENUMERATION_IO 14.3.10, параметр WIDTH 14.3.5, подтип FIELD 14.3.5, признак конца строчки 14.3.5, пропуск 14.3.5, просмотреть 14.3.5, процедура GET 14.3.5, процедура PUT 14.3.5, тип FILE_TYPE 14.1.

14.3.10. СПЕЦИФИКАЦИЯ ПАКЕТА ВВОДА-ВЫВОДА ТЕКСТА

with IO_EXCEPTIONS;
package TEXT_IO is

   type FILE_TYPE is limited private;

   type FILE_MODE is (IN_FILE, OUT_FILE);

   type COUNT is range 0 .. определяется_реапизацией;
   subtype POSITIVE_COUNT is COUNT range 1 .. COUNT'LAST;
   UNBOUNDED : constant COUNT := 0; -- длина строчки и страницы

   subtype FIELD       is INTEGER range 0 .. определяется_реапизацией;
   subtype NUMBER_BASE is INTEGER range 2 .. 16;

   type TYPE_SET is (LOWER_CASE, UPPER_CASE);

   -- управление файлами

   procedure CREATE (FILE : in out FILE_TYPE;
                     MODE : in FILE_MODE := OUT_FILE;
                     NAME : in STRING    := "";
                     FORM : in STRING    := "");

   procedure OPEN   (FILE : in out FILE_TYPE;
                     MODE : in FILE_MODE;
                     NAME : in STRING;
                     FORM : in STRING := "");

   procedure CLOSE  (FILE : in out FILE_TYPE);
   procedure DELETE (FILE : in out FILE_TYPE);
   procedure RESET  (FILE : in out FILE_TYPE; MODE : in FILE_MODE);
   procedure RESET  (FILE : in out FILE_TYPE);

   function  MODE   (FILE : in FILE_TYPE) return FILE_MODE;
   function  NAME   (FILE : in FILE_TYPE) return STRING;
   function  FORM   (FILE : in FILE_TYPE) return STRING;

   function  IS_OPEN(FILE : in FILE_TYPE) return BOOLEAN;

   -- управление файлами ввода и вывода по умолчанию

   procedure SET_INPUT (FILE : in FILE_TYPE);
   procedure SET_OUTPUT(FILE : in FILE_TYPE);

   function STANDARD_INPUT  return FILE_TYPE;
   function STANDARD_OUTPUT return FILE_TYPE;

   function CURRENT_INPUT   return FILE_TYPE;
   function CURRENT_OUTPUT  return FILE_TYPE;

   -- спецификация длин строчки и страницы

   procedure SET_LINE_LENGTH(FILE : in FILE_TYPE; TO : in COUNT);
   procedure SET_LINE_LENGTH(TO : in COUNT);

   procedure SET_PAGE_LENGTH(FILE : in FILE_TYPE; TO : in COUNT);
   procedure SET_PAGE_LENGTH(TO : in COUNT);

   function  LINE_LENGTH(FILE : in FILE_TYPE) return COUNT;
   function  LINE_LENGTH return COUNT;

   function  PAGE_LENGTH(FILE : in FILE_TYPE) return COUNT;
   function  PAGE_LENGTH return COUNT;

   -- управление колонкой, строчкой и страницей

   procedure NEW_LINE   (FILE : in FILE_TYPE; SPACING : in POSITIVE_COUNT := 1);
   procedure NEW_LINE   (SPACING : in POSITIVE_COUNT := 1);

   procedure SKIP_LINE  (FILE : in FILE_TYPE; SPACING : in POSITIVE_COUNT := 1);
   procedure SKIP_LINE  (SPACING : in POSITIVE_COUNT := 1);

   function  END_OF_LINE(FILE : in FILE_TYPE) return BOOLEAN;
   function  END_OF_LINE return BOOLEAN;

   procedure NEW_PAGE   (FILE : in FILE_TYPE);
   procedure NEW_PAGE;

   procedure SKIP_PAGE  (FILE : in FILE_TYPE);
   procedure SKIP_PAGE;

   function  END_OF_PAGE(FILE : in FILE_TYPE) return BOOLEAN;
   function  END_OF_PAGE return BOOLEAN;

   function  END_OF_FILE(FILE : in FILE_TYPE) return BOOLEAN;
   function  END_OF_FILE return BOOLEAN;

   procedure SET_COL (FILE : in FILE_TYPE; TO : in POSITIVE_COUNT);
   procedure SET_COL (TO   : in POSITIVE_COUNT);

   procedure SET_LINE(FILE : in FILE_TYPE; TO : in POSITIVE_COUNT);
   procedure SET_LINE(TO   : in POSITIVE_COUNT);

   function COL (FILE : in FILE_TYPE) return POSITIVE_COUNT;
   function COL  return POSITIVE_COUNT;

   function LINE(FILE : in FILE_TYPE) return POSITIVE_COUNT;
   function LINE return POSITIVE_COUNT;

   function PAGE(FILE : in FILE_TYPE) return POSITIVE_COUNT;
   function PAGE return POSITIVE_COUNT;

   -- символьный ввод-вывод

   procedure GET(FILE : in  FILE_TYPE; ITEM : out CHARACTER);
   procedure GET(ITEM : out CHARACTER);
   procedure PUT(FILE : in  FILE_TYPE; ITEM : in CHARACTER);
   procedure PUT(ITEM : in  CHARACTER);

   -- строковый ввод-вывод

   procedure GET(FILE : in  FILE_TYPE; ITEM : out STRING);
   procedure GET(ITEM : out STRING);
   procedure PUT(FILE : in  FILE_TYPE; ITEM : in STRING);
   procedure PUT(ITEM : in  STRING);

   procedure GET_LINE(FILE : in  FILE_TYPE; ITEM : out STRING; LAST :
     out NATURAL);
   procedure GET_LINE(ITEM : out STRING; LAST : out NATURAL);
   procedure PUT_LINE(FILE : in  FILE_TYPE; ITEM : in STRING);
   procedure PUT_LINE(ITEM : in  STRING);

   -- настраиваемый пакет для ввода-вывода целых типов

   generic
      type NUM is range <>;
   package INTEGER_IO is

      DEFAULT_WIDTH : FIELD := NUM'WIDTH;
      DEFAULT_BASE  : NUMBER_BASE := 10;

      procedure GET(FILE : in  FILE_TYPE; ITEM : out NUM; WIDTH : in FIELD := 0);
      procedure GET(ITEM : out NUM; WIDTH : in FIELD := 0);

      procedure PUT(FILE  : in FILE_TYPE;
                    ITEM  : in NUM;
                    WIDTH : in FIELD := DEFAULT_WIDTH;
                    BASE  : in NUMBER_BASE := DEFAULT_BASE);
      procedure PUT(ITEM  : in NUM;
                    WIDTH : in FIELD := DEFAULT_WIDTH;
                    BASE  : in NUMBER_BASE := DEFAULT_BASE);
      procedure GET(FROM : in  STRING; ITEM : out NUM; LAST : out POSITIVE);
      procedure PUT(TO   : out STRING;
                    ITEM : in NUM;
                    BASE : in NUMBER_BASE := DEFAULT_BASE);

 end INTEGER_IO;

   -- настраиваемый пакет для ввода-вывода вещественных типов

   generic
      type NUM is digits <>;
   package FLOAT_IO is

      DEFAULT_FORE : FIELD := 2;
      DEFAULT_AFT  : FIELD := NUM'DIGITS-1;
      DEFAULT_EXP  : FIELD := 3;

      procedure GET(FILE : in FILE_TYPE; ITEM : out NUM; WIDTH : in FIELD := 0);
      procedure GET(ITEM : out NUM; WIDTH : in FIELD := 0);

      procedure PUT(FILE : in FILE_TYPE;
                    ITEM : in NUM;
                    FORE : in FIELD := DEFAULT_FORE;
                    AFT  : in FIELD := DEFAULT_AFT;
                    EXP  : in FIELD := DEFAULT_EXP);
      procedure PUT(ITEM : in NUM;
                    FORE : in FIELD := DEFAULT_FORE;
                    AFT  : in FIELD := DEFAULT_AFT;
                    EXP  : in FIELD := DEFAULT_EXP);

     procedure GET(FROM : in STRING; ITEM : out NUM; LAST : out POSITIVE);
       procedure PUT(TO   : out STRING;
                    ITEM : in NUM;
                    AFT  : in FIELD := DEFAULT_AFT;
                    EXP  : in FIELD := DEFAULT_EXP);
   end FLOAT_IO;

   generic
      type NUM is delta <>;
   package FIXED_IO is

      DEFAULT_FORE : FIELD := NUM'FORE;
      DEFAULT_AFT  : FIELD := NUM'AFT;
      DEFAULT_EXP  : FIELD := 0;

      procedure GET(FILE : in FILE_TYPE; ITEM : out NUM; WIDTH : in FIELD := 0);
      procedure GET(ITEM : out NUM; WIDTH : in FIELD := 0);

      procedure PUT(FILE : in FILE_TYPE;
                    ITEM : in NUM;
                    FORE : in FIELD := DEFAULT_FORE;
                    AFT  : in FIELD := DEFAULT_AFT;
                    EXP  : in FIELD := DEFAULT_EXP);
      procedure PUT(ITEM : in NUM;
                    FORE : in FIELD := DEFAULT_FORE;
                    AFT  : in FIELD := DEFAULT_AFT;
                    EXP  : in FIELD := DEFAULT_EXP);

      procedure GET(FROM : in  STRING; ITEM : out NUM; LAST : out POSITIVE);
      procedure PUT(TO   : out STRING;
                    ITEM : in NUM;
                    AFT  : in FIELD := DEFAULT_AFT;
                    EXP  : in FIELD := DEFAULT_EXP);
   end FIXED_IO;

   -- настраиваемый пакет для ввода-вывода перечислимых типов

   generic
      type ENUM is (<>);
   package ENUMERATION_IO is

      DEFAULT_WIDTH   : FIELD := 0;
      DEFAULT_SETTING : TYPE_SET := UPPER_CASE;

      procedure GET(FILE  : in FILE_TYPE; ITEM : out ENUM);
      procedure GET(ITEM  : out ENUM);

      procedure PUT(FILE  : in FILE_TYPE;
                    ITEM  : in ENUM;
                    WIDTH : in FIELD    := DEFAULT_WIDTH;
                    SET   : in TYPE_SET := DEFAULT_SETTING);
      procedure PUT(ITEM  : in ENUM;
                    WIDTH : in FIELD    := DEFAULT_WIDTH;
                    SET   : in TYPE_SET := DEFAULT_SETTING);

      procedure GET(FROM : in  STRING; ITEM : out ENUM; LAST : out POSITIVE);
      procedure PUT(TO   : out STRING;
                    ITEM : in  ENUM;
                    SET  : in  TYPE_SET := DEFAULT_SETTING);
   end ENUMERATION_IO;

   -- исключения

   STATUS_ERROR : exception renames IO_EXCEPTIONS.STATUS_ERROR;
   MODE_ERROR   : exception renames IO_EXCEPTIONS.MODE_ERROR;
   NAME_ERROR   : exception renames IO_EXCEPTIONS.NAME_ERROR;
   USE_ERROR    : exception renames IO_EXCEPTIONS.USE_ERROR;
   DEVICE_ERROR : exception renames IO_EXCEPTIONS.DEVICE_ERROR;
   END_ERROR    : exception renames IO_EXCEPTIONS.END_ERROR;
   DATA_ERROR   : exception renames IO_EXCEPTIONS.DATA_ERROR;
   LAYOUT_ERROR : exception renames IO_EXCEPTIONS.LAYOUT_ERROR;

private
   -- определяется реализацией
end TEXT_IO;

Пред. | Уровень выше | След.
14.2. ФАЙЛЫ ПОСЛЕДОВАТЕЛЬНОГО И ПРЯМОГО ДОСТУПА | Начало | 14.4. ИСКЛЮЧЕНИЯ ПРИ ВВОДЕ-ВЫВОДЕ


14.4. ИСКЛЮЧЕНИЯ ПРИ ВВОДЕ-ВЫВОДЕ
Пред. Глава 14. ВВОД-ВЫВОД След.

14.4. ИСКЛЮЧЕНИЯ ПРИ ВВОДЕ-ВЫВОДЕ

В этом разделе описаны исключения, которые могут быть возбуждены при выполнении операций ввода-вывода. Они описаны в пакете IO_EXCEPTIONS; определение этого пакета приведено в разд. 14.5. Этот пакет упоминается в спецификаторах контекста каждого из трех описанных пакетов ввода-вывода. Для исключений NAME_ERROR, USE_ERROR и DEVICE_ERROR описаны общие характеристики условий возбуждения этих исключений; детальное описание должно быть приведено в приложении F. Если существует более чем одно ошибочное условие, соответствующее одному исключению, то возбуждается то из них, которое раньше описано в данном ниже списке исключений.

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

Исключение MODE_ERROR возбуждается при попытке чтения или проверке конца файла с текущим видом OUT_FILE, а также при попытке записи в файл с текущим видом IN_FILE. Для пакета TEXT_IO исключение MODE_ERROR возбуждается также при использовании файла с текущим видом OUT_FILE в качестве параметра подпрограмм SET_INPUT, SKIP_LINE, END_OF_LINE, SKIP_PAGE и END_OF_PAGE и при использовании файла с текущим видом IN_FILE в качестве параметра подпрограммы SET_OUTPUT, SET_LINE_LENGTH, SET_PAGE_LENGTH, LINE_LENGTH, PAGE_LENGTH, NEW_LINE или NEW_PAGE.

Исключение NAME_ERROR возбуждается при вызове процедур CREATE и OPEN, если строка, заданная параметром NAME, не позволяет идентифицировать внешний файл. Например, это исключение возбуждается, если такая строка вообще недопустима или если ей либо не соответствует ни один внешний файл, либо соответствует несколько внешних файлов.

Исключение USE_ERROR возбуждается при попытке выполнить операцию, не разрешенную по причинам, зависящим от характеристик внешнего файла. Например, процедурой CREATE такое исключение может быть возбуждено при задании параметром MODE вида OUT_FILE, а параметром FORM устройства, допускающего только ввод, либо при задании параметром FORM неверных прав доступа, либо если внешний файл с данным именем уже существует и перезапись недопустима.

Исключение DEVICE_ERROR возбуждается при невозможности завершения операции ввода-вывода из-за неисправностей в используемой системе.

Исключение END_ERROR возбуждается при попытке пропустить признак конца файла (чтение за концом файла).

Исключение DATA_ERROR может быть возбуждено процедурой READ, если читаемый элемент нельзя интерпретировать как значение требуемого типа. Это же исключение возбуждается процедурой GET (определенной в пакете TEXT_IO), если введенная последовательность символов не соответствует требуемому синтаксису или если введенное значение не принадлежит диапазону требуемого типа или подтипа.

Исключение LAYOUT_ERROR возбуждается (в текстовом вводе-выводе) при вызове функции COL, LINE или PAGE, если возвращаемое значение превышает COUNT'LAST. Это же исключение возбуждается при выводе: при попытке установить номер столбца или строчки, превышающий заданную максимальную длину строчки или страницы (кроме случая неограниченной длины строчки или страницы). Оно также возбуждается процедурой PUT при попытке вывести в строку слишком большое количество символов.

Ссыпки: вид IN_FILE 14.1, вид OUT_FILE 14.1, внешний файл 14.1, пакет IO_EXCEPTIONS 14.5. пакет TEXT_IO 14.3, процедура GET 14.3.5, процедура CREATE 14.2.1, процедура NEW_LINE 14.3.4, процедура NEW-PAGE 14.3.4, процедура OPEN 14.2.1, процедура PUT 14.3.5, процедура READ 14.2.2, 14.2.3, процедура SET-INPUT 14.3.2, процедура SET_LINE-LENGTH 14.3.3, процедура SET-PAGE-LENGTH 14.3.3, процедура SET-OUTPUT 14.3.2, процедура SKIP_LINE 14.3.4, процедура SKIP-PAGE 14.3,4, строка FORM 14.1, строка NAME 14.1, файл 14.1, функция COL 14.3.4, функция END-OF_LINE 14.3.4, функция END-OF-PAGE 14.3.4, функция LINE 14.3.4, функция LINE-LENGTH 14.3.4, функция PAGE 14.3.4, функция PAGE-LENGTH 14.3.4.

Пред. | Уровень выше | След.
14.3. ВВОД-ВЫВОД ТЕКСТОВ | Начало | 14.5. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА


14.5. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА
Пред. Глава 14. ВВОД-ВЫВОД След.

14.5. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА

В этом пакете определены исключения, необходимые для работы пакетов SEQUENTIAL_IO, DIRECT_IO и TEXT_IO.

package IO_EXCEPTIONS is
   STATUS_ERROR : exception;
   MODE_ERROR   : exception;
   NAME_ERROR   : exception;
   USE_ERROR    : exception;
   DEVICE_ERROR : exception;
   END_ERROR    : exception;
   DATA_ERROR   : exception;
   LAYOUT_ERROR : exception;
end IO_EXCEPTIONS;

Пред. | Уровень выше | След.
14.4. ИСКЛЮЧЕНИЯ ПРИ ВВОДЕ-ВЫВОДЕ | Начало | 14.6. ВВОД-ВЫВОД НИЗКОГО УРОВНЯ


14.6. ВВОД-ВЫВОД НИЗКОГО УРОВНЯ
Пред. Глава 14. ВВОД-ВЫВОД След.

14.6. ВВОД-ВЫВОД НИЗКОГО УРОВНЯ

Операция ввода-вывода низкого уровня — это операция, выполняющаяся на физическом устройстве. Для выполнения таких операций используется одна из (совмещенных) предопределенных процедур SEND_CONTROL и RECEIVE_CONTROL

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

Эти процедуры описаны в стандартном пакете LOW_LEVEL_IO. Каждая из них имеет два параметра, задающие устройство и данные. Однако сорт и формат управляющей информации зависят от физических характеристик машины и устройств; поэтому типы параметров зависят от реализации. Возможно определение совмещенных подпрограмм, управляющих различными устройствами.

Видимый раздел пакета, определяющего такие процедуры, имеет следующую структуру:

package LOW_LEVEL_IO is
   -- описания возможных типов параметров DEVICE и DATA
   -- описания совмещенных процедур над такими типами;
   procedure SEND_CONTROL   (DEVICE : тип-устройства; DATA : in out тип-данных);
   procedure RECEIVE_CONTROL (DEVICE : тип-устройства; DATA : in out тип-данных};
end;

Тела процедур SEND_CONTROL и RECEIVE_CONTROL для различных устройств могут быть размещены в теле пакета LOW_LEVEL_IO. Эти тела процедур могут быть записаны операторами кода.

Пред. | Уровень выше | След.
14.5. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА | Начало | 14.7. ПРИМЕР ВВОДА-ВЫВОДА


14.7. ПРИМЕР ВВОДА-ВЫВОДА
Пред. Глава 14. ВВОД-ВЫВОД След.

14.7. ПРИМЕР ВВОДА-ВЫВОДА

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

with TEXT_IO; use TEXT_IO;
procedure DIALOGUE is
   type COLOR is (WHITE, RED, ORANGE, YELLOW, GREEN, BLUE, BROWN);
   package COLOR_IO is new ENUMERATION_10(ENUM => COLOR);
   package NUMBER_IO is new INTEGER_IO(INTEGER);

   use COLOR_IO, NUMBER_IO;

   INVENTORY : array (COLOR) of INTEGER := (20, 17, 43, 10, 28, 173, 87);
   CHOICE : COLOR;

   procedure ENTER_COLOR (SELECTION : out COLOR) is
   begin
      loop
         begin
            PUT ("Color selected: "); -— обращение к пользователю
            GET (SELECTION);          -— вводит набранный цвет или возбуждает исключение
            return;
         exception
            when DATA_ERROR =>
               PUT("lnvalid color, try again. ");-- пользователь должен набрать новую строчку
               NEW_LINE(2);
               -- завершение выполнения оператора блока
         end;
      end loop;
      -— повторение оператора блока, пока не будет получен правильнй цвет
   end;

begin -- операторы процедуры DIALOGUE;

   NUMBERJO.DEFAULT_WIDTH := 5;
   loop

      ENTER_COLOR(CHOICE); -- пользователь набирает цвет и
                           -— начинает новую строчку
      SET_COL(5);   PUT(CHOICE);   PUT(" items available:");
      SET_COL(40);  PUT(INVENTORY(CHOICE));   -— ширина по умолчанию равна 5
      NEW_LINE;
   end loop;
end DIALOGUE;

Пример диалога (набранное пользователем выделено курсивом):

ВЫБРАННЫЙ ЦВЕТ: Black
ОШИБОЧНЫЙ ЦВЕТ, ПОВТОРИТЕ НАБОР

ВЫБРАННЫЙ ЦВЕТ: Blue
    BLUE ВСЕГО ПРЕДМЕТОВ: 173
ВЫБРАННЫЙ ЦВЕТ: Yellow
    YELLOW ВСЕГО ПРЕДМЕТОВ: 10

Пред. | Уровень выше | След.
14.6. ВВОД-ВЫВОД НИЗКОГО УРОВНЯ | Начало | Приложение A. АТРИБУТЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ


СПРАВОЧНОЕ РУКОВОДСТВО ПО ЯЗЫКУ АДА 83
След.

СПРАВОЧНОЕ РУКОВОДСТВО ПО ЯЗЫКУ АДА 83

Содержание

ПРЕДИСЛОВИЕ РЕДАКТОРА ПЕРЕВОДА
ПРЕДИСЛОВИЕ
1. ВВЕДЕНИЕ
1.1. ОБЛАСТЬ ДЕЙСТВИЯ СТАНДАРТА
1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА
1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ
1.4. ОБЗОР СВОЙСТВ ЯЗЫКА
1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ
1.6. КЛАССИФИКАЦИЯ ОШИБОК
2. ЛЕКСИКА
2.1. НАБОР СИМВОЛОВ
2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ
2.3. ИДЕНТИФИКАТОРЫ
2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ
2.5. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ
2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ
2.7. КОММЕНТАРИИ
2.8. ПРАГМЫ
2.9. ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА
2.10. ДОПУСТИМЫЕ ЗАМЕНЫ СИМВОЛОВ
3. ОПИСАНИЯ И ТИПЫ
3.1. ОПИСАНИЯ
3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА
3.3. ТИПЫ И ПОДТИПЫ
3.4. ПРОИЗВОДНЫЕ ТИПЫ
3.5. СКАЛЯРНЫЕ ТИПЫ
3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ
3.7. ИМЕНУЕМЫЕ ТИПЫ
3.8. ССЫЛОЧНЫЕ ТИПЫ
3.9. РАЗДЕЛЫ ОПИСАНИЙ
4. ИМЕНА И ВЫРАЖЕНИЯ
4.1. ИМЕНА
4.2. ЛИТЕРАЛЫ
4.3. АГРЕГАТЫ
4.4. ВЫРАЖЕНИЯ
4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ
4.6. ПРЕОБРАЗОВАНИЕ ТИПА
4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ
4.8. ГЕНЕРАТОРЫ
4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ
4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ
5. ОПЕРАТОРЫ
5.1. ПРОСТЫЕ И СОСТАВНЫЕ ОПЕРАТОРЫ. ПОСЛЕДОВАТЕЛЬНОСТИ ОПЕРАТОРОВ
5.2. ОПЕРАТОРЫ ПРИСВАИВАНИЯ
5.3. УСЛОВНЫЕ ОПЕРАТОРЫ
5.4. ОПЕРАТОРЫ ВЫБОРА
5.5. ОПЕРАТОРЫ ЦИКЛА
5.6. ОПЕРАТОРЫ БЛОКА
5.7. ОПЕРАТОРЫ ВЫХОДА
5.8. ОПЕРАТОРЫ ВОЗВРАТА
5.9. ОПЕРАТОРЫ ПЕРЕХОДА
6. ПОДПРОГРАММЫ
6.1. ОПИСАНИЕ ПОДПРОГРАММЫ
6.2. ВИДЫ ФОРМАЛЬНЫХ ПАРАМЕТРОВ
6.3. ТЕЛА ПОДПРОГРАММ
6.4. ВЫЗОВЫ ПОДПРОГРАММ
6.5. ФУНКЦИИ
6.6. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ
6.7. СОВМЕЩЕНИЕ ОПЕРАЦИЙ
7. ПАКЕТЫ
7.1. СТРУКТУРА ПАКЕТА
7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ
7.3. ТЕЛА ПАКЕТОВ
7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ
7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ
7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ
8. ПРАВИЛА ВИДИМОСТИ
8.1. ЗОНА ОПИСАНИЯ
8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ
8.3. ВИДИМОСТЬ
8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ
8.6. СТАНДАРТНЫЙ ПАКЕТ
8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ
9. ЗАДАЧИ
9.1. СПЕЦИФИКАЦИИ ЗАДАЧ И ТЕЛА ЗАДАЧ
9.2. ЗАДАННЫЕ ТИПЫ И ЗАДАЧНЫЕ ОБЪЕКТЫ
9.3. ВЫПОЛНЕНИЕ И АКТИВИЗАЦИЯ ЗАДАЧИ
9.4. ЗАВИСИМОСТЬ ЗАДАЧ. ЗАВЕРШЕНИЕ ЗАДАЧ
9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ
9.6. ОПЕРАТОРЫ ЗАДЕРЖКИ, ДЛИТЕЛЬНОСТЬ И ВРЕМЯ
9.7. ОПЕРАТОРЫ ОТБОРА
9.7.2. УСЛОВНЫЕ ВЫЗОВЫ ВХОДОВ
9.8. ПРИОРИТЕТЫ
9.9. АТРИБУТЫ ЗАДАЧ И ВХОДОВ
9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ
9.11. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ
9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ
10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ
10.1. КОМПИЛИРУЕМЫЕ МОДУЛИ. БИБЛИОТЕЧНЫЕ МОДУЛИ
10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ
10.3. ПОРЯДОК КОМПИЛЯЦИИ
10.4. ПРОГРАММНАЯ БИБЛИОТЕКА
10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ
10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ
11. ИСКЛЮЧЕНИЯ
11.1. ОПИСАНИЯ ИСКЛЮЧЕНИЙ
11.2. ОБРАБОТЧИКИ ИСКЛЮЧЕНИЙ
11.3. ОПЕРАТОРЫ ВОЗБУЖДЕНИЯ
11.4. ОБРАБОТКА ИСКЛЮЧЕНИЙ
11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ
11.6. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ
11.7. ПОДАВЛЕНИЕ ПРОВЕРОК
12. НАСТРАИВАЕМЫЕ МОДУЛИ
12.1. ОПИСАНИЕ НАСТРОЙКИ
12.2. НАСТРАИВАЕМЫЕ ТЕЛА
12.3. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ
12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА
13. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ И ОСОБЕННОСТИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ
13.1. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ
13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ
13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ
13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ
13.5. СПЕЦИФИКАТОРЫ АДРЕСА
13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ
13.7. СИСТЕМНЫЙ ПАКЕТ
13.8. ВСТАВКИ МАШИННЫХ КОДОВ
13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ
13.10. НЕКОНТРОЛИРУЕМОЕ ПРОГРАММИРОВАНИЕ
14. ВВОД-ВЫВОД
14.1. ВНЕШНИЕ ФАЙЛЫ И ФАЙЛОВЫЕ ОБЪЕКТЫ
14.2. ФАЙЛЫ ПОСЛЕДОВАТЕЛЬНОГО И ПРЯМОГО ДОСТУПА
14.3. ВВОД-ВЫВОД ТЕКСТОВ
14.4. ИСКЛЮЧЕНИЯ ПРИ ВВОДЕ-ВЫВОДЕ
14.5. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА
14.6. ВВОД-ВЫВОД НИЗКОГО УРОВНЯ
14.7. ПРИМЕР ВВОДА-ВЫВОДА
A. АТРИБУТЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ
B. ПРАГМЫ, ПРЕДОПРЕДЕЛЕННЫЕ В ЯЗЫКЕ
C. ПРЕДОПРЕДЕЛЕННОЕ ОКРУЖЕНИЕ ЯЗЫКА
D. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ
E. СВОДКА СИНТАКСИСА
F. ХАРАКТЕРИСТИКИ, ЗАВИСЯЩИЕ ОТ РЕАЛИЗАЦИИ
След.


Содержание

ПРЕДИСЛОВИЕ РЕДАКТОРА ПЕРЕВОДА
ПРЕДИСЛОВИЕ

ПРЕДИСЛОВИЕ РЕДАКТОРА ПЕРЕВОДА

Огромное внимание к языку Ада объясняется тем обстоятельством, что в нем формализовано около 40 современных методов программирования доступными техническими и лексическими средствами. Это, с одной стороны, усложняет реализацию языка, а с другой стороны, упрощает его использование во многих областях применения ЭВМ.

Стандарт описания языка Ада обеспечивает совместимость систем программирования на уровне исходных текстов программ. Внедрение единого языка программирования должно привести к существенному сокращению количества дублирующих работ и учебных курсов по применению ЭВМ, а также будет способствовать взаимопониманию различных участников создания программ (заказчиков, программистов и пользователей). Так, например, в США стандарт описания языка Ада за последние три года обеспечил разработку 160 совместимых по языку компиляторов, из которых 70 прошли аттестацию как компиляторы, соответствующие полному описанию языка. В СССР существует более 20 групп, реализующих системы программирования на основе языка Ада. Назрела необходимость в стандартизации описания языка в СССР и в странах - членах СЭВ. Публикация перевода этой книги будет способствовать достижению совместимости по исходным текстам программ всех систем программирования на различных типах ЭВМ.

Перевод книги существенно осложнялся большим объемом описания языка (63 зарезервированных слова, 180 синтаксических понятий, 1000 семантических понятий, 5000 общеупотребительных повествовательных слов) и ряд противоречивых требований к терминологии: учет контекста, независимость, уникальность, краткость, отсутствие синонимии. Переводчики стремились придерживаться терминологических традиций отечественной литературы по программированию, чему способствовала пятилетняя дискуссия по терминологии в Рабочей группе по языку программирования Ада Комиссии по языкам и системам программирования при ГКНТ СССР.

Книга может быть использована как пособие по проектированию, разработке, отладке и сопровождению больших и сверхбольших программ. Ее изучение позволит программистам уточнить свои знания языка Ада и более эффективно осуществлять поиск ошибок в текстах программ.

Большую помощь в работе над переводом стандарта ANSI описания языка Ада оказали Н. Е. Богородская, Н. Л. Жданова, В. Г. Коневских, В. М. Курочкин, В. В. Лукашев, А. П. Попов, Е. П.Фадеева.

Над переводом второй части книги работали В. А. Хитров, В. П. Чепкасов, А. В. Черепанов.

А. А. Красилов

Последняя версия

Электронная версия перевода доступна по адресу http://ada-rm.euro.ru/

Пред. | Уровень выше | След.
СПРАВОЧНОЕ РУКОВОДСТВО ПО ЯЗЫКУ АДА 83 | Начало | ПРЕДИСЛОВИЕ


ПРЕДИСЛОВИЕ
Пред. След.

ПРЕДИСЛОВИЕ

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

Разработка проекта единого языка программирования высокого уровня была начата в 1974 г. Требования министерства обороны США были формализованы в серии документов, которые тщательно изучались службами министерства, промышленными организациями, университетами, а также министерствами обороны зарубежных стран. Язык Ада был разработан в соответствии с окончательным видом этих требований (1978 г.), изложенных в их спецификации под названием "Steelman" [1] .

В группу разработчиков языка Ада, возглавляемую Жаном Д. Ишбиа, входили: Берндт Криг-Брукнер, Бриан А. Уичман, Анри Ф. Ледгар, Жан-Клод Элиар, Жан-Лоу Гэлли, Жан-Раймонд Абриал, Джон Г. П. Бэрнс, Майкл Вуджер, Оливер Рубин, Пол Н. Хилфингер и Роберт Фирс.

С группой разработчиков были тесно связаны несколько человек, которые на разных фазах проекта внесли большой вклад в работу. Это: Дж. Б. Гудинаф, Р. Ф. Брендер, М. В. Дэвис, Г. Ферран, К. Лестер, А. МакЛарен, Е. Морель, И. Р. Нэсси, Я. К. Пайл, С. А. Шуман и С. К. Вестал.

На втором этапе этой разработки были одновременно начаты работы в двух направлениях, которые оказали глубокое влияние на язык. Одно из них - разработка формального определения языка с использованием денотационной семантики. В этой работе принимали участие: В. Донзо-Гуж, Г. Кан и Б. Ланг. Другое - разработка пробного транслятора. В этой работе принимали участие: К. Рипкен, Р. Болье, П. Кадо, Дж. Холден, Дж. Ф. Хуэрас, Р. Г. Лан-ге, Д. Т. Корнхил. Успеху работы способствовала постоянная помощь со стороны Лин Черчилль и Марион Майерс и эффективная техническая поддержка со стороны Б. Гравем, В. Л. Хаймердингера и П. Клива. Руководил проектом X. Г. Шмитц.

В течение пяти лет работы над этим проектом было проведено несколько рабочих совещаний продолжительностью в одну неделю, в которых приняли участие: П. Белмонт, Б. Броз-гол, П. Коэн, Р. Дево, А. Эванс, Г. Фишер, X. Харт, А. Л. Хиссен, П. Кнуэвеп, М. Крунентал, Н. Ломато, Э. Плодередер, Г. Зигмюллер, В. Стеннинг, Д. Таффс, а также Ф. Белц, Р. Конверс, К. Коррел, А. Н. Хаберманн, Дж. Саммет, С. Сквайерс, Дж. Теллер, Р. Вегнер и П. Р. Везерол.

Своими замечаниями, критикой и предложениями влияние на проект оказали несколько человек. Это были: П. Бринч Хансен, Г. Гооз, К. А. Р. Хоар, Марк Рэйн, В. А. Вулф, а также Е. Боебер, П. Боннар, X. Клаузен, М. Кокс, Г. Дисмукс, Р. Ичус, Т. Фрогат, X. Ганцингер, К. Хью-итт, С. Камин, Р. Котлер, О. Лекарм, Дж. А. Н. Ли, Дж. Л. Мансион, Ф. Минел, Т. Финни, Дж. Рой-рих, В. Шнайдер, А. Сингер, Д. Шлосберг, И. К. Ванд, рецензенты из групп Ада-Европа, AdaTEC, Afeet, LMSC и рецензенты из токийской группы.

Рецензии и замечания, многочисленные отчеты об исследованиях, полученные по окончании обоих этапов, девятьсот отчетов по вопросам, связанным с языком, и отчетов об исследованиях и проверке, полученных из пятидесяти различных стран на третьем этапе проекта, тысячи замечаний, полученных в результате работ по стандартизации ANSI, а также текущая работа рабочей группы LTPL-E Комитета Падуя - Европа - все это оказало существенное влияние на окончательное определение языка Ада.

Широкая поддержка была оказана со стороны военных ведомств и агентств. Сюда входят финансирование, обширные рецензии и огромный личный вклад членов рабочей группы по языкам высокого уровня и других заинтересованных лиц. В частности, Уильям А. Уиттекер возглавлял данную программу на ее организационных этапах, а Дэвид А. Фишер обеспечил успешную разработку документов, содержащих требования к языку, которые привели к появлению спецификации требований "Steelman".

Данное определение языка было разработано силами исследовательских центров фирм Ханиуэлл и Ханиуэлл-Буль, а позднее Alsys по контракту с министерством обороны США. В роли технического представителя правительства США выступал В. Е. Карлсон, а позднее Лар-ри Э. Драффел и Роберт Е. Масис, успешно координировавшие труд всех участников проекта по языку Ада.

[1] Далее стилмановские требования. - Прим. ред.

Пред. | Уровень выше | След.
 | Начало | Глава 1. ВВЕДЕНИЕ