Category : Miscellaneous Language Source Code
Archive   : ADAREF.ZIP
Filename : LRM-04.DOC

 
Output of file : LRM-04.DOC contained in archive : ADAREF.ZIP


The Ada Joint Program Office does not guarantee the accuracy of this
file, as compared with the contents of ANSI/MIL-STD-1815A-1983,
the Reference Manual for the Ada* Programming Language. If errors or
discrepancies are found in this machine-readable version, please
forward comments via the Defense Data Network (DDN) to

[email protected]

or via conventional mail to

Ada Information Clearinghouse
3D139 (1211 S. Fern, C-107)
The Pentagon
Washington, D.C. 20301-3081.

-----------------------------------------------------------------------

Copyright 1980, 1982, 1983 owned by the United States Government as
represented by the Under Secretary of Defense, Research and
Engineering. All rights reserved. Provided that notice of copyright
is included on the first page, this document may be copied in its
entirety without alteration or as altered by (1) adding text that is
clearly marked as an insertion; (2) shading or highlighting existing
text; (3) deleting examples. Permission to publish other excerpts
should be obtained from the Ada Joint Program Office, OUSDRE (R&AT),
The Pentagon, Washington, DC 20301-2081, U.S.A.

Ada* is a registered trademark of the United States Government,
Department of Defense, Under Secretary for Research and Engineering.
Its use is administered by the Ada Joint Program Office (AJPO). In
all contexts, use of the term "Ada" should indicate conformance to the
standard. In keeping with policies on voluntary conformance, use of
the term Ada is equivalent to a voluntary statement of conformance to
the standard.

The use of the trademarked term Ada will be made freely available to
those who use it to indicate conformance to the standard and in
accordance with the following guidelines:

In any published material the first appearance of the term Ada
must be properly acknowledged and include the statement "Ada
is a registered trademark of the U.S. Government (Ada Joint
Program Office)."

Describing, advertising, or promoting a language processor
as an "Ada" processor is equivalent to making a voluntary
statement of conformance to ANSI/MIL-STD-1815A.

The term Ada may be used in describing language processors
which are not completely conforming or are not making a claim
of conformance provided that there is a precise, easily
visible statement of their non-conformance at the same
time and in the same context.

Uses of the term Ada other than those described above, including all
organizations, companies and product names incorporating or utilizing
the term Ada, need written authorization from the AJPO. Those persons
advertising or otherwise promoting a language processor asserted as
being a standard Ada processor for sale or public use are required to
provide the AJPO with evidence sufficient to demonstrate conformance
to the Ada standard.

Use of the trademark does not imply any endorsement or warranty of the
product by either U.S. DoD or ANSI.

The Department of Defense (DoD), as the trademark owner, will allow
others to use the Ada trademark free of charge and will not take
action to prevent use of the Ada trademark so long as the trademark is
used properly according to the above policy. Misuse of the trademark
may lead to legal action.

In the interest of information interchange, all users of this standard
are encouraged to contact the Ada Joint Program Office, Department of
Defense, OUSD(R&E), Washington, D.C. 20301, U.S.A. Users of the
trademark and those reprinting the standard are required to notify the
AJPO.


*Ada is a registered trademark of the U.S. Government
(Ada Joint Program Office).




