Агрегаты
Агрегат — это базовая операция, которая объединяет значения компонент в составное значение именуемого или индексируемого типа.
агрегат ::= (сопоставление-компонент {, сопоставление-компонент})
сопоставление-компонент ::= [выбор { | выбор} = > ] выражение
Каждое сопоставление компонент связывает выражение с компонентами. Сопоставление компонент называется
именованным,
если компоненты явно определены выборами, и
позиционным в
противном случае. При позиционном сопоставлении каждой отдельно взятой компоненте неявно соответствует некоторая позиция: именуемым компонентам — в порядке следования их описаний, индексируемым компонентам — по возрастанию индекса.
Именованные сопоставления могут стоять в произвольном порядке (исключая выбор
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. ВЫРАЖЕНИЯ |
Атрибуты задач и входов
Для задачного объекта или значения Т определены следующие атрибуты:
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. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ |
Цели и источники разработки
Язык был разработан, исходя из трех противоречивых требований:
• обеспечить надежность и сопровождение программ;
• поддерживать программирование как вид человеческой деятельности;
• обеспечить эффективность программ.
Необходимость в языках, повышающих надежность и упрощающих сопровождение, является установленным фактом. В языке Ада предпочтение было отдано удобочитаемости программы по сравнению с легкостью ее написания. Например, правила языка требуют, чтобы все переменные и их типы были явно описаны в программе. Далее, тип переменной неизменен, и компилятор может гарантировать совместимость операций над переменными со свойствами, присущими объектам этого типа. Более того, чтобы избежать обозначений, которые могут привести к ошибкам, в синтаксисе языка было отдано предпочтение конструкциям, которые ближе к естественному языку, чем к каким-то кодированным формам. Наконец, язык поддерживает раздельную компиляцию программных модулей способом, облегчающим разработку и сопровождение программ и обеспечивающим один и тот же уровень контроля для межмодульных и внутримодульных связей.
При разработке языка также учитывался человеческий фактор в программировании. Прежде всего была сделана попытка ограничить язык настолько, насколько это позволяла широкая область его применения. Авторы попытались путем систематизации и выявления однородности охватить всю область применения небольшим числом основных понятий, а также постарались вложить в языковые конструкции такую семантику, которая совпадает с интуитивным представлением о них у пользователя.
Как и многие другие виды человеческой деятельности, разработка программ становится все более децентрализованной и разобщенной. Следовательно, одной из центральных идей при разработке языка было обеспечение возможности составлять программу из независимо разработанных компонент. Концепции пакетов, личных типов и настраиваемых модулей прямо служат этой идее, которая повлияла на многие другие аспекты языка.
При создании любого языка нельзя избежать проблемы эффективности. Языки, которые требуют сверхсложных компиляторов или приводят к неэффективному использованию памяти и времени выполнения программы, дают неэффективные результаты на всех машинах и для всех программ. При создании языка Ада каждая его конструкция оценивалась с точки зрения современных методов реализации. Отвергались все те конструкции, которые были недостаточно ясными или требовали чрезмерных машинных ресурсов.
Ни одна из указанных выше целей разработки языка не откладывалась на будущее. Все они учитывались одновременно и с самого начала разработки.
При разработке любого языка трудность заключается в том, что необходимо определить не только возможности, которыми должен обладать язык и которые диктует предполагаемая область применения, но и собственно разработать средства языка, обеспечивающие эти возможности. Подобная трудность существовала и при разработке языка Ада, хотя благодаря стилмановским требованиям она была меньше, чем обычно. Стилмановские требования, коль скоро требования уже существуют, позволяли сконцентрировать внимание собственно на создании системы, удовлетворяющей этим требованиям, что часто упрощало процесс разработки.
Другое обстоятельство, существенно упростившее разработку, было следствием приобретенного ранее опыта реализации удачных проектов с целями, подобными указанным выше, на базе языка Паскаль. Такими языками являются языки Евклид, Лис, Меса, Модула и Сью. Многие из ключевых идей и синтаксических форм этих языков имеют аналоги в языке Ада. Некоторые существующие языки, такие как Алгол-68 и Симула, а также современные проекты языков Альфард и Клу, также повлияли на разработку языка, хотя и в меньшей степени, чем языки семейства Паскаль.
Наконец, большое значение для определения стандарта языка имели его начальная разработка (язык «Зеленый»), проекты языков «Красный», «Голубой» и «Желтый», рассмотрение различных стадий проекта и тысячи замечаний, полученных из 15 стран на предварительных этапах разработки и в процессе голосования при стандартизации, — все это оказало значительное влияние на определение стандарта языка.
Пред. | Уровень выше | След. |
1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА | Содержание | 1.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. СИМВОЛЬНЫЕ ЛИТЕРАЛЫ |
Допустимые замены символов
Для основных символов — вертикальной черты, номера и кавычки — допустимы следующие замены:
• Символ вертикальной черты ( ) можно заменить восклицательным знаком (!) там, где он используется как ограничитель.
• Символ номера (#) в литерале с основанием можно заменить двоеточием (:) при условии, что в этом литерале заменяются оба символа номера.
• Символ кавычки ("), использованный как строковая скобка на обоих концах строкового литерала, можно заменить символом процента (%), если последовательность символов строкового литерала не содержит символа кавычки и если в этом литерале заменяются обе строковые скобки. Для представления символа процента внутри последовательности символов строкового литерала должна использоваться пара соседних символов процента, которая рассматривается как один символ процента.
Эти замены не изменяют смысла программы.
Примечание.
Рекомендуется, чтобы замена символов вертикальной черты, номера и кавычки была ограничена случаями, когда соответствующих графических символов нет на терминалах. Заметим, что вертикальная черта изображается на некоторых устройствах прерывистой линией, замена в этом случае не рекомендуется.
Правила для идентификаторов и числовых литералов таковы, что строчные и прописные буквы эквивалентны; эти лексемы могут быть записаны только символами основного набора. Если строковый литерал предопределенного типа 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.
ОПИСАНИЯ И ТИПЫ |
Файлы последовательного и прямого доступа
Для внешних файлов определены два сорта доступа:
последовательный доступ
и
прямой доступ.
В настраиваемых пакетах 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. ВВОД-ВЫВОД ТЕКСТОВ |
Функции
Функция — это подпрограмма, которая возвращает значение (результат вызова функции). Спецификация функции начинается с зарезервированного слова
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. ПРОФИЛЬ ТИПА ПАРАМЕТРОВ И РЕЗУЛЬТАТА. СОВМЕЩЕНИЕ ПОДПРОГРАММ |
Генераторы
Вычисление генератора создает объект и вырабатывает ссылочное значение, которое указывает на этот объект.
генератор ::= 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.1. ИМЕНА
4.2. ЛИТЕРАЛЫ
4.3. АГРЕГАТЫ
4.4. ВЫРАЖЕНИЯ
4.5. ОПЕРАЦИИ И ВЫЧИСЛЕНИЕ ВЫРАЖЕНИЯ
4.6. ПРЕОБРАЗОВАНИЕ ТИПА
4.7. КВАЛИФИЦИРОВАННЫЕ ВЫРАЖЕНИЯ
4.8. ГЕНЕРАТОРЫ
4.9. СТАТИЧЕСКИЕ ВЫРАЖЕНИЯ И СТАТИЧЕСКИЕ ПОДТИПЫ
4.10. УНИВЕРСАЛЬНЫЕ ВЫРАЖЕНИЯ
В этой главе приведены правила, применяемые к различным формам имен и выражений, а также к их вычислению.
исключения
Содержание
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.
лексика
Содержание
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.
настраиваемые модули
Содержание
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.
операторы
Содержание
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.
описания и типы
Содержание
3.1. ОПИСАНИЯ
3.2. ОБЪЕКТЫ И ИМЕНОВАННЫЕ ЧИСЛА
3.3. ТИПЫ И ПОДТИПЫ
3.4. ПРОИЗВОДНЫЕ ТИПЫ
3.5. СКАЛЯРНЫЕ ТИПЫ
3.6. ИНДЕКСИРУЕМЫЕ ТИПЫ
3.7. ИМЕНУЕМЫЕ ТИПЫ
3.8. ССЫЛОЧНЫЕ ТИПЫ
3.9. РАЗДЕЛЫ ОПИСАНИЙ
Эта глава описывает типы и правила описания констант, переменных и именованных чисел.
пакеты
Содержание
7.1. СТРУКТУРА ПАКЕТА
7.2. СПЕЦИФИКАЦИИ И ОПИСАНИЯ ПАКЕТОВ
7.3. ТЕЛА ПАКЕТОВ
7.4. ОПИСАНИЯ ЛИЧНЫХ ТИПОВ И СУБКОНСТАНТ
7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ
7.6. ПРИМЕР ПАКЕТА ОБРАБОТКИ ТЕКСТОВ
Пакеты — это одна из четырех форм программных модулей, из которых составляются программы. Другие формы — это подпрограммы, задачные модули и настраиваемые модули.
Пакеты допускают спецификацию групп логически связанных понятий. Простейшие формы пакета специфицируют совокупность общих объектов и описаний типов. Вообще пакеты могут использоваться для спецификации групп взаимосвязанных понятий, включающих также подпрограммы, которые могут быть вызваны извне пакета, тогда как действие внутри пакета остается скрытым и защищенным от внешних пользователей.
Ссылки:
задачный модуль 9, настраиваемый модуль 12, описание типа 3.3.1, подпрограмма 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.
правила видимости
Содержание
8.1. ЗОНА ОПИСАНИЯ
8.2. ОБЛАСТИ ДЕЙСТВИЯ ОПИСАНИЙ
8.3. ВИДИМОСТЬ
8.5. ОПИСАНИЯ ПЕРЕИМЕНОВАНИЯ
8.6. СТАНДАРТНЫЙ ПАКЕТ
8.7. КОНТЕКСТ РАЗРЕШЕНИЯ СОВМЕЩЕНИЯ
В этой главе описаны правила, определяющие область действия описания, и правила, определяющие видимость идентификаторов в различных точках текста программы. Формулировка правил видимости использует понятие зоны описания.
Ссылки:
видимость 8.3, зона описания 8.1, идентификатор 2.3, область 8.2, описание 3.1.
спецификаторы представления и особенности, зависящие от реализации
Содержание
13.1. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ
13.2. СПЕЦИФИКАТОРЫ ДЛИНЫ
13.3. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ПЕРЕЧИСЛЕНИЯ
13.4. СПЕЦИФИКАТОРЫ ПРЕДСТАВЛЕНИЯ ЗАПИСЕЙ
13.5. СПЕЦИФИКАТОРЫ АДРЕСА
13.6. ИЗМЕНЕНИЕ ПРЕДСТАВЛЕНИЯ
13.7. СИСТЕМНЫЙ ПАКЕТ
13.8. ВСТАВКИ МАШИННЫХ КОДОВ
13.9. СВЯЗЬ С ДРУГИМИ ЯЗЫКАМИ
13.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.
с так называемыми стилмановскими требованиями,
Содержание
1.1. ОБЛАСТЬ ДЕЙСТВИЯ СТАНДАРТА
1.2. СТРУКТУРА СПРАВОЧНОГО РУКОВОДСТВА
1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ
1.4. ОБЗОР СВОЙСТВ ЯЗЫКА
1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ
1.6. КЛАССИФИКАЦИЯ ОШИБОК
Ада — это язык программирования, разработанный в соответствии с так называемыми стилмановскими требованиями, определенными МО США. Более того, эти требования определили язык с мощными выразительными возможностями, пригодный для широкого класса задач. Вследствие этого языку Ада присущи как свойства классических языков, подобных языку Паскаль, так и свойства, характерные для специализированных языков. Таким образом, этот язык является современным алгоритмическим языком с традиционными управляющими структурами и средствами определения типов и подпрограмм. Он также удовлетворяет требованию модульности; данные, типы и подпрограммы могут образовывать пакеты. Модульность понимается и в физическом смысле, что обеспечивается раздельной компиляцией модулей.
В дополнение к указанному язык обеспечивает программирование задач реального времени с возможностями моделирования параллельных задач и обработки исключений. Он пригоден также для системного программирования; это требует прецизионного управления представлением данных и доступа к зависимым от системы параметрам. Наконец, в языке определены пользовательский и машинный уровни ввода-вывода.
ввод-вывод
Содержание
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.
задачи
Содержание
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.
Идентификаторы
Идентификаторы используются в качестве имен и зарезервированных слов.
идентификатор ::= буква {[подчеркивание] буква-или-цифра}
буква-или-цифра ::= буква | цифра
буква ::= прописная буква | строчная буква
Все символы идентификатора существенны, включая символ подчеркивания между соседними буквами или цифрами. Идентификаторы, различающиеся только размерами букв, считаются совпадающими.
Примеры:
СЧЕТЧИК | Х | дай-символ | Эвелина | Марион | |||||||
СНОБОЛ-4 | Х1 | СчетчикСтраниц | ЗАПАСТИ_СЛЕДУЮЩИЙ_ЭЛЕМЕНТ |
Примечание.
Пробел внутри идентификатора недопустим, поскольку он является разделителем.
Ссылки:
зарезервированное слово 2.9, имя 4.1, прописная буква 2.1, разделитель 2.2, символ пробела 2.1, строчная буква 2.1, цифра 2.1.
Пред. | Уровень выше | След. | |
2.2. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ | Содержание | 2.4. ЧИСЛОВЫЕ ЛИТЕРАЛЫ |
Имена
Имена могут обозначать понятия, описанные явно или неявно (см. 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) |
/p>
Примечание к примеру.
Для компонент многомерных массивов (таких, как 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) |
/p>
Примечание.
Для одномерного массива А имя 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. ЛИТЕРАЛЫ |
Именуемые типы
Объект именуемого типа (запись) — это составной объект, состоящий из именованных компонент. Значение записи — составное значение, состоящее из значений своих компонент.
определение-именуемого-типа::= 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. ССЫЛОЧНЫЕ ТИПЫ |
Индексируемые типы
Индексируемый объект (массив) — это составной объект, содержащий компоненты, имеющие один и тот
же подтип. В имени компоненты массива используется одно или несколько индексных значений, принадлежащих заданным дискретным типам. Значение массива — это составное значение, состоящее из значений его компонент
опеределение-индексируемого-типа :: = определение-неограниченного-индексируемого-типа | определение-ограниченного-индексируемого-типа
определение-неограниченного-индексируемого-типа ::= 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. ИМЕНУЕМЫЕ ТИПЫ |
Исключения и оптимизация
В данном разделе описаны условия, при которых в реализации можно выполнять те или иные действия раньше или позже, чем это определено правилами языка.
В целом, если правила языка задают порядок некоторых действий
[канонический порядок},
реализация может использовать альтернативный порядок при гарантии, что такое переупорядочивание не скажется на результате выполнения программы. В частности, если при выполнении программы в каноническом порядке не возбуждается никакое исключение, то также никакие исключения не должны возбуждаться при выполнении переупорядоченной программы. С другой стороны, если порядок некоторых действий не определен языком, то реализация может использовать любой порядок. (Например, аргументы предопределенной операции могут вычисляться в любом порядке, так как правила из разд. 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. ПОДАВЛЕНИЕ ПРОВЕРОК |
Исключения при вводе-выводе
В этом разделе описаны исключения, которые могут быть возбуждены при выполнении операций ввода-вывода. Они описаны в пакете 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. СПЕЦИФИКАЦИЯ ПАКЕТА ИСКЛЮЧЕНИЙ ВВОДА-ВЫВОДА |
Исключения, возбуждаемые при взаимодействии задач
Исключение может распространяться на взаимодействие задач или на попытку начать взаимодействие одной задачи с другой. Исключение может также распространяться на вызывающую задачу, если оно было возбуждено в процессе рандеву.
Когда задача вызывает вход другой задачи, то в точке этого вызова в вызывающей задаче возбуждается исключение 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. ИСКЛЮЧЕНИЯ И ОПТИМИЗАЦИЯ |
Изменение представления
Для данного типа и данного аспекта его представления допустимо не более одного спецификатора представления. Поэтому если желательно другое представление, то необходимо описать второй тип, производный от первого, и для него специфицировать другое представление.
Пример:
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. СИСТЕМНЫЙ ПАКЕТ |
Классификация ошибок
Определение языка делит ошибки на несколько различных категорий:
а)
Ошибки, которые должны быть обнаружены во время компиляции любым компилятором с языка Ада.
Эти ошибки соответствуют любому нарушению правил, данных в этом стандарте, кроме нарушений, соответствующим пунктам б) и в). В частности, к этой категории относятся нарушения правил, в которых использованы слова должно, допустимо, правильный
или неправильный.
Любая содержащая такую ошибку Ада-программа не является правильной; с другой стороны, тот факт, что программа правильна в этом смысле, не означает, что в ней нет других ошибок.
б)
Ошибки, которые должны быть обнаружены во время выполнения Ада-программы.
Соответствующим ошибочным ситуациям сопоставлены имена предопределенных исключений. Каждый компилятор с языка Ада должен генерировать код, возбуждающий соответствующее исключение, если такая ошибочная ситуация встретится во время выполнения программы. Если исключение обязательно будет возбуждаться при выполнении данной программы, то компиляторы могут (но не обязательно) сообщить об этом во время компиляции.
в) Ошибочное выполнение.
В языке определен ряд правил, которым должна подчиняться Ада-программа, хотя от компилятора и не требуется обнаружение нарушений этих правил ни во время компиляции, ни во время выполнения программы. Слово ошибочный
квалифицирует выполнение конструкций, содержащих ошибки этой категории. Результат выполнения ошибочной конструкции непредсказуем.
г) Некорректная зависимость от порядка.
Когда в справочном руководстве указывается, что различные части данной конструкции должны быть выполнены в порядке, который не определен в языке,
это означает, что реализация допускает выполнение этих частей в любом порядке, но не параллельно. Более того, конструкция некорректна, если выполнение этих частей в различном порядке дает различный результат. Во время компиляции и во время выполнения программы (этот процесс называется выполнением) компилятор не всегда обеспечивает проверку некорректной зависимости результата от порядка.
Термин выполнение в равной мере применим к процессам, которые называют вычислением и предвыполнением.
Если компилятор способен распознать во время компиляции, что конструкция ошибочна или содержит некорректную зависимость от порядка, то допускается, чтобы компилятор генерировал код, заменяющий конструкцию кодом, возбуждающим предопределенное исключение PROGRAM-ERROR. Компилятор также может сгенерировать код, который во время выполнения проверяет ошибочность конструкции, некорректную зависимость от порядка или и то и другое. Предопределенное исключение PROGRAM-ERROR возбуждается, если проверка покажет наличие такой ошибки.
Пред. | Уровень выше | След. |
1.5. МЕТОД ОПИСАНИЯ И СИНТАКСИЧЕСКИЕ ОБОЗНАЧЕНИЯ | Содержание | Глава 2. ЛЕКСИКА |
и продолжается до конца строчки.
Комментарий начинается с двух соседних дефисов и продолжается до конца строчки. Комментарий может помещаться в любой строчке программы. Присутствие или отсутствие комментария не влияет ни на правильность, ни на неправильность программы. Более того, комментарии не влияют на смысл программы; их единственное назначение — сделать программу более понятной.
Примеры:
-- последнее предложение выражает ту же мысль, что и -- в языке Алгол-68
end; -- обработка LINE завершена
-- длинный комментарий может быть разбит на -- две или несколько последовательных строчек
------- первые два дефиса начинают комментарий
Примечание.
Горизонтальная табуляция может быть использована в комментариях после двух дефисов, это эквивалентно одному или нескольким пробелам (см. 2.2).
Ссылки:
конец строчки 2.2, неправильный 1.6, правильный 1.6, символ пробела 2.1.
Пред. | Уровень выше | След. |
2.6. СТРОКОВЫЕ ЛИТЕРАЛЫ | Содержание | 2.8. ПРАГМЫ |
Компилируемые модули библиотечные модули
Текст программы может подаваться на вход компилятора в виде одной или нескольких компиляций. Каждая компиляция представляет собой последовательность компилируемых модулей.
компиляция ::= (компилируемый-модуль)
компилируемый-модуль ::= спецификатор-контекста библиотечный-модуль | спецификатор-контекста вторичный-модуль
библиотечный-модуль ::= описание-подпрограммы | описание-пакета | описание-настройки | конкретизация-настройки | тело-подпрограммы
вторичный-модуль ::= тело-библиотечного-модуля | субмодуль
тело-библиотечного-модуля ::= тело-подпрограммы | тело-пакета
Говорят, что компилируемые модули программы принадлежат
программной библиотеке.
Компирируемый модуль определяет библиотечный модуль или вторичный модуль. Вторичный модуль — это раздельно компилируемое соответствующее тело библиотечного модуля или субмодуль другого компилируемого модуля. Обозначением раздельно компилируемой подпрограммы (библиотечного модуля или субмодуля) должен быть идентификатор. В программной библиотеке простые имена всех библиотечных модулей должны быть различными идентификаторами.
Результат компилирования библиотечного модуля состоит в том, чтобы определить (или переопределить) его как модуль программной библиотеки. По правилам видимости каждый библиотечный модуль рассматривается как описание, приведенное непосредственно внутри пакета 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. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ |
Конкретизация настройки
Экземпляр настраиваемого модуля описывается конкретизацией настройки.
конкретизация - настройки ::= 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. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА |
Контекст разрешения совмещения
Совмещение определено для программ, литералов перечисления, символов операций и одиночных входов, а также для тех операций, которые присущи обычным базовым операциям, например присваивание, проверка принадлежности, генератор, литерал
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. ЗАДАЧИ |
Квалифицированные выражения
Квалифицированное выражение используется для явного указания типа и, возможно, подтипа операнда, заданного выражением или агрегатом.
квалифицированное-выражение ::= обозначение-типа' (выражение) | обозначение-типа'агрегат
Тип операнда должен совпадать с базовым типом обозначения типа. Значение квалифицированного выражения — это значение операнда. Вычисление квалифицированного выражения выдает операнд и проверяет, принадлежит ли его значение подтипу, заданному в обозначении типа. При отрицательном результате проверки возбуждается исключение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. ГЕНЕРАТОРЫ |
Лексемы, разделители и ограничители
Текст программы состоит из текстов одной или нескольких компиляций. Текст каждой компиляции — это последовательность отдельных лексем. Лексема (лексический элемент) — это ограничитель, идентификатор (который может быть зарезервированным словом), числовой литерал, символьный литерал, строковый литерал или комментарий. Результат выполнения программы зависит только от конкретной последовательности лексем, исключая возможные комментарии.
В некоторых случаях необходим явный
разделитель
между соседними лексемами (в противном случае они могут быть восприняты как одна). Разделителем может быть символ пробела, символ управления форматом или конец строчки. Символ пробела не является разделителем в комментарии, строковом литерале или символьном литерале. Символ управления форматом (кроме символа горизонтальной табуляции, когда он употребляется в комментариях) всегда является разделителем.
Конец строчки всегда является разделителем. Язык не определяет, что является концом строчки. Если в данной реализации конец строчки обозначается одним или несколькими символами, то эти символы должны быть символами управления форматом, отличными от символа горизонтальной табуляции. Во всяком случае, последовательность из одного или нескольких символов управления форматом, отличных от символа горизонтальной табуляции, должна заменить по крайней мере один конец строчки.
Один или несколько разделителей допустимы между соседними, перед первой или после последней лексемы. По крайней мере один разделитель необходим между идентификатором или числовым литералом и соседними идентификаторами или числовыми литералами.
Ограничитель —
это один из следующих специальных символов из набора основных символов:
&'()*+,-./:;<=>!
или один из следующих
составных ограничителей,
представляющих собой пару специальныхсимволов:
=> .. ** := /= >= <= << >> <>
Каждый специальный символ является простым ограничителем, за исключением тех случаев, когда он встречается в составном ограничителе, в комментарии, в строковом, символьном или числовом литералах.
Остальные формы лексем описаны в других разделах данной главы.
Примечание.
Каждая лексема должна располагаться в одной строчке, поскольку конец строчки — разделитель. Символы кавычки, решетки, подчеркивания и два соседних дефиса не являются ограничителями, но могут входить в лексемы в качестве ее частей.
Наименования составных ограничителей даны ниже:
Ограничитель |
Наименование |
= > |
стрелка |
.. | двойная точка |
** | двойная звездочка, возведение в степень |
:= | присваивание (читается: «Становится равным») |
/= | неравенство (читается: «Не равно») |
> = | больше или равно |
< = | меньше или равно |
<< | левая скобка метки |
>> | правая скобка метки |
< > | бокс (или коробка) |
Ссылки:
зарезервированное слово 2.9, идентификатор 2.3, комментарий 2.7, компиляция 10.1, символ пробела 2.1, символ управления 2.1, символьный литерал 2.5, специальный символ 2.1, строковый литерал 2.6, числовой литерал 2.4.
Пред. | Уровень выше | След. |
Глава 2. ЛЕКСИКА | Содержание | 2.3. ИДЕНТИФИКАТОРЫ |
Литералы
Литерал — это либо числовой литерал, либо литерал перечисления, либо литерал
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. АГРЕГАТЫ |
Метод описания и синтаксические обозначения
Контекстно-свободный синтаксис программных модулей языка Ада вместе с контекстно-зависимыми требованиями выражается правилами в повествовательной форме.
Семантика программных модулей описана правилами определения результата выполнения каждой конструкции и правилами их построения. В изложении используются термины, точное определение которых дано в тексте (ссылки на содержащие определения разделы помещены в конце каждого использующего понятие раздела).
Все другие понятия имеют свое естественное значение, определенное в словаре русского языка Ушакова [2]
.
Контекстно-свободный синтаксис языка описывается с помощью простого варианта форм Бэкуса-Наура. В частности:
а) Записанные строчными буквами слова, возможно содержащие в некоторых случаях символ подчеркивания, используются для обозначения синтаксических понятий, например:
аддитивная - операция
В названиях синтаксических понятий, используемых вне контекста синтаксических правил, вместо символа подчеркивания используется пробел (например, аддитивная операция).
б) Полужирным шрифтом выделены зарезервированные слова, например:
array
в) В квадратные скобки заключены необязательные элементы. Поэтому два следующих правила эквивалентны:
оператор-возврата ::= return
[выражение];
оператор-возврата ::= return; | return
выражение;
г) Повторяющиеся элементы заключаются в фигурные скобки. Этот элемент может встретиться нуль или более раз; повторение осуществляется слева направо в соответствии с правилом левой рекурсии. Таким образом, два следующих правила эквивалентны:
слагаемое ::= множитель (операция-умножения множитель)
слагаемое ::= множитель 1 слагаемое операция-умножения множитель
д) Вертикальная черта разделяет альтернативные элементы, кроме тех случаев, когда черта встречается непосредственно за открывающейся фигурной скобкой, тогда она обозначает знак вертикальной черты:
буква-или-цифра ::= буква 1 цифра
сопоставление-компонента ::= [выбор (I выбор) =>] выражение
е) Если название какого-нибудь синтаксического понятия содержит выделенную курсивом часть, оно эквивалентно названию синтаксического понятия без выделенной курсивом части.
Выделенная курсивом часть предназначена для выражения некоторой семантической информации. Например, имя-типа и имя-задачи эквивалентны просто понятию имя.
Примечание.
Описывающие структурные конструкции синтаксические правила представлены в форме, соответствующей рекомендованному делению на абзацы. Например, условный оператор определяется так:
условный-оператор ::= if условие then
последовательность - операторов {elsif условие then
последовательность - операторов} [else
последовательность - операторов] end if;
Синтаксические правила записываются в несколько строчек, если соответствующие части конструкции рекомендуется располагать на разных строчках. Все отступы от начала строчки рекомендованы в правилах для сдвига соответствующих частей конструкции. Все отступы должны быть кратны базовому шагу отступа (число пробелов в базовом шаге не определяется). Переход на новую строчку рекомендуется после точки с запятой. С другой стороны, если вся конструкция умещается на одной строчке, то это также допустимо.
[2]
В оригинале: третий новый международный словарь английского языка Уэбстера. - Прим. перев.
стр.360
Пред. | Уровень выше | След. |
1.4. ОБЗОР СВОЙСТВ ЯЗЫКА | Содержание | 1.6. КЛАССИФИКАЦИЯ ОШИБОК |
Набор символов
Символами в тексте программы должны быть только графические символы и символы управления форматом. Каждый графический символ соответствует единственному коду из набора символов 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. ЛЕКСЕМЫ, РАЗДЕЛИТЕЛИ И ОГРАНИЧИТЕЛИ |
Настраиваемые тела
Тело настраиваемой подпрограммы или настраиваемого пакета (настраиваемое тело) является шаблоном для тел соответствующих подпрограмм или пакетов, получаемых конкретизацией настройки. Синтаксис настраиваемого тела идентичен обычному телу.
Для каждого описания настраиваемой подпрограммы должно быть соответствующее тело.
Предвыполнение настраиваемого тела не имеет другого эффекта, кроме установления того, что тело начиная с этого момента может быть использовано в качестве шаблона для получения соответствующих экземпляров.
Пример настраиваемого тела процедуры:
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. КОНКРЕТИЗАЦИЯ НАСТРОЙКИ |
Неконтролируемое программирование
Для неконтролируемого освобождения памяти и неконтролируемого преобразования типов используются предопределенные настраиваемые библиотечные подпрограммы:
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. ВВОД-ВЫВОД |
Объекты и именованные числа
Объект —
это понятие языка; объект имеет (содержит) значение данного типа. Объектом может быть:
• объект, объявленный в описании объекта или в описании одиночной задачи;
• формальный параметр подпрограммы, входа или настраиваемой подпрограммы;
• формальный объект настройки;
• параметр цикла;
• объект, указанный значением ссылочного типа;
• компонента или отрезок другого объекта.
Описание числа — это специальная форма описания объекта, которая связывает идентификатор со значением типа
универсальный-целый
или
универсальный-вещественный.
описание-объекта ::= список-идентификаторов : [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. ТИПЫ И ПОДТИПЫ |
Область действия стандарта
В данном стандарте описаны форма представления и семантика программных модулей, написанных на языке Ада. Цель стандарта — повысить переносимость Ада-программ.
1.1.1. СОДЕРЖАНИЕ СТАНДАРТА
Данный стандарт определяет:
а) форму представления программного модуля, написанного на языке Ада;
б) результаты трансляции и выполнения такого программного модуля;
в) способ получения Ада-программ из набора программных модулей;
г) предопределенные программные модули, которые должна обеспечивать согласованная со стандартом реализация (далее в тексте — согласованная реализация);
д) допустимые в рамках стандарта изменения и способы их задания;
е) те нарушения стандарта, которые обязана обнаруживать согласованная реализация, а также результат попытки транслировать или выполнить программный модуль, содержащий такие нарушения;
ж) те нарушения стандарта, которые согласованная реализация не обязана обнаруживать.
Этот стандарт не определяет:
з) средства преобразования программного модуля, написанного на языке Ада, в объектный код, выполняемый процессором;
и) средства запуска трансляции, выполнения программных модулей и управления ими;
к) размер и скорость выполнения объектного кода, а также относительную скорость выполнения различных языковых конструкций;
л) форму и содержание любых листингов, создаваемых реализациями, в частности форму и содержание сообщений об ошибках или предупреждающих сообщений;
м) результат выполнения программного модуля, содержащего любое нарушение стандарта, которое согласованная реализация не обязана обнаруживать;
н) предельный размер программы или программного модуля для конкретной согласованной реализации.
Там, где стандарт предписывает, что программный модуль, написанный на языке Ада, имеет точный результат, этот результат является функциональным значением данного программного модуля, и его должны обеспечить все согласованные реализации. Там, где стандарт допускает неоднозначность результата выполнения программного модуля, под функциональным значением программного модуля в целом понимается множество возможных результатов, и согласованная реализация может обеспечить любой из этих возможных результатов.
Примерами допустимых неоднозначностей являются:
• значения фиксированных и плавающих числовых величин, а также результаты операций над ними;
• порядок выполнения операторов в различных параллельных задачах при отсутствии явной синхронизации.
1.1.2. СОГЛАСОВАННОСТЬ РЕАЛИЗАЦИИ СО СТАНДАРТОМ
Согласованная реализация должна:
а) корректно транслировать и выполнять правильные программные модули, написанные на языке Ада, если только их объем находится в допустимых для реализации пределах;
б) отвергать все программные модули, объем которых больше допускаемого реализацией;
в) отвергать все программные модули, содержащие ошибки, обнаружение которых предусмотрено стандартом;
г) обеспечивать всеми предопределенными программными модулями, предусмотренными стандартом;
д) содержать только те изменения, которые допускает стандарт;
е) описывать допустимые изменения способом, разрешенным стандартом.
Пред. | Уровень выше | След. |
ПРЕДИСЛОВИЕ | Содержание | 1.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. ВИДИМОСТЬ |
Обработчики исключений
Ответная реакция на одно или несколько исключений определяется обработчиком исключения.
обработчик - исключения :: = 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.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. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ |
Обзор свойств языка
Ада-программа представляет собой один или несколько программных модулей, которые могут компилироваться раздельно. Программные модули — это подпрограммы (определяющие выполняемый алгоритм), пакеты (определяющие наборы понятий), модули-задачи (определяющие параллельные вычисления) или настраиваемые модули (определяющие параметризованные пакеты и подпрограммы). Каждый модуль обычно состоит из двух частей: спецификации, содержащей видимую для других модулей информацию, и тела, содержащего детали реализации, о которых другие модули не обязаны знать.
Это различие между спецификацией и телом, а также возможность компилировать модули раздельно позволяют разрабатывать, кодировать и тестировать программу как множество в достаточной степени независимых программных компонент.
Ада-программа обычно будет использовать библиотеку программных модулей общего назначения.
Язык предоставляет средства, с помощью которых отдельные организации могут создавать свои собственные библиотеки. В тексте раздельно компилируемого программного модуля должны быть указаны имена библиотечных модулей, которые ему требуются.
Программные модули .
Подпрограмма является основным модулем для представления алгоритма. Существует два вида подпрограмм: процедуры и функции. Процедура — это средство вызова последовательности действий. Например, она может считывать данные, изменять значения переменных или выводить информацию. Процедура может иметь параметры для управления механизмом передачи информации между процедурой и точкой вызова.
Функция — это средство вызова действий по вычислению значения. Она подобна процедуре, но в результате выполнения еще и возвращает значение.
Пакет — это основной модуль для определения набора логически связанных понятий. Например, пакет может быть использован для определения общей группы данных и типов, набора взаимосвязанных подпрограмм или же множества описаний типов и соответствующих операций. Части пакета могут быть скрыты от пользователя, разрешая, таким образом, доступ только к тем логическим свойствам, которые описаны в спецификации пакета.
Задачный модуль — это основной модуль для определения задачи, последовательность действий которой может выполняться параллельно с выполнением других задач. Такие задачи могут быть реализованы на многомашинной или многопроцессорной системе либо чередованием выполнения задач на одном процессоре. Задачный модуль может определить или одну выполняемую задачу, или задачный тип, позволяющий создать любое количество подобных задач.
Описания и операторы .
Тело программного модуля, как правило, содержит две части: раздел описаний, который определяет логические понятия, используемые в программном модуле, и последовательность операторов, определяющую выполнение этого программного модуля.
Раздел описаний связывает имена с описанными понятиями. Например, имя может обозначать тип, константу, переменную или исключение. Раздел описаний также может вводить имена и параметры других вложенных подпрограмм, пакеты, задачные модули и настраиваемые модули, используемые в этом программном модуле.
Последовательность операторов описывает последовательность действий, которые должны быть выполнены. Операторы выполняются последовательно (если только оператор возврата, перехода, выхода или возбуждения исключения не вызовет продолжения выполнения с другого места).
Оператор присваивания изменяет значение переменной. Вызов процедуры инициирует выполнение процедуры после сопоставления каждого фактического параметра, заданного в вызове, соответствующему формальному параметру.
Оператор выбора и условный оператор позволяют выполнить одну из входящих в них последовательностей операторов, определяемую значением выражения или значением условия.
Оператор цикла обеспечивает основной итерационный механизм в языке. Оператор цикла задает повторение выполнения некоторой последовательности операторов по заданной итерационной схеме или до выполнения оператора выхода.
Оператор блока включает в себя последовательность операторов, которым предшествуют описания локальных понятий, используемых в этих операторах.
Некоторые операторы применимы только к задачам. Оператор задержки приостанавливает выполнение задачи на указанный интервал времени. Оператор вызова входа записывается как оператор вызова процедуры; он показывает, что выполнившая этот вызов задача готова для рандеву с другой задачей, имеющей указанный вход. Вызываемая задача готова принять вызов входа, когда ее выполнение достигает соответствующего оператора принятия, который определяет выполняемые далее действия. После завершения рандеву обе задачи, как вызывающая, так и имеющая вход, продолжают свое параллельное выполнение. Одна из форм оператора отбора допускает отбор с ожиданием для одного из нескольких альтернативных рандеву. Другие формы оператора отбора допускают условные или временные вызовы входа.
Выполнение программного модуля может привести к ошибочным ситуациям, вследствие чего продолжение нормального выполнения программы невозможно: например, когда результат арифметического вычисления превышает максимально допустимое числовое значение или когда, делается попытка доступа к компоненте массива с неправильным значением индекса. Для работы с такими ошибочными ситуациями текстуально за операторами программного модуля могут следовать обработчики исключений, определяющие предпринимаемые при возникновении ошибочных ситуаций действия. Исключения могут быть возбуждены и явно оператором возбуждения.
Типы данных .
Каждый объект языка имеет тип, характеризующий множество значений и множество применимых к ним операций. Основные классы типов — это скалярные типы (включающие перечислимые и числовые типы), составные, ссылочные и личные типы.
Перечислимый тип определяет упорядоченное множество различных литералов перечисления, например список состояний или перечень символов. Перечислимые типы BOOLEAN и CHARACTER предопределены.
Числовые типы обеспечивают средства выполнения точных или приближенных числовых вычислений. Для точных вычислений используются целые типы, которые обозначают множе ства последовательных целых чисел.
В приближенных вычислениях используются либо фиксированные типы (типы чисел с фиксированной точкой), представимые с абсолютной погрешностью, либо плавающие типы (типы чисел с плавающей точкой), представимые с относительной погрешностью. Числовые типы INTEGER, FLOAT и DURATION предопределены.
Составные типы допускают определения структурных объектов из сгруппированных компонент. Составные типы в языке представлены массивами и записями. Массив — это объект с индексируемыми компонентами одного и того же типа. Запись — это объект с именованными компонентами, возможно, различных типов. Индексируемый тип STRING предопределен.
Запись может иметь специальные компоненты, называемые дискриминантами. В записях можно определить альтернативные структуры, зависящие от значений дискриминантов.
Ссылочные типы позволяют вычислением генератора создавать связанные ссылками структуры данных. Они позволяют нескольким переменным ссылочного типа указывать на один и тот же объект, а компонентам одного объекта указывать на тот же самый или другие объекты. Элементы такой связанной ссылками структуры данных и их связи с другими элементами могут быть изменены во время выполнения программы.
Личные типы могут быть определены в пакете, скрывающем внутреннюю структуру, несущественную вне пакета. Пользователю таких типов видны логически существенные их свойства (включая дискриминанты).
Концепция типа уточняется концепцией подтипа, благодаря чему пользователь может ограничить множество допустимых значений данного типа. Подтипы могут быть использованы для определения поддиапазонов скалярных типов, массивов с ограниченным множеством значений индексов, а также именованных и личных типов с конкретными значениями дискриминантов.
Другие свойства языка .
Для определения отображения типов на архитектуру объектной машины можно использовать спецификаторы представления. Например, пользователь может задать число битов для представления объектов данного типа или размещение в памяти машины компонент записи.
Другие свойства языка допускают управляемое использование особенностей, связанных с низким уровнем, непереносимостью или зависимостью от реализиции, включая прямое использование машинного кода.
Ввод-вывод в языке определен средствами предопределенных библиотечных пакетов. Предоставляются средства для ввода-вывода значений типов, определенных пользователем, а также значений предопределенных типов; обеспечивается представление изображений значений в стандартной форме.
Наконец, язык предоставляет мощные средства параметризации программных модулей, называемых настраиваемыми программными модулями. Параметрами настройки могут быть типы и подпрограммы (а также объекты), и, таким образом, допустимы общие алгоритмы, применимые для всех типов данного класса.
Пред. | Уровень выше | След. |
1.3. ЦЕЛИ И ИСТОЧНИКИ РАЗРАБОТКИ | Содержание | 1.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 |
Конъюнкция |
Любой логический тип Массив логических компонент |
Тот же логический тип Тот же индексируемый тип |
ог |
Дизъюнкция |
Любой логический тип Массив логических компонент |
Тот же логический тип Тот же индексируемый тип |
хог |
Исключающая дизъюнкция |
Любой логический ТИП Массив логических компонент |
Тот же логический Тот же индексируемый тип |
/p>
Операции над массивами выполняются покомпонентно, если компоненты имеются (как для равенства, см. 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 |
/p>
Ссылки:
базовый тип 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. ПРЕОБРАЗОВАНИЕ ТИПА |
Операторы блока
Оператор блока содержит последовательность операторов, которой может предшествовать раздел описаний и за которой могут следовать обработчики исключений.
оператор-блока ::= [простое - имя - блока:] [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. ОПЕРАТОРЫ ВЫХОДА |
Операторы цикла
Оператор цикла содержит последовательность операторов, выполнение которой повторяется несколько раз или ни одного раза.
\
оператор-цикла ::= [простое-имя-цикла:] [схема-итерации] 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. ОПЕРАТОРЫ БЛОКА |