Spec-Zone.ru › Ada 2022
Руководство по Ada (Ada 2022)

4.3.4 Агрегаты Delta

Вычисление агрегата delta (для записей или массивов) даёт составное значение, которое начинается с копии другого значения того же типа, а затем присваивает некоторые (но обычно не все) компоненты копии.

Синтаксис

delta_aggregate ::= record_delta_aggregate | array_delta_aggregate
record_delta_aggregate ::=
(base_expression с delta record_component_association_list)
array_delta_aggregate ::=
(base_expression с delta array_component_association_list)
| '[' base_expression с delta array_component_association_list ']'

Правила разрешения имён

Ожидаемый тип для record_delta_aggregate должен быть одиночным потомком типа записи или расширения записи.
Ожидаемый тип для array_delta_aggregate должен быть типом массива.
Ожидаемый тип для base_expression любого delta_aggregate — это тип окружающего delta_aggregate.
Правила разрешения имён и правила допустимости для каждого record_component_association агрегата record_delta_aggregate определены в 4.3.1.
Для array_delta_aggregate ожидаемый тип для каждого discrete_choice в array_component_association — это тип индекса типа delta_aggregate.
Ожидаемый тип expression в array_component_association определяется аналогично array_component_association в array_aggregate типа delta_aggregate.

Правила допустимости

Для array_delta_aggregate, array_component_association не должны использовать символ "квадратных скобок" <>, а discrete_choice не должны быть others.
Для array_delta_aggregate размерность типа delta_aggregate должна быть 1.
Для array_delta_aggregate, base_expression и каждое expression в каждой array_component_association должны быть типов без ограничений.

Динамическая семантика

Вычисление delta_aggregate начинается с вычисления base_expression delta_aggregate; затем это значение используется для создания и инициализации анонимного объекта aggregate. Границы анонимного объекта array_delta_aggregate и дискриминанты (если есть) анонимного объекта record_delta_aggregate — те же, что и у base_expression. Если record_delta_aggregate — это тип с меткой, его метка — метка конкретного типа; если это тип класса, его метка — метка base_expression.
Для record_delta_aggregate, для каждого компонента, связанного с каждой record_component_association (в произвольном порядке):
  • если ассоциированный компонент принадлежит к variant, проверяется, что значения дискриминантов таковы, что анонимный объект имеет этот компонент. Исключение Constraint_Error возникает, если эта проверка не пройдёт.
  • вычисляется expression record_component_association, преобразуется в номинальный подтип соответствующего компонента и присваивается компоненту анонимного объекта.
Для array_delta_aggregate, для каждого discrete_choice каждой array_component_association (в порядке, заданном в окружающем discrete_choice_list и array_component_association_list соответственно), discrete_choice вычисляется; для каждого представленного значения индекса (в возрастающем порядке, если discrete_choice представляет диапазон):
  • значение индекса преобразуется в тип индекса типа массива.
  • проверяется, принадлежит ли значение индекса диапазону индексов анонимного объекта aggregate; Constraint_Error генерируется, если проверка не пройдёт.
  • вычисляется expression компонента, преобразуется в подтип компонента массива и присваивается компоненту анонимного объекта, идентифицируемого значением индекса.

Примеры

Примеры использования агрегатов delta в пост-условиях:
procedure Двенадцатое (D : in out Дата) -- см. 3.8 для типа Дата
с Post => D = (D'Old с delta День => 12);
procedure Ответ (V : in out Вектор;
A, B : in Целое) -- см. 3.6 для типа Вектор
с Post => V = (V'Old с delta A .. B => 42.0, V'Первое => 0.0);
Примеры, где выражение базы нетривиально:
Новая_Ячейка : Ячейка := (Минимальная_Ячейка (Голова) с delta Значение => 42);
-- см. 3.10.1 для Ячейка и Голова; 6.1 для Минимальная_Ячейка
A1 : Вектор := ((0 => 1.0, 1 => 2.0, 2 => 3.0)
с delta Целое(Случайное * 2.0) => 14.2);
-- см. 3.6 для объявления типа Вектор
-- см. 6.1 для объявления Случайное
Завтра := ((Вчера с delta День => 12)
с delta Месяц => Апрель); -- см. 3.8
Пример, где выражение базы — тип класса:
function Перевести (P : Точка'Класс; X, Y : Вещественный) return Точка'Класс is
(P с delta X => P.X + X,
Y => P.Y + Y); -- см. 3.9 для объявления типа Точка


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API