4. Names and Expressions
The rules applicable to the different forms of name and expression, and to
their evaluation, are given in this chapter.
4.1 Names
Names can denote declared entities, whether declared explicitly or
implicitly (see 3.1). Names can also denote objects designated by access
values; subcomponents and slices of objects and values; single entries,
entry families, and entries in families of entries. Finally, names can
denote attributes of any of the foregoing.
name ::= simple_name
| character_literal | operator_symbol
| indexed_component | slice
| selected_component | attribute
simple_name ::= identifier
prefix ::= name | function_call
A simple name for an entity is either the identifier associated with the
entity by its declaration, or another identifier associated with the entity
by a renaming declaration.
Certain forms of name (indexed and selected components, slices, and
attributes) include a prefix that is either a name or a function call. If
the type of a prefix is an access type, then the prefix must not be a name
that denotes a formal parameter of mode out or a subcomponent thereof.
If the prefix of a name is a function call, then the name denotes a
component, a slice, an attribute, an entry, or an entry family, either of
the result of the function call, or (if the result is an access value) of
the object designated by the result.
A prefix is said to be appropriate for a type in either of the following
cases:
- The type of the prefix is the type considered.
- The type of the prefix is an access type whose designated type is the
type considered.
4 - 1
The evaluation of a name determines the entity denoted by the name. This
evaluation has no other effect for a name that is a simple name, a
character literal, or an operator symbol.
The evaluation of a name that has a prefix includes the evaluation of the
prefix, that is, of the corresponding name or function call. If the type
of the prefix is an access type, the evaluation of the prefix includes the
determination of the object designated by the corresponding access value;
the exception CONSTRAINT_ERROR is raised if the value of the prefix is a
null access value, except in the case of the prefix of a representation
attribute (see 13.7.2).
4 - 2
Examples of simple names:
PI -- the simple name of a number (see 3.2.2)
LIMIT -- the simple name of a constant (see 3.2.1)
COUNT -- the simple name of a scalar variable (see 3.2.1)
BOARD -- the simple name of an array variable (see 3.6.1)
MATRIX -- the simple name of a type (see 3.6)
RANDOM -- the simple name of a function (see 6.1)
ERROR -- the simple name of an exception (see 11.1)
References: access type 3.8, access value 3.8, attribute 4.1.4, belong to
a type 3.3, character literal 2.5, component 3.3, constraint_error
exception 11.1, declaration 3.1, designate 3.8, designated type 3.8, entity
3.1, entry 9.5, entry family 9.5, evaluation 4.5, formal parameter 6.1,
function call 6.4, identifier 2.3, indexed component 4.1.1, mode 6.1, null
access value 3.8, object 3.2.1, operator symbol 6.1, raising of exceptions
11, renaming declarations 8.5, selected component 4.1.3, slice 4.1.2,
subcomponent 3.3, type 3.3
4.1.1 Indexed Components
An indexed component denotes either a component of an array or an entry in
a family of entries.
indexed_component ::= prefix(expression {, expression})
In the case of a component of an array, the prefix must be appropriate for
an array type. The expressions specify the index values for the component;
there must be one such expression for each index position of the array
type. In the case of an entry in a family of entries, the prefix must be a
name that denotes an entry family of a task object, and the expression
(there must be exactly one) specifies the index value for the individual
entry.
Each expression must be of the type of the corresponding index. For the
evaluation of an indexed component, the prefix and the expressions are
evaluated in some order that is not defined by the language. The exception
CONSTRAINT_ERROR is raised if an index value does not belong to the range
of the corresponding index of the prefixing array or entry family.
Examples of indexed components:
MY_SCHEDULE(SAT) -- a component of a one-dimensional array (see 3.6.1)
PAGE(10) -- a component of a one-dimensional array (see 3.6)
BOARD(M, J + 1) -- a component of a two-dimensional array (see 3.6.1)
PAGE(10)(20) -- a component of a component (see 3.6)
REQUEST(MEDIUM) -- an entry in a family of entries (see 9.5)
NEXT_FRAME(L)(M, N) -- a component of a function call (see 6.1)
Notes on the examples:
4 - 3
Distinct notations are used for components of multidimensional arrays (such
as BOARD) and arrays of arrays (such as PAGE). The components of an array
of arrays are arrays and can therefore be indexed. Thus PAGE(10)(20)
denotes the 20th component of PAGE(10). In the last example NEXT_FRAME(L)
is a function call returning an access value which designates a
two-dimensional array.
References: appropriate for a type 4.1, array type 3.6, component 3.3,
component of an array 3.6, constraint_error exception 11.1, dimension 3.6,
entry 9.5, entry family 9.5, evaluation 4.5, expression 4.4, function call
6.4, in some order 1.6, index 3.6, name 4.1, prefix 4.1, raising of
exceptions 11, returned value 5.8 6.5, task object 9.2
4 - 4
4.1.2 Slices
A slice denotes a one-dimensional array formed by a sequence of consecutive
components of a one-dimensional array. A slice of a variable is a
variable; a slice of a constant is a constant; a slice of a value is a
value.
slice ::= prefix(discrete_range)
The prefix of a slice must be appropriate for a one-dimensional array type.
The type of the slice is the base type of this array type. The bounds of
the discrete range define those of the slice and must be of the type of the
index; the slice is a null slice denoting a null array if the discrete
range is a null range.
For the evaluation of a name that is a slice, the prefix and the discrete
range are evaluated in some order that is not defined by the language. The
exception CONSTRAINT_ERROR is raised by the evaluation of a slice, other
than a null slice, if any of the bounds of the discrete range does not
belong to the index range of the prefixing array. (The bounds of a null
slice need not belong to the subtype of the index.)
Examples of slices:
STARS(1 .. 15) -- a slice of 15 characters (see 3.6.3)
PAGE(10 .. 10 + SIZE) -- a slice of 1 + SIZE components (see 3.6 and 3.2.1)
PAGE(L)(A .. B) -- a slice of the array PAGE(L) (see 3.6)
STARS(1 .. 0) -- a null slice (see 3.6.3)
MY_SCHEDULE(WEEKDAY) -- bounds given by subtype (see 3.6 and 3.5.1)
STARS(5 .. 15)(K) -- same as STARS(K) (see 3.6.3)
-- provided that K is in 5 .. 15
Notes:
For a one-dimensional array A, the name A(N .. N) is a slice of one
component; its type is the base type of A. On the other hand, A(N) is a
component of the array A and has the corresponding component type.
References: appropriate for a type 4.1, array 3.6, array type 3.6, array
value 3.8, base type 3.3, belong to a subtype 3.3, bound of a discrete
range 3.6.1, component 3.3, component type 3.3, constant 3.2.1, constraint
3.3, constraint_error exception 11.1, dimension 3.6, discrete range 3.6,
evaluation 4.5, index 3.6, index range 3.6, name 4.1, null array 3.6.1,
null range 3.5, prefix 4.1, raising of exceptions 11, type 3.3, variable 3.2.1
4.1.3 Selected Components
Selected components are used to denote record components, entries, entry
families, and objects designated by access values; they are also used as
expanded names as described below.
4 - 5
selected_component ::= prefix.selector
selector ::= simple_name
| character_literal | operator_symbol | all
4 - 6
The following four forms of selected components are used to denote a
discriminant, a record component, an entry, or an object designated by an
access value:
(a) A discriminant:
The selector must be a simple name denoting a discriminant of an
object or value. The prefix must be appropriate for the type of this
object or value.
(b) A component of a record:
The selector must be a simple name denoting a component of a record
object or value. The prefix must be appropriate for the type of this
object or value.
For a component of a variant, a check is made that the values of the
discriminants are such that the record has this component. The
exception CONSTRAINT_ERROR is raised if this check fails.
(c) A single entry or an entry family of a task:
The selector must be a simple name denoting a single entry or an entry
family of a task. The prefix must be appropriate for the type of this
task.
(d) An object designated by an access value:
The selector must be the reserved word all. The value of the prefix
must belong to an access type.
A selected component of one of the remaining two forms is called an
expanded name. In each case the selector must be either a simple name, a
character literal, or an operator symbol. A function call is not allowed
as the prefix of an expanded name. An expanded name can denote:
(e) An entity declared in the visible part of a package:
The prefix must denote the package. The selector must be the simple
name, character literal, or operator symbol of the entity.
(f) An entity whose declaration occurs immediately within a named
construct:
The prefix must denote a construct that is either a program unit, a
block statement, a loop statement, or an accept statement. In the
case of an accept statement, the prefix must be either the simple name
of the entry or entry family, or an expanded name ending with such a
simple name (that is, no index is allowed). The selector must be the
simple name, character literal, or operator symbol of an entity whose
declaration occurs immediately within the construct.
This form of expanded name is only allowed within the construct itself
(including the body and any subunits, in the case of a program unit).
A name declared by a renaming declaration is not allowed as the
4 - 7
prefix. If the prefix is the name of a subprogram or accept statement
and if there is more than one visible enclosing subprogram or accept
statement of this name, the expanded name is ambiguous, independently
of the selector.
If, according to the visibility rules, there is at least one possible
interpretation of the prefix of a selected component as the name of an
enclosing subprogram or accept statement, then the only interpretations
considered are those of rule (f), as expanded names (no interpretations of
the prefix as a function call are then considered).
4 - 8
The evaluation of a name that is a selected component includes the
evaluation of the prefix.
Examples of selected components:
TOMORROW.MONTH -- a record component (see 3.7)
NEXT_CAR.OWNER -- a record component (see 3.8.1)
NEXT_CAR.OWNER.AGE -- a record component (see 3.8.1)
WRITER.UNIT -- a record component (a discriminant) (see 3.7.3)
MIN_CELL(H).VALUE -- a record component of the result (see 6.1 and 3.8.1)
-- of the function call MIN_CELL(H)
CONTROL.SEIZE -- an entry of the task CONTROL (see 9.1 and 9.2)
POOL(K).WRITE -- an entry of the task POOL(K) (see 9.1 and 9.2)
NEXT_CAR.all -- the object designated by
-- the access variable NEXT_CAR (see 3.8.1)
Examples of expanded names:
TABLE_MANAGER.INSERT -- a procedure of the visible part of a package (see 7.5)
KEY_MANAGER."<" -- an operator of the visible part of a package (see 7.4.2)
DOT_PRODUCT.SUM -- a variable declared in a procedure body (see 6.5)
BUFFER.POOL -- a variable declared in a task unit (see 9.12)
BUFFER.READ -- an entry of a task unit (see 9.12)
SWAP.TEMP -- a variable declared in a block statement (see 5.6)
STANDARD.BOOLEAN -- the name of a predefined type (see 8.6 and C) Note:
For a record with components that are other records, the above rules imply
that the simple name must be given at each level for the name of a
subcomponent. For example, the name NEXT_CAR.OWNER.BIRTH.MONTH cannot be
shortened (NEXT_CAR.OWNER.MONTH is not allowed).
References: accept statement 9.5, access type 3.8, access value 3.8,
appropriate for a type 4.1, block statement 5.6, body of a program unit
3.9, character literal 2.5, component of a record 3.7, constraint_error
exception 11.1, declaration 3.1, designate 3.8, discriminant 3.3, entity
3.1, entry 9.5, entry family 9.5, function call 6.4, index 3.6, loop
statement 5.5, object 3.2.1, occur immediately within 8.1, operator 4.5,
operator symbol 6.1, overloading 8.3, package 7, predefined type C, prefix
4.1, procedure body 6.3, program unit 6, raising of exceptions 11, record
3.7, record component 3.7, renaming declaration 8.5, reserved word 2.9,
simple name 4.1, subprogram 6, subunit 10.2, task 9, task object 9.2, task
unit 9, variable 3.7.3, variant 3.7.3, visibility 8.3, visible part 3.7.3
4.1.4 Attributes
An attribute denotes a basic operation of an entity given by a prefix.
4 - 9
attribute ::= prefix'attribute_designator
attribute_designator ::= simple_name [(universal_static_expression)]
The applicable attribute designators depend on the prefix. An attribute
can be a basic operation delivering a value; alternatively it can be a
function, a type, or a range. The meaning of the prefix of an attribute
must be determinable independently of the attribute designator and
independently of the fact that it is the prefix of an attribute.
4 - 1 4
The attributes defined by the language are summarized in Annex A. In
addition, an implementation may provide implementation-defined attributes;
their description must be given in Appendix F. The attribute designator of
any implementation-defined attribute must not be the same as that of any
language-defined attribute.
The evaluation of a name that is an attribute consists of the evaluation of
the prefix.
Notes:
The attribute designators DIGITS, DELTA, and RANGE have the same identifier
as a reserved word. However, no confusion is possible since an attribute
designator is always preceded by an apostrophe. The only predefined
attribute designators that have a universal expression are those for
certain operations of array types (see 3.6.2).
Examples of attributes:
COLOR'FIRST -- minimum value of the enumeration type COLOR (see 3.3.1 and 3.5)
RAINBOW'BASE'FIRST -- same as COLOR'FIRST (see 3.3.2 and 3.3.3)

