Ada Conformity Assessment Authority |
Home |
Conformity Assessment | Test Suite |
ARG | Ada Standard |

{*AI05-0147-1*}
{*AI05-0188-1*}
{*AI05-0262-1*}
A conditional_expression
selects for evaluation at most one of the enclosed *dependent_*expressions,
depending on a decision among the alternatives. One kind of conditional_expression
is the if_expression,
which selects for evaluation a *dependent_*expression
depending on the value of one or more corresponding conditions. The other
kind of conditional_expression
is the case_expression,
which selects for evaluation one of a number of alternative *dependent_*expressions;
the chosen alternative is determined by the value of a *selecting_*expression.

{*AI05-0188-1*}
As previously noted, there are two kinds of conditional_expression,
if_expressions
and case_expressions.
Whenever possible, we have written the rules in terms of conditional_expressions
to avoid duplication.

{*AI05-0147-1*}
The rules for conditional_expressions
have been designed as much as possible to work similarly to a parenthesized
expression. The intent is that as much as possible, wherever a parenthesized
expression would be allowed, a conditional_expression
would be allowed, and it should work the same way.

{*AI05-0147-1*}
{*AI05-0188-1*}
if_expression ::=

**if** condition **then** *dependent_*expression

{**elsif** condition **then** *dependent_*expression}

[**else** *dependent_*expression]

{

[

{*AI05-0188-1*}
case_expression ::=

**case** *selecting_*expression **is**

case_expression_alternative {,

case_expression_alternative}

case_expression_alternative {,

case_expression_alternative}

{*AI05-0147-1*}
Wherever the Syntax Rules allow an expression,
a conditional_expression
may be used in place of the expression,
so long as it is immediately surrounded by parentheses.

The grammar makes
the following directly legal:

A := (**if** X **then** Y **else** Z); --* parentheses required*

A := B + (**if** X **then** Y **else** Z) + C; --* parentheses required*

A := B + (

The following
procedure calls are syntactically legal; the first uses the above rule
to eliminate the redundant parentheses found in the second:

P(**if** X **then** Y **else** Z);

P((**if** X **then** Y **else** Z)); --* redundant parentheses*

P((

P((**if** X **then** Y **else** Z), Some_Other_Param);

P(Some_Other_Param, (**if** X **then** Y **else** Z));

P(Formal => (**if** X **then** Y **else** Z));

P(Some_Other_Param, (

P(Formal => (

whereas the following
are illegal:

P(**if** X **then** Y **else** Z, Some_Other_Param);

P(Some_Other_Param,**if** X **then** Y **else** Z);

P(Formal =>**if** X **then** Y **else** Z);

P(Some_Other_Param,

P(Formal =>

because in these latter cases, the conditional_expression
is not immediately surrounded by parentheses (which means on both sides!).

The English-language rule applies in all places
that could surround an expression with parentheses, including pragma
arguments, type conversion and qualified expression operands, and array
index expressions.

This English-language rule could have been implemented
instead by adding a nonterminal expression_within_parentheses,
which would consist of expressions
and conditional_expressions.
Then, that could be used in all of the syntax which could consist of
parens directly around an expression.
We did not do that because of the large amount of change required. A
complete grammar is given in AI05-0147-1.

{*AI05-0147-1*}
If a conditional_expression
is expected to be of a type *T*, then each *dependent_*expression
of the conditional_expression
is expected to be of type *T*. Similarly, if a conditional_expression
is expected to be of some class of types, then each *dependent_*expression
of the conditional_expression
is subject to the same expectation. If a conditional_expression
shall resolve to be of a type *T*, then each *dependent_*expression
shall resolve to be of type *T*.

{*AI05-0147-1*}
The possible types of a conditional_expression
are further determined as follows:

If the conditional_expression
is the operand of a type conversion, the type of the conditional_expression
is the target type of the conversion; otherwise,

T(**if** C **then** A **else** B)

has the same semantics
as

(**if** C **then** T(A) **else** T(B))

If all of the *dependent_*expressions
are of the same type, the type of the conditional_expression
is that type; otherwise,

If a *dependent_*expression
is of an elementary type, the type of the conditional_expression
shall be covered by that type; otherwise,

If the conditional_expression
is expected to be of type *T* or shall resolve to type *T*,
then the conditional_expression
is of type *T*.

{*AI05-0188-1*}
The expected type for the *selecting_*expression
and the discrete_choices
are as for case statements (see 5.4).

{*AI05-0147-1*}
{*AI05-0188-1*}
All of the *dependent_*expressions
shall be convertible (see 4.6) to the type
of the conditional_expression.

{*AI05-0147-1*}
{*AI05-0188-1*}
{*AI05-0269-1*}
If the expected type of a conditional_expression
is a specific tagged type, all of the *dependent_*expressions
of the conditional_expression
shall be dynamically tagged, or none shall be dynamically tagged. In
this case, the conditional_expression
is dynamically tagged if all of the *dependent_*expressions
are dynamically tagged, is tag-indeterminate if all of the *dependent_*expressions
are tag-indeterminate, and is statically tagged otherwise.

{*AI05-0147-1*}
{*AI05-0262-1*}
If there is no **else** *dependent_*expression,
the if_expression
shall be of a boolean type.

{*AI05-0188-1*}
{*AI05-0269-1*}
All Legality Rules that apply to the discrete_choices
of a case_statement
(see 5.4) also apply to the discrete_choices
of a case_expression
except within an instance of a generic unit.

X : Float := (

Note that the Legality Rules still apply in
the generic unit itself; they are just not enforced in an instance of
the unit.

{*AI05-0147-1*}
{*AI05-0188-1*}
For the evaluation of an if_expression,
the condition
specified after **if**, and any conditions
specified after **elsif**, are evaluated in succession (treating a
final **else** as **elsif** True **then**), until one evaluates
to True or all conditions
are evaluated and yield False. If a condition
evaluates to True, the associated *dependent_*expression
is evaluated, converted to the type of the if_expression,
and the resulting value is the value of the if_expression.
Otherwise (when there is no **else** clause), the value of the if_expression
is True.

{*AI05-0188-1*}
For the evaluation of a case_expression,
the *selecting_*expression
is first evaluated. If the value of the *selecting_*expression
is covered by the discrete_choice_list
of some case_expression_alternative,
then the *dependent_*expression
of the case_expression_alternative
is evaluated, converted to the type of the case_expression,
and the resulting value is the value of the case_expression.
Otherwise (the value is not covered by any discrete_choice_list,
perhaps due to being outside the base range), Constraint_Error is raised.

{*AI12-0429-1*}
*Example of use of an* if_expression*:*

{*AI12-0312-1*}
Put_Line ("Casey is " &

(**if** Casey.Sex = M **then** "Male" **else** "Female")); --* see 3.10.1*

(

{*AI12-0429-1*}
*Example of use of a* case_expression*:*

{*AI12-0312-1*}
**function** Card_Color (Card : Suit) **return** Color **is** --* see 3.5.1*

(**case** Card **is**

**when** Clubs | Spades => Black,

**when** Hearts | Diamonds => Red);

(

{*AI05-0147-1*}
If expressions and case expressions are new.

Ada 2005 and 2012 Editions sponsored in part by **Ada-Europe**