REAL'DIGITS -- precision of the type REAL (see 3.5.7 and 3.5.8)
BOARD'LAST(2) -- upper bound of the second dimension of BOARD (see 3.6.1 and 3.6.2)
BOARD'RANGE(1) -- index range of the first dimension of BOARD (see 3.6.1 and 3.6.2)
POOL(K)'TERMINATED -- TRUE if task POOL(K) is terminated (see 9.2 and 9.9)
DATE'SIZE -- number of bits for records of type DATE (see 3.7 and 13.7.2)
MESSAGE'ADDRESS -- address of the record variable MESSAGE (see 3.7.2 and 13.7.2)
References: appropriate for a type 4.1, basic operation 3.3.3, declared
entity 3.1, name 4.1, prefix 4.1, reserved word 2.9, simple name 4.1,
static expression 4.9, type 3.3, universal expression 4.1 4
4.2 Literals
A literal is either a numeric literal, an enumeration literal, the literal
null, or a string literal. The evaluation of a literal yields the
corresponding value.
Numeric literals are the literals of the types universal_integer and
universal_real. Enumeration literals include character literals and yield
values of the corresponding enumeration types. The literal null yields a
null access value which designates no objects at all.
A string literal is a basic operation that combines a sequence of
characters into a value of a one-dimensional array of a character type;
the bounds of this array are determined according to the rules for
positional array aggregates (see 4.3.2). For a null string literal, the
upper bound is the predecessor, as given by the PRED attribute, of the
lower bound. The evaluation of a null string literal raises the exception
CONSTRAINT_ERROR if the lower bound does not have a predecessor (see
3.5.5).
4 - 11
The type of a string literal and likewise the type of the literal null must
be determinable solely from the context in which this literal appears,
excluding the literal itself, but using the fact that the literal null is a
value of an access type, and similarly that a string literal is a value of
a one-dimensional array type whose component type is a character type.
The character literals corresponding to the graphic characters contained
within a string literal must be visible at the place of the string literal
(although these characters themselves are not used to determine the type of
the string literal).
4 - 12
Examples:
3.14159_26536 -- a real literal
1_345 -- an integer literal
CLUBS -- an enumeration literal
'A' -- a character literal
"SOME TEXT" -- a string literal
References: access type 3.8, aggregate 4.3, array 3.6, array bound 3.6,
array type 3.6, character literal 2.5, character type 3.5.2, component type
3.3, constraint_error exception 11.1, designate 3.8, dimension 3.6,
enumeration literal 3.5.1, graphic character 2.1, integer literal 2.4, null
access value 3.8, null literal 3.8, numeric literal 2.4, object 3.2.1, real
literal 2.4, string literal 2.6, type 3.3, universal_integer type 3.5.4,
universal_real type 3.5.6, visibility 8.3
4.3 Aggregates
An aggregate is a basic operation that combines component values into a
composite value of a record or array type.
aggregate ::=
(component_association {, component_association})
component_association ::=
[choice {| choice} => ] expression
Each component association associates an expression with components
(possibly none). A component association is said to be named if the
components are specified explicitly by choices; it is otherwise said to be
positional. For a positional association, the (single) component is
implicitly specified by position, in the order of the corresponding
component declarations for record components, in index order for array
components.
Named associations can be given in any order (except for the choice
others), but if both positional and named associations are used in the same
aggregate, then positional associations must occur first, at their normal
position. Hence once a named association is used, the rest of the
aggregate must use only named associations. Aggregates containing a single
component association must always be given in named notation. Specific
rules concerning component associations exist for record aggregates and
array aggregates.
Choices in component associations have the same syntax as in variant parts
(see 3.7.3). A choice that is a component simple name is only allowed in a
record aggregate. For a component association, a choice that is a simple
expression or a discrete range is only allowed in an array aggregate; a
choice that is a simple expression specifies the component at the
corresponding index value; similarly a discrete range specifies the
components at the index values in the range. The choice others is only
allowed in a component association if the association appears last and has
4 - 13
this single choice; it specifies all remaining components, if any.
Each component of the value defined by an aggregate must be represented
once and only once in the aggregate. Hence each aggregate must be complete
and a given component is not allowed to be specified by more than one
choice.
The type of an aggregate must be determinable solely from the context in
which the aggregate appears, excluding the aggregate itself, but using the
fact that this type must be composite and not limited. The type of an
aggregate in turn determines the required type for each of its components.
4 - 14
Notes:
The above rule implies that the determination of the type of an aggregate
cannot use any information from within the aggregate. In particular, this
determination cannot use the type of the expression of a component
association, or the form or the type of a choice. An aggregate can always
be distinguished from an expression enclosed by parentheses: this is a
consequence of the fact that named notation is required for an aggregate
with a single component.
References: array aggregate 4.3.2, array type 3.6, basic operation 3.3.3,
choice 3.7.3, component 3.3, composite type 3.3, composite value 3.3,
discrete range 3.6, expression 4.4, index 3.6, limited type 7.4.4, primary
4.4, record aggregate 4.3.1, record type 3.7, simple expression 4.4, simple
name 4.1, type 3.3, variant part 3.7.3
4.3.1 Record Aggregates
If the type of an aggregate is a record type, the component names given as
choices must denote components (including discriminants) of the record
type. If the choice others is given as a choice of a record aggregate, it
must represent at least one component. A component association with the
choice others or with more than one choice is only allowed if the
represented components are all of the same type. The expression of a
component association must have the type of the associated record
components.
The value specified for a discriminant that governs a variant part must be
given by a static expression (note that this value determines which
dependent components must appear in the record value).
For the evaluation of a record aggregate, the expressions given in the
component associations are evaluated in some order that is not defined by
the language. The expression of a named association is evaluated once for
each associated component. A check is made that the value of each
subcomponent of the aggregate belongs to the subtype of this subcomponent.
The exception CONSTRAINT_ERROR is raised if this check fails.
Example of a record aggregate with positional associations:
(4, JULY, 1776) -- see 3.7
Examples of record aggregates with named associations:
(DAY => 4, MONTH => JULY, YEAR => 1776)
(MONTH => JULY, DAY => 4, YEAR => 1776)
(DISK, CLOSED, TRACK => 5, CYLINDER => 12) -- see 3.7.3
(UNIT => DISK, STATUS => CLOSED, CYLINDER => 9, TRACK => 1)
Example of component association with several choices:
4 - 15
(VALUE => 0, SUCC|PRED => new CELL'(0, null, null)) -- see 3.8.1
-- The allocator is evaluated twice: SUCC and PRED designate different cells Note:
For an aggregate with positional associations, discriminant values appear
first since the discriminant part is given first in the record type
declaration; they must be in the same order as in the discriminant part.
4 - 16
References: aggregate 4.3, allocator 4.8, choice 3.7.3, component
association 4.3, component name 3.7, constraint 3.3, constraint_error
exception 11.1, depend on a discriminant 3.7.1, discriminant 3.3,
discriminant part 3.7.1, evaluate 4.5, expression 4.4, in some order 1.6,
program 10, raising of exceptions 11, record component 3.7, record type
3.7, satisfy 3.3, static expression 4.9, subcomponent 3.3, subtype 3.3.2,
type 3.3, variant part 3.7.3
4.3.2 Array Aggregates
If the type of an aggregate is a one-dimensional array type, then each
choice must specify values of the index type, and the expression of each
component association must be of the component type.
If the type of an aggregate is a multidimensional array type, an
n-dimensional aggregate is written as a one-dimensional aggregate, in which
the expression specified for each component association is itself written
as an (n-1)-dimensional aggregate which is called a subaggregate; the
index subtype of the one-dimensional aggregate is given by the first index
position of the array type. The same rule is used to write a subaggregate
if it is again multidimensional, using successive index positions. A
string literal is allowed in a multidimensional aggregate at the place of a
one-dimensional array of a character type. In what follows, the rules
concerning array aggregates are formulated in terms of one-dimensional
aggregates.
Apart from a final component association with the single choice others, the
rest (if any) of the component associations of an array aggregate must be
either all positional or all named. A named association of an array
aggregate is only allowed to have a choice that is not static, or likewise
a choice that is a null range, if the aggregate includes a single component
association and this component association has a single choice. An others
choice is static if the applicable index constraint is static.
The bounds of an array aggregate that has an others choice are determined
by the applicable index constraint. An others choice is only allowed if
the aggregate appears in one of the following contexts (which defines the
applicable index constraint):
(a) The aggregate is an actual parameter, a generic actual parameter, the
result expression of a function, or the expression that follows an
assignment compound delimiter. Moreover, the subtype of the
corresponding formal parameter, generic formal parameter, function
result, or object is a constrained array subtype.
For an aggregate that appears in such a context and contains an
association with an others choice, named associations are allowed for
other associations only in the case of a (nongeneric) actual parameter
or function result. If the aggregate is a multidimensional array,
this restriction also applies to each of its subaggregates.
4 - 17
(b) The aggregate is the operand of a qualified expression whose type mark
denotes a constrained array subtype.
(c) The aggregate is the expression of the component association of an
enclosing (array or record) aggregate. Moreover, if this enclosing
aggregate is a multidimensional array aggregate then it is itself in
one of these three contexts.
The bounds of an array aggregate that does not have an others choice are
determined as follows. For an aggregate that has named associations, the
bounds are determined by the smallest and largest choices given. For a
positional aggregate, the lower bound is determined by the applicable index
constraint if the aggregate appears in one of the contexts (a) through (c);
otherwise, the lower bound is given by S'FIRST where S is the index
subtype; in either case, the upper bound is determined by the number of
components.
4 - 18
The evaluation of an array aggregate that is not a subaggregate proceeds in
two steps. First, the choices of this aggregate and of its subaggregates,
if any, are evaluated in some order that is not defined by the language.
Second, the expressions of the component associations of the array
aggregate are evaluated in some order that is not defined by the language;
the expression of a named association is evaluated once for each associated
component. The evaluation of a subaggregate consists of this second step
(the first step is omitted since the choices have already been evaluated).
For the evaluation of an aggregate that is not a null array, a check is
made that the index values defined by choices belong to the corresponding
index subtypes, and also that the value of each subcomponent of the
aggregate belongs to the subtype of this subcomponent. For an
n-dimensional multidimensional aggregate, a check is made that all
(n-1)-dimensional subaggregates have the same bounds. The exception
CONSTRAINT_ERROR is raised if any of these checks fails. Note:
The allowed contexts for an array aggregate including an others choice are
such that the bounds of such an aggregate are always known from the
context.
Examples of array aggregates with positional associations:
(7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
TABLE'(5, 8, 4, 1, others => 0) -- see 3.6
Examples of array aggregates with named associations:
(1 .. 5 => (1 .. 8 => 0.0)) -- two-dimensional
(1 .. N => new CELL) -- N new cells, in particular for N = 4
TABLE'(2 | 4 | 10 => 1, others => 0)
SCHEDULE'(MON .. FRI => TRUE, others => FALSE) -- see 3.6
SCHEDULE'(WED | SUN => FALSE, others => TRUE)
Examples of two-dimensional array aggregates:
-- Three aggregates for the same value of type MATRIX (see 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))
Examples of aggregates as initial values:
A : TABLE := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0); -- A(1)=7, A(10)= 8 B : TABLE := TABLE'(2 | 4 | 10 => 1, others => 0); -- B(1)=0, B(10)=1
C : constant MATRIX := (1 .. 5 => (1 .. 8 => 0.0)); -- C'FIRST(1)=1, C'LAST(2)=8
D : BIT_VECTOR(M .. N) := (M .. N => TRUE); -- see 3.6
E : BIT_VECTOR(M .. N) := (others => TRUE);
F : STRING(1 .. 1) := (1 => 'F'); -- a one component aggregate: same as "F"
4 - 19
References: actual parameter 6.4.1, aggregate 4.3, array type 3.6,
assignment compound delimiter 5.2, choice 3.7.3, component 3.3, component
association 4.3, component type 3.3, constrained array subtype 3.6,
constraint 3.3, constraint_error exception 11.1, dimension 3.6, evaluate
4.5, expression 4.4, formal parameter 6.1, function 6.5, in some order 1.6,
index constraint 3.6.1, index range 3.6, index subtype 3.6, index type 3.6,
named component association 4.3, null array 3.6.1, object 3.2, positional
component association 4.3, qualified expression 4.7, raising of exceptions
11, static expression 4.9, subcomponent 3.3, type 3.3
4 - 2 4
4.4 Expressions
An expression is a formula that defines the computation of a value.
expression ::=
relation {and relation} | relation {and then relation}
| relation {or relation} | relation {or else relation}
| relation {xor relation}
relation ::=
simple_expression [relational_operator simple_expression]
| simple_expression [not] in range
| simple_expression [not] in type_mark
simple_expression ::= [unary_adding_operator] term {binary_adding_operator term}
term ::= factor {multiplying_operator factor}
factor ::= primary [** primary] | abs primary | not primary
primary ::=
numeric_literal | null | aggregate | string_literal | name | allocator
| function_call | type_conversion | qualified_expression | (expression)
Each primary has a value and a type. The only names allowed as primaries
are named numbers; attributes that yield values; and names denoting
objects (the value of such a primary is the value of the object) or
denoting values. Names that denote formal parameters of mode out are not
allowed as primaries; names of their subcomponents are only allowed in the
case of discriminants.
The type of an expression depends only on the type of its constituents and
on the operators applied; for an overloaded constituent or operator, the
determination of the constituent type, or the identification of the
appropriate operator, depends on the context. For each predefined
operator, the operand and result types are given in section 4.5.
Examples of primaries:
4.0 -- real literal
PI -- named number
(1 .. 10 => 0) -- array aggregate
SUM -- variable
INTEGER'LAST -- attribute
SINE(X) -- function call
COLOR'(BLUE) -- qualified expression
REAL(M*N) -- conversion
(LINE_COUNT + 10) -- parenthesized expression
Examples of expressions:
VOLUME -- primary
not DESTROYED -- factor
2*LINE_COUNT -- term
4 - 21
-4.0 -- simple expression
-4.0 + A -- simple expression
B**2 - 4.0*A*C -- simple expression
PASSWORD(1 .. 3) = "BWV" -- relation
COUNT in SMALL_INT -- relation
COUNT not in SMALL_INT -- relation
INDEX = 0 or ITEM_HIT -- expression
(COLD and SUNNY) or WARM -- expression (parentheses are required)
A**(B**C) -- expression (parentheses are required)
4 - 22
References: aggregate 4.3, allocator 4.8, array aggregate 4.3.2, attribute
4.1.4, binary adding operator 4.5 4.5.3, context of overload resolution
8.7, exponentiating operator 4.5 4.5.6, function call 6.4, multiplying
operator 4.5 4.5.5, name 4.1, named number 3.2, null literal 3.8, numeric
literal 2.4, object 3.2, operator 4.5, overloading 8.3, overloading an
operator 6.7, qualified expression 4.7, range 3.5, real literal 2.4,
relation 4.5.1, relational operator 4.5 4.5.2, result type 6.1, string
literal 2.6, type 3.3, type conversion 4.6, type mark 3.3.2, unary adding
operator 4.5 4.5.4, variable 3.2.1
4.5 Operators and Expression Evaluation
The language defines the following six classes of operators. The
corresponding operator symbols (except /=), and only those, can be used as
designators in declarations of functions for user-defined operators. They
are given in the order of increasing precedence.
logical_operator ::= and | or | xor
relational_operator ::= = | /= | < | <= | > | >=
binary_adding_operator ::= + | - | &
unary_adding_operator ::= + | -
multiplying_operator ::= * | / | mod | rem
highest_precedence_operator ::= ** | abs | not
The short-circuit control forms and then and or else have the same
precedence as logical operators. The membership tests in and not in have
the same precedence as relational operators.
For a term, simple expression, relation, or expression, operators of higher
precedence are associated with their operands before operators of lower
precedence. In this case, for a sequence of operators of the same
precedence level, the operators are associated in textual order from left
to right; parentheses can be used to impose specific associations.
The operands of a factor, of a term, of a simple expression, or of a
relation, and the operands of an expression that does not contain a
short-circuit control form, are evaluated in some order that is not defined
by the language (but before application of the corresponding operator).
The right operand of a short-circuit control form is evaluated if and only
if the left operand has a certain value (see 4.5.1).
For each form of type declaration, certain of the above operators are
predefined, that is, they are implicitly declared by the type declaration.
For each such implicit operator declaration, the names of the parameters
are LEFT and RIGHT for binary operators; the single parameter is called
RIGHT for unary adding operators and for the unary operators abs and not.
The effect of the predefined operators is explained in subsections 4.5.1
4 - 23
through 4.5.7.
The predefined operations on integer types either yield the mathematically
correct result or raise the exception NUMERIC_ERROR. A predefined
operation that delivers a result of an integer type (other than
universal_integer) can only raise the exception NUMERIC_ERROR if the
mathematical result is not a value of the type. The predefined operations
on real types yield results whose accuracy is defined in section 4.5.7. A
predefined operation that delivers a result of a real type (other than
universal_real) can only raise the exception NUMERIC_ERROR if the result is
not within the range of the safe numbers of the type, as explained in
section 4.5.7.
4 - 24
Examples of precedence:
not SUNNY or WARM -- same as (not SUNNY) or WARM
X > 4.0 and Y > 0.0 -- same as (X > 4.0) and (Y > 0.0)
-4.0*A**2 -- same as -(4.0 * (A**2))
abs(1 + A) + B -- same as (abs (1 + A)) + B
Y**(-3) -- parentheses are necessary
A / B * C -- same as (A/B)*C
A + (B + C) -- evaluate B + C before adding it to A
References: designator 6.1, expression 4.4, factor 4.4, implicit
declaration 3.1, in some order 1.6, integer type 3.5.4, membership test
4.5.2, name 4.1, numeric_error exception 11.1, overloading 6.6 8.7, raising
of an exception 11, range 3.5, real type 3.5.6, relation 4.4, safe number
3.5.6, short-circuit control form 4.5 4.5.1, simple expression 4.4, term
4.4, type 3.3, type declaration 3.3.1, universal_integer type 3.5.4,
universal_real type 3.5.6
4.5.1 Logical Operators and Short-circuit Control Forms
The following logical operators are predefined for any boolean type and any
one-dimensional array type whose components are of a boolean type; in
either case the two operands have the same type.
Operator Operation Operand type Result type
and conjunction any boolean type same boolean type
array of boolean components same array type
or inclusive disjunction any boolean type same boolean type
array of boolean components same array type
xor exclusive disjunction any boolean type same boolean type
array of boolean components same array type
The operations on arrays are performed on a component-by-component basis on
matching components, if any (as for equality, see 4.5.2). The bounds of
the resulting array are those of the left operand. A check is made that
for each component of the left operand there is a matching component of the
right operand, and vice versa. The exception CONSTRAINT_ERROR is raised if
this check fails.
The short-circuit control forms and then and or else are defined for two
operands of a boolean type and deliver a result of the same type. The left
operand of a short-circuit control form is always evaluated first. If the
left operand of an expression with the control form and then evaluates to
FALSE, the right operand is not evaluated and the value of the expression
is FALSE. If the left operand of an expression with the control form or
else evaluates to TRUE, the right operand is not evaluated and the value of
the expression is TRUE. If both operands are evaluated, and then delivers
the same result as and, and or else delivers the same result as or.
4 - 25
Note: The conventional meaning of the logical operators is given by the
following truth table:
A B (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
4 - 26
Examples of logical operators:
SUNNY or WARM
FILTER(1 .. 10) and FILTER(15 .. 24) -- see 3.6.1
Examples of short-circuit control forms:
NEXT_CAR.OWNER /= null and then NEXT_CAR.OWNER.AGE > 25 -- see 3.8.1
N = 0 or else A(N) = HIT_VALUE
References: array type 3.6, boolean type 3.5.3, bound of an index range
3.6.1, component of an array 3.6, constraint_error exception 11.1,
dimension 3.6, false boolean value 3.5.3, index subtype 3.6, matching
components of arrays 4.5.2, null array 3.6.1, operation 3.3, operator 4.5,
predefined operator 4.5, raising of exceptions 11, true boolean value
3.5.3, type 3.3
4.5.2 Relational Operators and Membership Tests
The equality and inequality operators are predefined for any type that is
not limited. The other relational operators are the ordering operators <
(less than), <= (less than or equal), > (greater than), and >= (greater
than or equal). The ordering operators are predefined for any scalar
type, and for any discrete array type, that is, a one-dimensional array
type whose components are of a discrete type. The operands of each
predefined relational operator have the same type. The result type is the
predefined type BOOLEAN.
The relational operators have their conventional meaning: the result is
equal to TRUE if the corresponding relation is satisfied; the result is
FALSE otherwise. The inequality operator gives the complementary result to
the equality operator: FALSE if equal, TRUE if not equal.
Operator Operation Operand type Result type
= /= equality and inequality any type BOOLEAN
< <= > >= test for ordering any scalar type BOOLEAN
discrete array type BOOLEAN
Equality for the discrete types is equality of the values. For real
operands whose values are nearly equal, the results of the predefined
relational operators are given in section 4.5.7. Two access values are
equal either if they designate the same object, or if both are equal to the
null value of the access type.
For two array values or two record values of the same type, the left
operand is equal to the right operand if and only if for each component of
the left operand there is a matching component of the right operand and
vice versa; and the values of matching components are equal, as given by
the predefined equality operator for the component type. In particular,
two null arrays of the same type are always equal; two null records of the
4 - 27
same type are always equal.
For comparing two records of the same type, matching components are those
which have the same component identifier.
For comparing two one-dimensional arrays of the same type, matching
components are those (if any) whose index values match in the following
sense: the lower bounds of the index ranges are defined to match, and the
successors of matching indices are defined to match. For comparing two
multidimensional arrays, matching components are those whose index values
match in successive index positions.
4 - 28
If equality is explicitly defined for a limited type, it does not extend to
composite types having subcomponents of the limited type (explicit
definition of equality is allowed for such composite types).
The ordering operators <, <=, >, and >= that are defined for discrete array
types correspond to lexicographic order using the predefined order relation
of the component type. A null array is lexicographically less than any
array having at least one component. In the case of nonnull arrays, the
left operand is lexicographically less than the right operand if the first
component of the left operand is less than that of the right; otherwise
the left operand is lexicographically less than the right operand only if
their first components are equal and the tail of the left operand is
lexicographically less than that of the right (the tail consists of the
remaining components beyond the first and can be null).
The membership tests in and not in are predefined for all types. The
result type is the predefined type BOOLEAN. For a membership test with a
range, the simple expression and the bounds of the range must be of the
same scalar type; for a membership test with a type mark, the type of the
simple expression must be the base type of the type mark. The evaluation
of the membership test in yields the result TRUE if the value of the simple
expression is within the given range, or if this value belongs to the
subtype denoted by the given type mark; otherwise this evaluation yields
the result FALSE (for a value of a real type, see 4.5.7). The membership
test not in gives the complementary result to the membership test in.
Examples:
X /= Y
"" < "A" and "A" < "AA" -- TRUE
"AA" < "B" and "A" < "A " -- TRUE
MY_CAR = null -- true if MY_CAR has been set to null (see 3.8.1)
MY_CAR = YOUR_CAR -- true if we both share the same car
MY_CAR.all = YOUR_CAR.all -- true if the two cars are identical
N not in 1 .. 10 -- range membership test
TODAY in MON .. FRI -- range membership test
TODAY in WEEKDAY -- subtype membership test (see 3.5.1)
ARCHIVE in DISK_UNIT -- subtype membership test (see 3.7.3)
Notes:
No exception is ever raised by a predefined relational operator or by a
membership test, but an exception can be raised by the evaluation of the
operands.
If a record type has components that depend on discriminants, two values of
this type have matching components if and only if their discriminants are
equal. Two nonnull arrays have matching components if and only if the
value of the attribute LENGTH(N) for each index position N is the same for both.
4 - 29
References: access value 3.8, array type 3.6, base type 3.3, belong to a
subtype 3.3, boolean predefined type 3.5.3, bound of a range 3.5, component
3.3, component identifier 3.7, component type 3.3, composite type 3.3,
designate 3.8, dimension 3.6, discrete type 3.5, evaluation 4.5, exception
11, index 3.6, index range 3.6, limited type 7.4.4, null access value 3.8,
null array 3.6.1, null record 3.7, object 3.2.1, operation 3.3, operator
4.5, predefined operator 4.5, raising of exceptions 11, range 3.5, record
type 3.7, scalar type 3.5, simple expression 4.4, subcomponent 3.3,
successor 3.5.5, type 3.3, type mark 3.3.2
4 - 3 4
4.5.3 Binary Adding Operators
The binary adding operators + and - are predefined for any numeric type
and have their conventional meaning. The catenation operators & are
predefined for any one-dimensional array type that is not limited.
Operator Operation Left operand type Right operand type Result type
+ addition any numeric type same numeric type same numeric type
- subtraction any numeric type same numeric type same numeric type
& catenation any array type same array type same array type
any array type the component type same array type
the component type any array type same array type
the component type the component type any array type
For real types, the accuracy of the result is determined by the operand
type (see 4.5.7).
If both operands are one-dimensional arrays, the result of the catenation
is a one-dimensional array whose length is the sum of the lengths of its
operands, and whose components comprise the components of the left operand
followed by the components of the right operand. The lower bound of this
result is the lower bound of the left operand, unless the left operand is a
null array, in which case the result of the catenation is the right
operand.
If either operand is of the component type of an array type, the result of
the catenation is given by the above rules, using in place of this operand
an array having this operand as its only component and having the lower
bound of the index subtype of the array type as its lower bound.
The exception CONSTRAINT_ERROR is raised by catenation if the upper bound
of the result exceeds the range of the index subtype, unless the result is
a null array. This exception is also raised if any operand is of the
component type but has a value that does not belong to the component
subtype.
Examples:
Z + 0.1 -- Z must be of a real type
"A" & "BCD" -- catenation of two string literals
'A' & "BCD" -- catenation of a character literal and a string literal
'A' & 'A' -- catenation of two character literals
References: array type 3.6, character literal 2.5, component type 3.3,
constraint_error exception 11.1, dimension 3.6, index subtype 3.6, length
of an array 3.6.2, limited type 7.4.4, null array 3.6.1, numeric type 3.5,
operation 3.3, operator 4.5, predefined operator 4.5, raising of exceptions
11, range of an index subtype 3.6.1, real type 3.5.6, string literal 2.6,
type 3.3
4 - 31
4.5.4 Unary Adding Operators
The unary adding operators + and - are predefined for any numeric type and
have their conventional meaning. For each of these operators, the operand
and the result have the same type.
4 - 32
Operator Operation Operand type Result type
+ identity any numeric type same numeric type
- negation any numeric type same numeric type
References: numeric type 3.5, operation 3.3, operator 4.5, predefined
operator 4.5, type 3.3
4.5.5 Multiplying Operators
The operators * and / are predefined for any integer and any floating point
type and have their conventional meaning; the operators mod and rem are
predefined for any integer type. For each of these operators, the operands
and the result have the same base type. For floating point types, the
accuracy of the result is determined by the operand type (see 4.5.7).
Operator Operation Operand type Result type
* multiplication any integer type same integer type
any floating point type same floating point type
/ integer division any integer type same integer type
floating division any floating point type same floating point type
mod modulus any integer type same integer type
rem remainder any integer type same integer type
Integer division and remainder are defined by the relation
A = (A/B)*B + (A rem B)
where (A rem B) has the sign of A and an absolute value less than the
absolute value of B. Integer division satisfies the identity
(-A)/B = -(A/B) = A/(-B)
The result of the modulus operation is such that (A mod B) has the sign of
B and an absolute value less than the absolute value of B; in addition,
for some integer value N, this result must satisfy the relation
A = B*N + (A mod B)
For each fixed point type, the following multiplication and division
operators, with an operand of the predefined type INTEGER, are predefined.
Operator Operation Left operand type Right operand type Result type
* multiplication any fixed point type INTEGER same as left
INTEGER any fixed point type same as right
4 - 33
/ division any fixed point type INTEGER same as left
4 - 34
Integer multiplication of fixed point values is equivalent to repeated
addition. Division of a fixed point value by an integer does not involve a
change in type but is approximate (see 4.5.7).
Finally, the following multiplication and division operators are declared
in the predefined package STANDARD. These two special operators apply to
operands of all fixed point types (it is a consequence of other rules that
they cannot be renamed or given as generic actual parameters).
Operator Operation Left operand type Right operand type Result type
* multiplication any fixed point type any fixed point type universal_fixed
/ division any fixed point type any fixed point type universal_fixed

Multiplication of operands of the same or of different fixed point types is
exact and delivers a result of the anonymous predefined fixed point type
universal_fixed whose delta is arbitrarily small. The result of any such
multiplication must always be explicitly converted to some numeric type.
This ensures explicit control of the accuracy of the computation. The same
considerations apply to division of a fixed point value by another fixed
point value. No other operators are defined for the type universal_fixed.
The exception NUMERIC_ERROR is raised by integer division, rem, and mod if
the right operand is zero.
Examples:
I : INTEGER := 1;
J : INTEGER := 2;
K : INTEGER := 3;
X : REAL digits 6 := 1.0; -- see 3.5.7
Y : REAL digits 6 := 2.0;
F : FRACTION delta 0. := 0.1; -- see 3.5.9
G : FRACTION delta 0. := 0.1;
Expression Value Result Type
I*J 2 same as I and J, that is, INTEGER
K/J 1 same as K and J, that is, INTEGER
K mod J 1 same as K and J, that is, INTEGER
X/Y 0.5 same as X and Y, that is, REAL
F/2 0.05 same as F, that is, FRACTION
3*F 0.3 same as F, that is, FRACTION
F*G 0.01 universal_fixed, conversion needed
FRACTION(F*G) 0.01 FRACTION, as stated by the conversion
REAL(J)*Y 4.0 REAL, the type of both operands after conversion of J
4 - 35
Notes:
For positive A and B, A/B is the quotient and A rem B is the remainder when
A is divided by B. The following relations are satisfied by the rem
operator:
A rem (-B) = A rem B
(-A) rem B = -(A rem B)
For any integer K, the following identity holds:
A mod B = (A + K*B) mod B
The relations between integer division, remainder, and modulus are
illustrated by the following table:
A B A/B A rem B A mod B A B A/B A rem B 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 8 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
References: actual parameter 6.4.1, base type 3.3, declaration 3.1, delta
of a fixed point type 3.5.9, fixed point type 3.5.9, floating point type
3.5.7, generic formal subprogram 12.1, integer type 3.5.4, numeric type
3.5, numeric_error exception 11.1, predefined operator 4.5, raising of
exceptions 11, renaming declaration 8.5, standard predefined package 8.6,
type conversion 4.6
4.5.6 Highest Precedence Operators
The highest precedence unary operator abs is predefined for any numeric
type. The highest precedence unary operator not is predefined for any
boolean type and any one-dimensional array type whose components have a
boolean type.
Operator Operation Operand type Result type
abs absolute value any numeric type same numeric type
not logical negation any boolean type same boolean type
array of boolean components same array type
4 - 36
The operator not that applies to a one-dimensional array of boolean
components yields a one-dimensional boolean array with the same bounds;
each component of the result is obtained by logical negation of the
corresponding component of the operand (that is, the component that has the
same index value).
4 - 37
The highest precedence exponentiating operator ** is predefined for each
integer type and for each floating point type. In either case the right
operand, called the exponent, is of the predefined type INTEGER.
Operator Operation Left operand type Right operand type Result type
** exponentiation any integer type INTEGER same as left
any floating point type INTEGER same as left
Exponentiation with a positive exponent is equivalent to repeated
multiplication of the left operand by itself, as indicated by the exponent
and from left to right. For an operand of a floating point type, the
exponent can be negative, in which case the value is the reciprocal of the
value with the positive exponent. Exponentiation by a zero exponent
delivers the value one. Exponentiation of a value of a floating point
type is approximate (see 4.5.7). Exponentiation of an integer raises the
exception CONSTRAINT_ERROR for a negative exponent.
References: array type 3.6, boolean type 3.5.3, bound of an array 3.6.1,
component of an array 3.6, constraint_error exception 11.1, dimensionality
3.6, floating point type 3.5.9, index 3.6, integer type 3.5.4,
multiplication operation 4.5.5, predefined operator 4.5, raising of
exceptions 11
4.5.7 Accuracy of Operations with Real Operands
A real subtype specifies a set of model numbers. Both the accuracy
required from any basic or predefined operation giving a real result, and
the result of any predefined relation between real operands are defined in
terms of these model numbers.
A model interval of a subtype is any interval whose bounds are model
numbers of the subtype. The model interval associated with a value that
belongs to a real subtype is the smallest model interval (of the subtype)
that includes the value. (The model interval associated with a model
number of a subtype consists of that number only.)
For any basic operation or predefined operator that yields a result of a
real subtype, the required bounds on the result are given by a model
interval defined as follows:
- The result model interval is the smallest model interval (of the
result subtype) that includes the minimum and the maximum of all the
values obtained by applying the (exact) mathematical operation, when
each operand is given any value of the model interval (of the operand
subtype) defined for the operand.
- The model interval of an operand that is itself the result of an
operation, other than an implicit conversion, is the result model
interval of this operation.
4 - 38
- The model interval of an operand whose value is obtained by implicit
conversion of a universal expression is the model interval associated
with this value within the operand subtype.
The result model interval is undefined if the absolute value of one of the
above mathematical results exceeds the largest safe number of the result
type. Whenever the result model interval is undefined, it is highly
desirable that the exception NUMERIC_ERROR be raised if the implementation
cannot produce an actual result that is in the range of safe numbers. This
is, however, not required by the language rules, in recognition of the fact
that certain target machines do not permit easy detection of overflow
situations. The value of the attribute MACHINE_OVERFLOWS indicates whether
the target machine raises the exception NUMERIC_ERROR in overflow
situations (see 13.7.3).
4 - 39
The safe numbers of a real type are defined (see 3.5.6) as a superset of
the model numbers, for which error bounds follow the same rules as for
model numbers. Any definition given in this section in terms of model
intervals can therefore be extended to safe intervals of safe numbers. A
consequence of this extension is that an implementation is not allowed to
raise the exception NUMERIC_ERROR when the result interval is a safe
interval.
For the result of exponentiation, the model interval defining the bounds on
the result is obtained by applying the above rules to the sequence of
multiplications defined by the exponent, and to the final division in the
case of a negative exponent.
For the result of a relation between two real operands, consider for each
operand the model interval (of the operand subtype) defined for the
operand; the result can be any value obtained by applying the mathematical
comparison to values arbitrarily chosen in the corresponding operand model
intervals. If either or both of the operand model intervals is undefined
(and if neither of the operand evaluations raises an exception) then the
result of the comparison is allowed to be any possible value (that is,
either TRUE or FALSE).
The result of a membership test is defined in terms of comparisons of the
operand value with the lower and upper bounds of the given range or type
mark (the usual rules apply to these comparisons). Note:
For a floating point type the numbers 15.0, 3.0, and 5.0 are always model
numbers. Hence X/Y where X equals 15.0 and Y equals 3.0 yields exactly 5. 9according to the above rules. In the general case, division does not yield
model numbers and in consequence one cannot assume that (1.0/X)*X = 1.0.
References: attribute 4.1.4, basic operation 3.3.3, bound of a range 3.5,
error bound 3.5.6, exponentiation operation 4.5.6, false boolean value
3.5.3, floating point type 3.5.9, machine_overflows attribute 13.7.1,
membership test 4.5.2, model number 3.5.6, multiplication operation 4.5.5,
numeric_error exception 11.1, predefined operation 3.3.3, raising of
exceptions 11, range 3.5, real type 3.5.6, relation 4.4, relational
operator 4.5.2 4.5, safe number 3.5.6, subtype 3.3, true boolean value
3.5.3, type conversion 4.6, type mark 3.3.2, universal expression 4.1 4
4.6 Type Conversions
The evaluation of an explicit type conversion evaluates the expression
given as the operand, and converts the resulting value to a specified
target type. Explicit type conversions are allowed between closely related
types as defined below.
type_conversion ::= type_mark(expression)
4 - 4 4
The target type of a type conversion is the base type of the type mark.
The type of the operand of a type conversion must be determinable
independently of the context (in particular, independently of the target
type). Furthermore, the operand of a type conversion is not allowed to be
a literal null, an allocator, an aggregate, or a string literal; an
expression enclosed by parentheses is allowed as the operand of a type
conversion only if the expression alone is allowed.
A conversion to a subtype consists of a conversion to the target type
followed by a check that the result of the conversion belongs to the
subtype. A conversion of an operand of a given type to the type itself is
allowed.
4 - 41
The other allowed explicit type conversions correspond to the following
three cases:
(a) Numeric types
The operand can be of any numeric type; the value of the operand is
converted to the target type which must also be a numeric type. For
conversions involving real types, the result is within the accuracy of
the specified subtype (see 4.5.7). The conversion of a real value to
an integer type rounds to the nearest integer; if the operand is
halfway between two integers (within the accuracy of the real subtype)
rounding may be either up or down.
(b) Derived types
The conversion is allowed if one of the target type and the operand
type is derived from the other, directly or indirectly, or if there
exists a third type from which both types are derived, directly or
indirectly.
(c) Array types
The conversion is allowed if the operand type and the target type are
array types that satisfy the following conditions: both types must
have the same dimensionality; for each index position the index types
must either be the same or be convertible to each other; the
component types must be the same; finally, if the component type is a
type with discriminants or an access type, the component subtypes must
be either both constrained or both unconstrained. If the type mark
denotes an unconstrained array type, then, for each index position,
the bounds of the result are obtained by converting the bounds of the
operand to the corresponding index type of the target type. If the
type mark denotes a constrained array subtype, then the bounds of the
result are those imposed by the type mark. In either case, the value
of each component of the result is that of the matching component of
the operand (see 4.5.2).
In the case of conversions of numeric types and derived types, the
exception CONSTRAINT_ERROR is raised by the evaluation of a type conversion
if the result of the conversion fails to satisfy a constraint imposed by
the type mark.
In the case of array types, a check is made that any constraint on the
component subtype is the same for the operand array type as for the target
array type. If the type mark denotes an unconstrained array type and if
the operand is not a null array, then, for each index position, a check is
made that the bounds of the result belong to the corresponding index
subtype of the target type. If the type mark denotes a constrained array
subtype, a check is made that for each component of the operand there is a
matching component of the target subtype, and vice versa. The exception
CONSTRAINT_ERROR is raised if any of these checks fails.
If a conversion is allowed from one type to another, the reverse conversion
is also allowed. This reverse conversion is used where an actual parameter
of mode in out or out has the form of a type conversion of a (variable)
4 - 42
name as explained in section 6.4.1.
Apart from the explicit type conversions, the only allowed form of type
conversion is the implicit conversion of a value of the type
universal_integer or universal_real into another numeric type. An implicit
conversion of an operand of type universal_integer to another integer type,
or of an operand of type universal_real to another real type, can only be
applied if the operand is either a numeric literal, a named number, or an
attribute; such an operand is called a convertible universal operand in
this section. An implicit conversion of a convertible universal operand is
applied if and only if the innermost complete context (see 8.7) determines
a unique (numeric) target type for the implicit conversion, and there is no
legal interpretation of this context without this conversion.
4 - 43
Notes:
The rules for implicit conversions imply that no implicit conversion is
ever applied to the operand of an explicit type conversion. Similarly,
implicit conversions are not applied if both operands of a predefined
relational operator are convertible universal operands.
The language allows implicit subtype conversions in the case of array types
(see 5.2.1). An explicit type conversion can have the effect of a change
of representation (in particular see 13.6). Explicit conversions are also
used for actual parameters (see 6.4).
Examples of numeric type conversion:
REAL(2*J) -- value is converted to floating point
INTEGER(1.6) -- value is 2
INTEGER(-0.4) -- value is 4
Example of conversion between derived types:
type A_FORM is new B_FORM;
X : A_FORM;
Y : B_FORM;
X := A_FORM(Y);
Y := B_FORM(X); -- the reverse conversion
Examples of conversions between array types:
type SEQUENCE is array (INTEGER range <>) of INTEGER;
subtype DOZEN is SEQUENCE(1 .. 12);
LEDGER : array(1 .. 1
of INTEGER;
SEQUENCE(LEDGER) -- bounds are those of LEDGER
SEQUENCE(LEDGER(31 .. 42)) -- bounds are 31 and 42
DOZEN(LEDGER(31 .. 42)) -- bounds are those of DOZEN
Examples of implicit conversions:
X : INTEGER := 2;
X + 1 + 2 -- implicit conversion of each integer literal
1 + 2 + X -- implicit conversion of each integer literal
X + (1 + 2) -- implicit conversion of each integer literal
2 = (1 + 1) -- no implicit conversion: the type is universal_integer
A'LENGTH = B'LENGTH -- no implicit conversion: the type is universal_integer
C : constant := 3 + 2; -- no implicit conversion: the type is universal_integer
X = 3 and 1 = 2 -- implicit conversion of 3, but not of 1 and 2
References: actual parameter 6.4.1, array type 3.6, attribute 4.1.4, base
type 3.3, belong to a subtype 3.3, component 3.3, constrained array subtype
3.6, constraint_error exception 11.1, derived type 3.4, dimension 3.6,
4 - 44
expression 4.4, floating point type 3.5.7, index 3.6, index subtype 3.6,
index type 3.6, integer type 3.5.4, matching component 4.5.2, mode 6.1,
name 4.1, named number 3.2, null array 3.6.1, numeric literal 2.4, numeric
type 3.5, raising of exceptions 11, real type 3.5.6, representation 13.1,
statement 5, subtype 3.3, type 3.3, type mark 3.3.2, unconstrained array
type 3.6, universal_integer type 3.5.4, universal_real type 3.5.6, variable 3.2.1
4 - 45
4.7 Qualified Expressions
A qualified expression is used to state explicitly the type, and possibly
the subtype, of an operand that is the given expression or aggregate.
qualified_expression ::=
type_mark'(expression) | type_mark'aggregate
The operand must have the same type as the base type of the type mark. The
value of a qualified expression is the value of the operand. The
evaluation of a qualified expression evaluates the operand and checks that
its value belongs to the subtype denoted by the type mark. The exception
CONSTRAINT_ERROR is raised if this check fails.
Examples:
type MASK is (FIX, DEC, EXP, SIGNIF);
type CODE is (FIX, CLA, DEC, TNZ, SUB);
PRINT (MASK'(DEC)); -- DEC is of type MASK
PRINT (CODE'(DEC)); -- DEC is of type CODE
for J in CODE'(FIX) .. CODE'(DEC) loop ... -- qualification needed for either FIX or DEC
for J in CODE range FIX .. DEC loop ... -- qualification unnecessary
for J in CODE'(FIX) .. DEC loop ... -- qualification unnecessary for DEC
DOZEN'(1 | 3 | 5 | 7 => 2, others => 0) -- see 4.6
Notes:
Whenever the type of an enumeration literal or aggregate is not known from
the context, a qualified expression can be used to state the type
explicitly. For example, an overloaded enumeration literal must be
qualified in the following cases: when given as a parameter in a
subprogram call to an overloaded subprogram that cannot otherwise be
identified on the basis of remaining parameter or result types, in a
relational expression where both operands are overloaded enumeration
literals, or in an array or loop parameter range where both bounds are
overloaded enumeration literals. Explicit qualification is also used to
specify which one of a set of overloaded parameterless functions is meant,
or to constrain a value to a given subtype.
References: aggregate 4.3, array 3.6, base type 3.3, bound of a range 3.5,
constraint_error exception 11.1, context of overload resolution 8.7,
enumeration literal 3.5.1, expression 4.4, function 6.5, loop parameter
5.5, overloading 8.5, raising of exceptions 11, range 3.3, relation 4.4,
subprogram 6, subprogram call 6.4, subtype 3.3, type 3.3, type mark 3.3.2
4.8 Allocators
4 - 46
The evaluation of an allocator creates an object and yields an access value
that designates the object.
allocator ::=
new subtype_indication | new qualified_expression
4 - 47
The type of the object created by an allocator is the base type of the type
mark given in either the subtype indication or the qualified expression.
For an allocator with a qualified expression, this expression defines the
initial value of the created object. The type of the access value returned
by an allocator must be determinable solely from the context, but using the
fact that the value returned is of an access type having the named
designated type.
The only allowed forms of constraint in the subtype indication of an
allocator are index and discriminant constraints. If an allocator includes
a subtype indication and if the type of the object created is an array type
or a type with discriminants that do not have default expressions, then the
subtype indication must either denote a constrained subtype, or include an
explicit index or discriminant constraint.
If the type of the created object is an array type or a type with
discriminants, then the created object is always constrained. If the
allocator includes a subtype indication, the created object is constrained
either by the subtype or by the default discriminant values. If the
allocator includes a qualified expression, the created object is
constrained by the bounds or discriminants of the initial value. For other
types, the subtype of the created object is the subtype defined by the
subtype indication of the access type definition.
For the evaluation of an allocator, the elaboration of the subtype
indication or the evaluation of the qualified expression is performed
first. The new object is then created. Initializations are then performed
as for a declared object (see 3.2.1); the initialization is considered
explicit in the case of a qualified expression; any initializations are
implicit in the case of a subtype indication. Finally, an access value
that designates the created object is returned.
An implementation must guarantee that any object created by the evaluation
of an allocator remains allocated for as long as this object or one of its
subcomponents is accessible directly or indirectly, that is, as long as it
can be denoted by some name. Moreover, if an object or one of its
subcomponents belongs to a task type, it is considered to be accessible as
long as the task is not terminated. An implementation may (but need not)
reclaim the storage occupied by an object created by an allocator, once
this object has become inaccessible.
When an application needs closer control over storage allocation for
objects designated by values of an access type, such control may be
achieved by one or more of the following means:
(a) The total amount of storage available for the collection of objects of
an access type can be set by means of a length clause (see 13.2).
(b) The pragma CONTROLLED informs the implementation that automatic
storage reclamation must not be performed for objects designated by
values of the access type, except upon leaving the innermost block
statement, subprogram body, or task body that encloses the access type
declaration, or after leaving the main program.
4 - 48
pragma CONTROLLED (access_type_simple_name);
A pragma CONTROLLED for a given access type is allowed at the same
places as a representation clause for the type (see 13.1). This
pragma is not allowed for a derived type.
(c) The explicit deallocation of the object designated by an access value
can be achieved by calling a procedure obtained by instantiation of
the predefined generic library procedure UNCHECKED_DEALLOCATION (see
13.10.1).
The exception STORAGE_ERROR is raised by an allocator if there is not
enough storage. Note also that the exception CONSTRAINT_ERROR can be
raised by the evaluation of the qualified expression, by the elaboration of
the subtype indication, or by the initialization.
4 - 49
Examples (for access types declared in section 3.8):
new CELL'(0, null, null) -- initialized explicitly
new CELL'(VALUE => 0, SUCC => null, PRED => null) -- initialized explicitly
new CELL -- not initialized
new MATRIX(1 .. 10, 1 .. 20) -- the bounds only are given
new MATRIX'(1 .. 10 => (1 .. 20 => 0.0)) -- initialized explicitly
new BUFFER(1
-- the discriminant only is given
new BUFFER'(SIZE => 80, POS => 0, VALUE => (1 .. 80 => 'A')) -- initialized explicitly
References: access type 3.8, access type definition 3.8, access value 3.8,
array type 3.6, block statement 5.6, bound of an array 3.6.1, collection
3.8, constrained subtype 3.3, constraint 3.3, constraint_error exception
11.1, context of overload resolution 8.7, derived type 3.4, designate 3.8,
discriminant 3.3, discriminant constraint 3.7.2, elaboration 3.9,
evaluation of a qualified expression 4.7, generic procedure 12.1, index
constraint 3.6.1, initial value 3.2.1, initialization 3.2.1, instantiation
12.3, length clause 13.2, library unit 10.1, main program 10.1, name 4.1,
object 3.2.1, object declaration 3.2.1, pragma 2.8, procedure 6, qualified
expression 4.7, raising of exceptions 11, representation clause 13.1,
simple name 4.1, storage_error exception 11.1, subcomponent 3.3, subprogram
body 6.3, subtype 3.3, subtype indication 3.3.2, task body 9.1, task type
9.2, terminated task 9.4, type 3.3, type declaration 3.3.1, type mark 3.3.2
type with discriminants 3.3
4.9 Static Expressions and Static Subtypes
Certain expressions of a scalar type are said to be static. Similarly,
certain discrete ranges are said to be static, and the type marks of
certain scalar subtypes are said to denote static subtypes.
An expression of a scalar type is said to be static if and only if every
primary is one of those listed in (a) through (h) below, every operator
denotes a predefined operator, and the evaluation of the expression
delivers a value (that is, it does not raise an exception):
(a) An enumeration literal (including a character literal).
(b) A numeric literal.
(c) A named number.
(d) A constant explicitly declared by a constant declaration with a static
subtype, and initialized with a static expression.
(e) A function call whose function name is an operator symbol that denotes
a predefined operator, including a function name that is an expanded
name; each actual parameter must also be a static expression.
4 - 5 4
(f) A language-defined attribute of a static subtype; for an attribute
that is a function, the actual parameter must also be a static
expression.
4 - 51
(g) A qualified expression whose type mark denotes a static subtype and
whose operand is a static expression.
(h) A static expression enclosed in parentheses.
A static range is a range whose bounds are static expressions. A static
range constraint is a range constraint whose range is static. A static
subtype is either a scalar base type, other than a generic formal type; or
a scalar subtype formed by imposing on a static subtype either a static
range constraint, or a floating or fixed point constraint whose range
constraint, if any, is static. A static discrete range is either a static
subtype or a static range. A static index constraint is an index
constraint for which each index subtype of the corresponding array type is
static, and in which each discrete range is static. A static discriminant
constraint is a discriminant constraint for which the subtype of each
discriminant is static, and in which each expression is static.
Notes:
The accuracy of the evaluation of a static expression having a real type is
defined by the rules given in section 4.5.7. If the result is not a model
number (or a safe number) of the type, the value obtained by this
evaluation at compilation time need not be the same as the value that would
be obtained by an evaluation at run time.
Array attributes are not static: in particular, the RANGE attribute is not
static.
References: actual parameter 6.4.1, attribute 4.1.4, base type 3.3, bound
of a range 3.5, character literal 2.5, constant 3.2.1, constant declaration
3.2.1, discrete range 3.6, discrete type 3.5, enumeration literal 3.5.1,
exception 11, expression 4.4, function 6.5, generic actual parameter 12.3,
generic formal type 12.1.2, implicit declaration 3.1, initialize 3.2.1,
model number 3.5.6, named number 3.2, numeric literal 2.4, predefined
operator 4.5, qualified expression 4.7, raising of exceptions 11, range
constraint 3.5, safe number 3.5.6, scalar type 3.5, subtype 3.3, type mark 3.3.2
4.10 Universal Expressions
A universal_expression is either an expression that delivers a result of
type universal_integer or one that delivers a result of type
universal_real.
The same operations are predefined for the type universal_integer as for
any integer type. The same operations are predefined for the type
universal_real as for any floating point type. In addition, these
operations include the following multiplication and division operators:
Operator Operation Left operand type Right operand type Result type
4 - 52
* multiplication universal_real universal_integer universal_real
universal_integer universal_real universal_real
/ division universal_real universal_integer universal_real
The accuracy of the evaluation of a universal expression of type
universal_real is at least as good as that of the most accurate predefined
floating point type supported by the implementation, apart from
universal_real itself. Furthermore, if a universal expression is a static
expression, then the evaluation must be exact.
4 - 53
For the evaluation of an operation of a nonstatic universal expression, an
implementation is allowed to raise the exception NUMERIC_ERROR only if the
result of the operation is a real value whose absolute value exceeds the
largest safe number of the most accurate predefined floating point type
(excluding universal_real), or an integer value greater than SYSTEM.MAX_INT
or less than SYSTEM.MIN_INT. Note:
It is a consequence of the above rules that the type of a universal
expression is universal_integer if every primary contained in the
expression is of this type (excluding actual parameters of attributes that
are functions, and excluding right operands of exponentiation operators)
and that otherwise the type is universal_real.
Examples:
1 + 1 -- 2
abs(-10)*3 -- 3 4
KILO : constant := 1
MEGA : constant := KILO*KILO; -- 1_ 042 LONG : constant := FLOAT'DIGITS*2;
HALF_PI : constant := PI/2; -- see 3.2.2
DEG_TO_RAD : constant := HALF_PI/90;
RAD_TO_DEG : constant := 1.0/DEG_TO_RAD; -- equivalent to 1.0/((3.14159_26536/2)/90)
References: actual parameter 6.4.1, attribute 4.1.4, evaluation of an
expression 4.5, floating point type 3.5.9, function 6.5, integer type
3.5.4, multiplying operator 4.5 4.5.5, predefined operation 3.3.3, primary
4.4, real type 3.5.6, safe number 3.5.6, system.max_int 13.7,
system.min_int 13.7, type 3.3, universal_integer type 3.5.4, universal_real
type 3.5.6
4 - 54




  3 Responses to “Category : Miscellaneous Language Source Code
Archive   : ADAREF.ZIP
Filename : LRM-04.DOC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/