DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: C T

⟦d706d3606⟧ TextFile

    Length: 142391 (0x22c37)
    Types: TextFile
    Names: »CHAPTER_3«

Derivation

└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
    └─⟦5cb1d1d7f⟧ »DATA« 
        └─⟦3b1ee7bd8⟧ 
            └─⟦this⟧ 

TextFile

                         3. Declarations and Types



This  chapter  describes  the  types  in  the  language  and  the rules for
declaring constants, variables, and named numbers.



3.1  Declarations


The language defines several kinds of entities that  are  declared,  either
explicitly or implicitly, by declarations.  Such an entity can be a numeric
literal,  an  object, a discriminant, a record component, a loop parameter,
an exception, a type, a subtype, a subprogram, a package, a  task  unit,  a
generic  unit,  a  single  entry, an entry family, a formal parameter (of a
subprogram, entry, or generic subprogram), a generic  formal  parameter,  a
named  block  or loop, a labeled statement, or an operation (in particular,
an attribute or an enumeration literal;  see 3.3.3).

There are several forms of declaration.  A basic declaration is a  form  of
declaration defined as follows.

    basic_declaration ::=
         object_declaration     | number_declaration
       | type_declaration       | subtype_declaration
       | subprogram_declaration | package_declaration
       | task_declaration       | generic_declaration
       | exception_declaration  | generic_instantiation
       | renaming_declaration   | deferred_constant_declaration

Certain  forms  of declaration always occur (explicitly) as part of a basic
declaration;   these  forms  are  discriminant  specifications,   component
declarations,   entry   declarations,   parameter  specifications,  generic
parameter declarations, and enumeration  literal  specifications.   A  loop
parameter  specification  is  a  form  of  declaration  that occurs only in
certain forms of loop statement.

The remaining forms of declaration are implicit:  the name of a block,  the
name  of  a  loop,  and a statement label are implicitly declared.  Certain
operations are implicitly declared (see 3.3.3).

For each form of declaration the language rules define a certain region  of
text  called  the  scope  of  the  declaration (see 8.2).  Several forms of
declaration associate an identifier with a  declared  entity.   Within  its
scope,  and  only  there,  there are places where it is possible to use the
identifier to refer to the associated declared entity;   these  places  are
defined  by  the visibility rules (see 8.3).  At such places the identifier
is said to be a name of the entity (its simple name);  the name is said  to


                                   3 - 1








denote the associated entity.

Certain  forms  of  enumeration literal specification associate a character
literal  with  the  corresponding  declared  entity.   Certain   forms   of
declaration  associate  an  operator  symbol or some other notation with an
explicitly or implicitly declared operation.

The process by which a  declaration  achieves  its  effect  is  called  the
elaboration  of  the  declaration;   this  process  happens  during program
execution.















































                                   3 - 2








After its elaboration, a declaration is said to be  elaborated.   Prior  to
the  completion  of its elaboration (including before the elaboration), the
declaration is not yet elaborated.  The elaboration of any declaration  has
always  at least the effect of achieving this change of state (from not yet
elaborated to elaborated).   The  phrase  "the  elaboration  has  no  other
effect"  is  used  in this manual whenever this change of state is the only
effect of elaboration for some form of declaration.  An elaboration process
is also defined for declarative parts, declarative items,  and  compilation
units (see 3.9 and 10.5).

Object,  number,  type,  and  subtype declarations are described here.  The
remaining basic declarations are described in later chapters.

Note:

The syntax rules use the term identifier for the  first  occurrence  of  an
identifier  in  some form of declaration;  the term simple name is used for
any occurrence of an identifier that already denotes some declared  entity.

References:    attribute  4.1.4,  block  name  5.6,  block  statement  5.6,
character literal 2.5, component declaration  3.7,  declarative  item  3.9,
declarative  part  3.9,  deferred  constant  declaration  7.4, discriminant
specification 3.7.1, elaboration 3.9, entry  declaration  9.5,  enumeration
literal   specification   3.5.1,   exception   declaration   11.1,  generic
declaration 12.1, generic instantiation 12.3, generic parameter declaration
12.1,  identifier  2.3,  label  5.1,  loop   name   5.5,   loop   parameter
specification  5.5, loop statement 5.5, name 4.1, number declaration 3.2.2,
numeric literal 2.4, object  declaration  3.2.1,  operation  3.3,  operator
symbol  6.1,  package  declaration 7.1, parameter specification 6.1, record
component 3.7, renaming declaration 8.5, representation clause 13.1,  scope
8.2,  simple  name  4.1,  subprogram  body 6.3, subprogram declaration 6.1,
subtype declaration 3.3.2, task declaration 9.1,  type  declaration  3.3.1,
visibility 8.3



3.2  Objects and Named Numbers


An  object  is  an  entity that contains (has) a value of a given type.  An
object is one of the following:

  -  an object declared by an  object  declaration  or  by  a  single  task
     declaration,

  -  a formal parameter of a subprogram, entry, or generic subprogram,

  -  a generic formal object,

  -  a loop parameter,

  -  an object designated by a value of an access type,

  -  a component or a slice of another object.



                                   3 - 3








A  number  declaration  is  a  special  form  of  object  declaration  that
associates  an  identifier  with  a  value  of  type  universal_integer  or
universal_real.

    object_declaration ::=
         identifier_list : [constant] subtype_indication [:= expression];
       | identifier_list : [constant] constrained_array_definition [:= expression];

    number_declaration ::=
         identifier_list : constant := universal_static_expression;

    identifier_list ::=  identifier {, identifier}













































                                   3 - 4








An  object  declaration  is  called  a  single  object  declaration  if its
identifier list has a single identifier;  it is called  a  multiple  object
declaration if the identifier list has two or more identifiers.  A multiple
object  declaration is equivalent to a sequence of the corresponding number
of single object declarations.   For  each  identifier  of  the  list,  the
equivalent  sequence  has  a  single  object  declaration  formed  by  this
identifier, followed by a colon and by whatever appears at the right of the
colon in the multiple object declaration;  the equivalent  sequence  is  in
the same order as the identifier list.

A  similar  equivalence  applies  also  for  the identifier lists of number
declarations,   component   declarations,   discriminant    specifications,
parameter   specifications,   generic   parameter  declarations,  exception
declarations, and deferred constant declarations.

In the remainder of this  reference  manual,  explanations  are  given  for
declarations  with a single identifier;  the corresponding explanations for
declarations with several identifiers follow from  the  equivalence  stated
above.

Example:

    --  the multiple object declaration

    JOHN, PAUL : PERSON_NAME := new PERSON(SEX => M);  --  see 3.8.1

    --  is equivalent to the two single object declarations in the order given

    JOHN : PERSON_NAME := new PERSON(SEX => M);
    PAUL : PERSON_NAME := new PERSON(SEX => M);

References:   access  type 3.8, constrained array definition 3.6, component
3.3, declaration 3.1, deferred constant  declaration  7.4,  designate  3.8,
discriminant  specification  3.7.1,  entry 9.5, exception declaration 11.1,
expression 4.4, formal parameter 6.1, generic formal object 12.1.1, generic
parameter declaration 12.1,  generic  unit  12,  generic  subprogram  12.1,
identifier   2.3,   loop   parameter   5.5,  numeric  type  3.5,  parameter
specification 6.1, scope 8.2, simple name 4.1, single task declaration 9.1,
slice 4.1.2, static expression 4.9, subprogram 6, subtype indication 3.3.2,
type 3.3, universal_integer type 3.5.4, universal_real type 3.5.6



3.2.1  Object Declarations


An object declaration declares an object whose type is given  either  by  a
subtype  indication  or  by  a constrained array definition.  If the object
declaration includes the  assignment  compound  delimiter  followed  by  an
expression,  the  expression  specifies  an  initial value for the declared
object;  the type of the expression must be that of the object.

The declared object is a constant if the reserved word constant appears  in
the  object  declaration;   the  declaration  must then include an explicit
initialization.   The  value  of  a  constant  cannot  be  modified   after


                                   3 - 5








initialization.   Formal  parameters of mode in of subprograms and entries,
and generic formal parameters of mode  in,  are  also  constants;   a  loop
parameter  is  a constant within the corresponding loop;  a subcomponent or
slice of a constant is a constant.

An object that is not a constant is called a variable (in  particular,  the
object declared by an object declaration that does not include the reserved
word  constant  is  a  variable).   The  only ways to change the value of a
variable are either directly by  an  assignment,  or  indirectly  when  the
variable  is updated (see 6.2) by a procedure or entry call statement (this
action can be performed either on the variable itself, on a subcomponent of
the variable, or on  another  variable  that  has  the  given  variable  as
subcomponent).












































                                   3 - 6









The elaboration of an object declaration proceeds as follows:

(a)  The subtype indication or the constrained array  definition  is  first
     elaborated.  This establishes the subtype of the object.

(b)  If the object declaration includes  an  explicit  initialization,  the
     initial value  is obtained by evaluating the corresponding expression.
     Otherwise  any  implicit  initial  values  for  the  object or for its
     subcomponents are evaluated.

(c)  The object is created.

(d)  Any initial value (whether explicit or implicit) is  assigned  to  the
     object or to the corresponding subcomponent.

Implicit  initial  values  are  defined  for  objects  declared  by  object
declarations, and for components of such objects, in the  following  cases:

  -  If the type of an object is an access type, the implicit initial value
     is the null value of the access type.

  -  If the type of an object is a task type,  the  implicit  initial  (and
     only) value designates a corresponding task.

  -  If the type of an object is a type with discriminants and the  subtype
     of the object is constrained, the implicit initial (and only) value of
     each discriminant is defined by the subtype of the object.

  -  If the type of an object is a composite  type,  the  implicit  initial
     value  of  each component that has a default expression is obtained by
     evaluation of this expression, unless the component is a  discriminant
     of a constrained object (the previous case).

In  the  case  of  a  component that is itself a composite object and whose
value is defined neither by an explicit initialization  nor  by  a  default
expression,  any  implicit  initial  values for components of the composite
object are defined by the same rules as for a declared object.

The steps (a) to (d) are performed in the order indicated.  For  step  (b),
if  the  default  expression  for  a  discriminant  is evaluated, then this
evaluation  is  performed  before   that   of   default   expressions   for
subcomponents that depend on discriminants, and also before that of default
expressions  that  include  the  name  of the discriminant.  Apart from the
previous rule, the evaluation of default expressions is performed  in  some
order that is not defined by the language.

The  initialization  of  an  object  (the  declared  object  or  one of its
subcomponents) checks that the initial value belongs to the subtype of  the
object;  for an array object declared by an object declaration, an implicit
subtype  conversion is first applied as for an assignment statement, unless
the object is a constant whose subtype is an unconstrained array type.  The
exception CONSTRAINT_ERROR is raised if this check fails.




                                   3 - 7








The value of a scalar  variable  is  undefined  after  elaboration  of  the
corresponding object declaration unless an initial value is assigned to the
variable by an initialization (explicitly or implicitly).

If  the  operand of a type conversion or qualified expression is a variable
that has scalar subcomponents with undefined values, then the values of the
corresponding subcomponents of the result are undefined.  The execution  of
a  program  is erroneous if it attempts to evaluate  a scalar variable with
an undefined value.  Similarly, the execution of a program is erroneous  if
it  attempts to apply a predefined operator to a variable that has a scalar
subcomponent with an undefined value.














































                                   3 - 8








Examples of variable declarations:

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

Examples of constant declarations:

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

Note:

The expression  initializing  a  constant  object  need  not  be  a  static
expression  (see  4.9).   In  the  above  examples, LIMIT and LOW_LIMIT are
initialized with static expressions, but TOLERANCE is not if DISPERSION  is
a user-defined function.

References:  access type 3.8, assignment 5.2, assignment compound delimiter
5.2,  component  3.3, composite type 3.3, constrained array definition 3.6,
constrained subtype 3.3, constraint_error exception 11.1,  conversion  4.6,
declaration 3.1, default expression for a discriminant 3.7, default initial
value  for  an  access  type 3.8, depend on a discriminant 3.7.1, designate
3.8,  discriminant  3.3,  elaboration  3.9,  entry  9.5,  evaluation   4.5,
expression  4.4,  formal parameter 6.1, generic formal parameter 12.1 12.3,
generic unit 12, in some order  1.6,  limited  type  7.4.4,  mode  in  6.1,
package  7,  predefined  operator  4.5,  primary  4.4,  private  type  7.4,
qualified expression 4.7, reserved word 2.9, scalar type 3.5, slice  4.1.2,
subcomponent 3.3, subprogram 6, subtype 3.3, subtype indication 3.3.2, task
9, task type 9.2, type 3.3, visible part 7.2



3.2.2  Number Declarations


A  number  declaration is a special form of constant declaration.  The type
of  the  static  expression  given  for  the  initialization  of  a  number
declaration   must  be  either  the  type  universal_integer  or  the  type
universal_real.  The constant declared by a number declaration is called  a
named number and has the type of the static expression.

Note:

The  rules  concerning  expressions  of  a  universal type are explained in
section 4.10.  It is a consequence of these rules  that  if  every  primary
contained  in  the  expression  is  of the type universal_integer, then the
named number is also of this type.  Similarly, if every primary is  of  the
type universal_real, then the named number is also of this type.

Examples of number declarations:



                                   3 - 9








    PI            : constant := 3.14159_26536; -- a real number
    TWO_PI        : constant := 2.0*PI;        -- a real number
    MAX           : constant := 500;           -- an integer number
    POWER_16      : constant := 2**16;         -- the integer 65_536
    ONE, UN, EINS : constant := 1;             -- three different names for 1


References:   identifier 2.3, primary 4.4, static expression 4.9, type 3.3,
universal_integer type 3.5.4, universal_real  type  3.5.6,  universal  type
4.10















































                                  3 - 10








3.3  Types and Subtypes


A type is characterized by a set of values and a set of operations.

There exist several classes of types.  Scalar types are integer types, real
types,  and  types defined by enumeration of their values;  values of these
types have no components.   Array and record types are composite;  a  value
of a composite type consists of component values.  An access type is a type
whose  values provide access to objects.  Private types are types for which
the set of possible values is well defined, but not directly  available  to
the  users  of  such types.  Finally, there are task types.  (Private types
are described in chapter 7, task types are  described  in  chapter  9,  the
other classes of types are described in this chapter.)

Certain   record   and   private   types  have  special  components  called
discriminants whose values distinguish alternative forms of values  of  one
of  these  types.   If  a private type has discriminants, they are known to
users of the type.  Hence a private type is only known  by  its  name,  its
discriminants if any, and by the corresponding set of operations.

The  set  of possible values for an object of a given type can be subjected
to a condition that is called a constraint (the case where  the  constraint
imposes  no  restriction  is  also included);  a value is said to satisfy a
constraint if it satisfies the corresponding condition.   A  subtype  is  a
type together with a constraint;  a value is said to belong to a subtype of
a  given  type if it belongs to the type and satisfies the constraint;  the
given type is called the base type of the subtype.  A type is a subtype  of
itself;   such  a subtype is said to be unconstrained:  it corresponds to a
condition that imposes no restriction.  The base type of a type is the type
itself.

The set of operations defined for a subtype of a given  type  includes  the
operations that are defined for the type;  however the assignment operation
to a variable having a given subtype only assigns values that belong to the
subtype.   Additional  operations,  such  as  qualification (in a qualified
expression), are implicitly defined by a subtype declaration.

Certain types have default initial values defined for objects of the  type;
certain  other  types  have  default expressions defined for some or all of
their components.  Certain operations of  types  and  subtypes  are  called
attributes;   these operations are denoted by the form of name described in
section 4.1.4.

The term subcomponent is used in this manual in place of the term component
to indicate either a component, or a  component  of  another  component  or
subcomponent.   Where  other subcomponents are excluded, the term component
is used instead.

A given type must not have a subcomponent whose  type  is  the  given  type
itself.

The  name  of  a  class  of types is used in this manual as a qualifier for
objects and values that have a type of the class considered.  For  example,
the  term "array object" is used for an object whose type is an array type;


                                  3 - 11








similarly, the term "access value" is used for a value of an  access  type.

Note:

The  set of values of a subtype is a subset of the values of the base type.
This subset need not be a proper subset;  it can be an empty subset.

References:  access type 3.8, array type  3.6,  assignment  5.2,  attribute
4.1.4,  component  of an array 3.6, component of a record 3.7, discriminant
constraint 3.7.2, enumeration type 3.5.1, integer type 3.5.4, object 3.2.1,
private type 7.4, qualified expression 4.7, real type  3.5.6,  record  type
3.7, subtype declaration 3.3.2, task type 9.1, type declaration 3.3.1













































                                  3 - 12








3.3.1  Type Declarations


A type declaration declares a type.

    type_declaration ::=  full_type_declaration
       | incomplete_type_declaration | private_type_declaration

    full_type_declaration ::=
         type identifier [discriminant_part] is type_definition;

    type_definition ::=
         enumeration_type_definition | integer_type_definition
       | real_type_definition        | array_type_definition
       | record_type_definition      | access_type_definition
       | derived_type_definition

The  elaboration  of a full type declaration consists of the elaboration of
the discriminant part, if  any  (except  in  the  case  of  the  full  type
declaration  for  an  incomplete  or  private type declaration), and of the
elaboration of the type definition.

The types created by the  elaboration  of  distinct  type  definitions  are
distinct  types.   Moreover,  the  elaboration of the type definition for a
numeric or derived type creates both a base type and a subtype of the  base
type;   the  same  holds for a constrained array definition (one of the two
forms of array type definition).

The simple name declared by a full type declaration  denotes  the  declared
type,  unless  the type declaration declares both a base type and a subtype
of the base type, in which case the simple name denotes  the  subtype,  and
the  base  type  is anonymous.  A type is said to be anonymous if it has no
simple name.  For explanatory purposes,  this  reference  manual  sometimes
refers  to an anonymous type by a pseudo-name, written in italics, and uses
such  pseudo-names  at  places  where  the  syntax  normally  requires   an
identifier.

Examples of type definitions:

    (WHITE, RED, YELLOW, GREEN, BLUE, BROWN, BLACK)
    range1 .. 72
    array(1 .. 10) of INTEGER

Examples of type declarations:

    type COLOR  is (WHITE, RED, YELLOW, GREEN, BLUE, BROWN, BLACK);
    type COLUMN is range 1 .. 72;
    type TABLE  is array(1 .. 10) of INTEGER;

Notes:

Two  type  definitions  always  define two distinct types, even if they are
textually identical.   Thus,  the  array  type  definitions  given  in  the
declarations of A and B below define distinct types.



                                  3 - 13








    A : array(1 .. 10) of BOOLEAN;
    B : array(1 .. 10) of BOOLEAN;

If  A  and  B are declared by a multiple object declaration as below, their
types are nevertheless different, since the multiple object declaration  is
equivalent to the above two single object declarations.

    A, B : array(1 .. 10) of BOOLEAN;

















































                                  3 - 14








Incomplete  type  declarations are used for the definition of recursive and
mutually dependent types (see 3.8.1).  Private type declarations  are  used
in  package  specifications  and in generic parameter declarations (see 7.4
and 12.1).

References:  access type definition 3.8, array type  definition  3.6,  base
type  3.3,  constrained  array  definition  3.6,  constrained  subtype 3.3,
declaration  3.1,  derived  type  3.4,   derived   type   definition   3.4,
discriminant  part  3.7.1,  elaboration  3.9,  enumeration  type definition
3.5.1, identifier 2.3, incomplete  type  declaration  3.8.1,  integer  type
definition  3.5.4,  multiple  object  declaration  3.2,  numeric  type 3.5,
private type declaration 7.4, real type  definition  3.5.6,  reserved  word
2.9, type 3.3



3.3.2  Subtype Declarations


A subtype declaration declares a subtype.

    subtype_declaration ::=
       subtype identifier is subtype_indication;

    subtype_indication ::=  type_mark [constraint]

    type_mark ::= type_name | subtype_name

    constraint ::=
         range_constraint | floating_point_constraint | fixed_point_constraint
       | index_constraint | discriminant_constraint

A  type  mark denotes a type or a subtype.  If a type mark is the name of a
type,  the  type  mark  denotes  this  type  and  also  the   corresponding
unconstrained subtype.  The base type of a type mark is, by definition, the
base type of the type or subtype denoted by the type mark.

A  subtype  indication defines a subtype of the base type of the type mark.

If an index constraint appears after a type mark in a  subtype  indication,
the  type mark must not already impose an index constraint.  Likewise for a
discriminant  constraint,  the  type  mark  must  not  already   impose   a
discriminant constraint.

The elaboration of a subtype declaration consists of the elaboration of the
subtype  indication.   The  elaboration  of  a subtype indication creates a
subtype.  If the subtype indication does  not  include  a  constraint,  the
subtype is the same as that denoted by the type mark.  The elaboration of a
subtype indication that includes a constraint proceeds as follows:

(a)  The constraint is first elaborated.

(b)  A check is then made that the constraint is compatible with  the  type
     or subtype denoted by the type mark.



                                  3 - 15








The  condition  imposed  by  a  constraint  is the condition obtained after
elaboration of the constraint.  (The rules of  constraint  elaboration  are
such  that  the expressions and  ranges of constraints are evaluated by the
elaboration of these constraints.)  The rules  defining  compatibility  are
given  for each form of constraint in the appropriate section.  These rules
are such that if a constraint  is  compatible  with  a  subtype,  then  the
condition imposed by the constraint cannot contradict any condition already
imposed  by  the  subtype on its values.  The exception CONSTRAINT_ERROR is
raised if any check of compatibility fails.
















































                                  3 - 16








Examples of subtype declarations:


    subtype RAINBOW   is COLOR range RED .. BLUE;        --  see 3.3.1
    subtype RED_BLUE  is RAINBOW;
    subtype INT       is INTEGER;
    subtype SMALL_INT is INTEGER range -10 .. 10;
    subtype UP_TO_K   is COLUMN range 1 .. K;            --  see 3.3.1
    subtype SQUARE    is MATRIX(1 .. 10, 1 .. 10);       --  see 3.6
    subtype MALE      is PERSON(SEX => M);               --  see 3.8

Note:

A subtype declaration does not define a new type.

References:  base  type  3.3,  compatibility  of  discriminant  constraints
3.7.2,  compatibility  of  fixed  point constraints 3.5.9, compatibility of
floating point constraints 3.5.7, compatibility of index constraints 3.6.1,
compatibility of range constraints 3.5,  constraint_error  exception  11.1,
declaration   3.1,   discriminant   3.3,   discriminant  constraint  3.7.2,
elaboration 3.9, evaluation 4.5, expression 4.4, floating point  constraint
3.5.7,   fixed  point  constraint  3.5.9,  index  constraint  3.6.1,  range
constraint 3.5, reserved word 2.9, subtype 3.3, type 3.3, type name  3.3.1,
unconstrained subtype 3.3



3.3.3  Classification of Operations


The   set  of  operations  of  a  type  includes  the  explicitly  declared
subprograms that have a parameter or result of the type;  such  subprograms
are necessarily declared after the type declaration.

The  remaining  operations  are  each  implicitly declared for a given type
declaration, immediately  after  the  type  definition.   These  implicitly
declared operations comprise the basic operations, the predefined operators
(see  4.5),  and  enumeration  literals.   In  the  case  of a derived type
declaration,  the  implicitly  declared  operations  include  any   derived
subprograms.    The   operations  implicitly  declared  for  a  given  type
declaration occur after the type declaration and before the  next  explicit
declaration,  if  any.   The  implicit  declarations of derived subprograms
occur last.

A basic operation is an operation that is inherent in one of the following:

  -  An assignment  (in  assignment  statements  and  initializations),  an
     allocator, a membership test, or a short-circuit control form.

  -  A selected component, an indexed component, or a slice.

  -  A  qualification  (in  qualified  expressions),   an   explicit   type
     conversion,  or  an  implicit  type  conversion  of  a  value  of type
     universal_integer or universal_real  to  the  corresponding  value  of
     another numeric type.


                                  3 - 17








  -  A numeric literal (for a universal type), the  literal  null  (for  an
     access type), a string literal, an aggregate, or an attribute.

For every type or subtype T, the following attribute is defined:

T'BASE     The base type of T.  This  attribute  is  allowed  only  as  the
           prefix   of   the  name  of  another  attribute:   for  example,
           T'BASE'FIRST.

















































                                  3 - 18








Note:

Each literal is an operation  whose  evaluation  yields  the  corresponding
value  (see  4.2).  Likewise, an aggregate is an operation whose evaluation
yields a value of a composite type (see 4.3).  Some operations  of  a  type
operate  on  values  of  the  type,  for  example, predefined operators and
certain subprograms and attributes.  The evaluation of some operations of a
type returns a value  of  the  type,  for  example,  literals  and  certain
functions,   attributes,   and  predefined  operators.   Assignment  is  an
operation that operates on an object and a value.  The  evaluation  of  the
operation corresponding to a selected component, an indexed component, or a
slice, yields the object or value denoted by this form of name.


References:  aggregate 4.3, allocator 4.8, assignment 5.2, attribute 4.1.4,
character   literal  2.5,  composite  type  3.3,  conversion  4.6,  derived
subprogram 3.4, enumeration literal 3.5.1, formal parameter  6.1,  function
6.5,  indexed component 4.1.1, initial value 3.2.1, literal 4.2, membership
test 4.5 4.5.2, null literal 3.8, numeric literal 2.4,  numeric  type  3.5,
object  3.2.1,  6.1,  predefined  operator  4.5,  qualified expression 4.7,
selected component 4.1.3,  short-circuit  control  form  4.5  4.5.1,  slice
4.1.2,  string  literal  2.6,  subprogram  6,  subtype  3.3, type 3.3, type
declaration 3.3.1, universal_integer type 3.5.4, universal_real type 3.5.6,
universal type 4.10



3.4  Derived Types


A derived type definition defines a new (base) type  whose  characteristics
are  derived from those of a parent type;  the new type is called a derived
type.  A derived type definition further defines a derived  subtype,  which
is a subtype of the derived type.

    derived_type_definition ::= new subtype_indication

The  subtype indication that occurs after the reserved word new defines the
parent subtype.  The parent type is the base type of  the  parent  subtype.
If  a constraint exists for the parent subtype, a similar constraint exists
for the  derived  subtype;   the  only  difference  is  that  for  a  range
constraint,  and  likewise  for  a  floating or fixed point constraint that
includes a range constraint, the value of each bound  is  replaced  by  the
corresponding  value  of  the  derived  type.   The  characteristics of the
derived type are defined as follows:

  -  The derived type belongs to the same class  of  types  as  the  parent
     type.   The  set  of possible values for the derived type is a copy of
     the set of possible values for the parent type.  If the parent type is
     composite, then the same components exist for the  derived  type,  and
     the subtype of corresponding components is the same.

  -  For each basic operation of the parent type, there is a  corresponding
     basic  operation  of  the derived type.  Explicit type conversion of a
     value of the parent type into the corresponding value of  the  derived


                                  3 - 19








     type is allowed and vice versa as explained in section 4.6.

  -  For each enumeration literal or predefined operator of the parent type
     there is a corresponding operation for the derived type.

  -  If the parent type is a task type, then for each entry of  the  parent
     type there is a corresponding entry for the derived type.

  -  If a default expression exists for a component of an object having the
     parent  type,  then  the  same  default  expression  is  used  for the
     corresponding component of an object having the derived type.














































                                  3 - 20








  -  If the parent type is an access type, then the parent and the  derived
     type  share the same collection;  there is a null access value for the
     derived type and it is the default initial value of that type.

  -  If an explicit representation clause exists for the parent type and if
     this clause appears before the derived type definition, then there  is
     a  corresponding  representation  clause  (an  implicit  one)  for the
     derived type.

  -  Certain subprograms that are operations of the parent type are said to
     be derivable.  For each derivable subprogram of the parent type, there
     is a corresponding derived subprogram for the derived type.  Two kinds
     of derivable subprograms exist.  First, if the parent type is declared
     immediately within the visible part of a package,  then  a  subprogram
     that is itself explicitly declared immediately within the visible part
     becomes  derivable  after  the  end  of  the visible part, if it is an
     operation of the parent type.   (The  explicit  declaration  is  by  a
     subprogram   declaration,   a   renaming  declaration,  or  a  generic
     instantiation.)  Second, if the parent type is itself a derived  type,
     then  any  subprogram  that  has  been  derived by this parent type is
     further derivable, unless the parent type is declared in  the  visible
     part  of a package and the derived subprogram is hidden by a derivable
     subprogram of the first kind.

Each operation of the derived type is implicitly declared at the  place  of
the  derived  type  declaration.   The implicit declarations of any derived
subprograms occur last.

The specification  of  a  derived  subprogram  is  obtained  implicitly  by
systematic  replacement  of  the  parent  type  by  the derived type in the
specification of the derivable subprogram.  Any subtype of the parent  type
is  likewise  replaced  by  a  subtype  of  the derived type with a similar
constraint (as for the transformation of a constraint of the parent subtype
into the corresponding constraint of the derived  subtype).   Finally,  any
expression  of  the  parent  type  is  made  to  be  the  operand of a type
conversion that yields a result of the derived type.

Calling a derived subprogram is equivalent  to  calling  the  corresponding
subprogram  of  the  parent type, in which each actual parameter that is of
the derived type is replaced by a type conversion of this actual  parameter
to the parent type (this means that a conversion to the parent type happens
before  the  call for the modes in and in out;  a reverse conversion to the
derived type happens after the call for the  modes  in  out  and  out,  see
6.4.1).   In  addition, if the result of a called function is of the parent
type, this result is converted to the derived type.

If a derived or private type is declared  immediately  within  the  visible
part  of  a  package, then, within this visible part, this type must not be
used as the parent type of a derived type definition.  (For private  types,
see also section 7.4.1.)

For the elaboration of a derived type definition, the subtype indication is
first  elaborated,  the  derived  type  is  then  created, and finally, the
derived subtype is created.



                                  3 - 21








Examples:

    type LOCAL_COORDINATE is new COORDINATE;   --  two different types
    type MIDWEEK is new DAY range TUE .. THU;  --  see 3.5.1
    type COUNTER is new POSITIVE;              --  same range as POSITIVE

    type SPECIAL_KEY is new KEY_MANAGER.KEY;   --  see 7.4.2
    -- the derived subprograms have the following specifications:

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














































                                  3 - 22








Notes:

The rules of derivation of basic operations and enumeration literals  imply
that  the  notation for any literal or aggregate of the derived type is the
same as for the parent type;  such literals and aggregates are said  to  be
overloaded.   Similarly,  it  follows  that  the  notation  for  denoting a
component, a discriminant, an entry, a slice, or an attribute is  the  same
for the derived type as for the parent type.

Hiding  of a derived subprogram is allowed even within the same declarative
region (see 8.3).  A derived subprogram hides a  predefined  operator  that
has the same parameter and result type profile (see 6.6).

A  generic  subprogram  declaration  is  not  derivable since it declares a
generic unit rather than a subprogram.  On the other hand, an instantiation
of a generic subprogram is a (nongeneric) subprogram, which is derivable if
it satisfies the requirements for derivability of subprograms.

If the parent type is a boolean type, the predefined  relational  operators
of  the  derived  type deliver a result of the predefined type BOOLEAN (see
4.5.2).

If a representation clause is given for the parent type but  appears  after
the  derived  type declaration, then no corresponding representation clause
applies to the derived type;  hence an explicit representation  clause  for
such a derived type is allowed.

For  a  derived subprogram, if a parameter belongs to the derived type, the
subtype of this parameter need not  have  any  value  in  common  with  the
derived subtype.

References:   access  value  3.8,  actual  parameter  6.4.1, aggregate 4.3,
attribute 4.1.4, base type 3.3, basic operation 3.3.3, boolean type  3.5.3,
bound  of  a  range  3.5, class of type 3.3, collection 3.8, component 3.3,
composite type  3.3,  constraint  3.3,  conversion  4.6,  declaration  3.1,
declarative region 8.1, default expression 3.2.1, default initial value for
an   access  type  3.8,  discriminant  3.3,  elaboration  3.9,  entry  9.5,
enumeration literal 3.5.1, floating point  constraint  3.5.7,  fixed  point
constraint   3.5.9,  formal  parameter  6.1,  function  call  6.4,  generic
declaration 12.1, immediately within 8.1, implicit declaration 3.1, literal
4.2, mode 6.1, overloading 6.6 8.7, package 7, package  specification  7.1,
parameter  association  6.4,  predefined  operator  4.5,  private type 7.4,
procedure  6,  procedure  call  statement  6.4,   range   constraint   3.5,
representation  clause  13.1, reserved word 2.9, slice 4.1.2, subprogram 6,
subprogram specification 6.1, subtype indication 3.3.2, subtype  3.3,  type
3.3, type definition 3.3.1, visible part 7.2



3.5  Scalar Types


Scalar  types  comprise  enumeration  types, integer types, and real types.
Enumeration types and integer types are called discrete types;  each  value
of  a  discrete  type  has  a  position  number  which is an integer value.


                                  3 - 23








Integer types and real types are called numeric types.   All  scalar  types
are  ordered,  that  is,  all relational operators are predefined for their
values.

    range_constraint ::=  range range

    range ::=  range_attribute
       | simple_expression .. simple_expression

















































                                  3 - 24








A range specifies a subset of values of a scalar type.  The range  L  ..  R
specifies  the values from L to R inclusive if the relation L <= R is true.
The values L and R are called the lower bound and upper bound of the range,
respectively.  A value V is said  to  satisfy  a  range  constraint  if  it
belongs  to  the  range;  the value V is said to belong to the range if the
relations L <= V and V <= R are both TRUE.  A null range  is  a  range  for
which  the  relation R < L is TRUE;  no value belongs to a null range.  The
operators <= and < in the above definitions are the predefined operators of
the scalar type.

If a range constraint is used in a subtype indication, either  directly  or
as  part  of  a  floating or fixed point constraint, the type of the simple
expressions (likewise,  of the bounds of a range  attribute)  must  be  the
same  as the base type of the type mark of the subtype indication.  A range
constraint is compatible with a subtype if each bound of the range  belongs
to the subtype, or if the range constraint defines a null range;  otherwise
the range constraint is not compatible with the subtype.

The  elaboration  of  a  range constraint consists of the evaluation of the
range.  The evaluation of a range defines its lower  bound  and  its  upper
bound.   If  simple  expressions  are  given  to  specify  the  bounds, the
evaluation of the range evaluates these simple expressions  in  some  order
that is not defined by the language.

Attributes

For  any scalar type T or for any subtype T of a scalar type, the following
attributes are defined:

T'FIRST     Yields the lower bound of T.  The value of this  attribute  has
            the same type as T.

T'LAST      Yields the upper bound of T.  The value of this  attribute  has
            the same type as T.

Note:

Indexing and iteration rules use values of discrete types.

References:   attribute  4.1.4,  constraint  3.3,  enumeration  type 3.5.1,
erroneous 1.6, evaluation 4.5, fixed point constraint 3.5.9, floating point
constraint 3.5.7, index 3.6, integer type 3.5.4, loop statement 5.5,  range
attribute  3.6.2, real type 3.5.6, relational operator 4.5 4.5.2, satisfy a
constraint 3.3, simple expression 4.4, subtype indication 3.3.2, type  mark
3.3.2



3.5.1  Enumeration Types


An enumeration type definition defines an enumeration type.

    enumeration_type_definition ::=
       (enumeration_literal_specification {, enumeration_literal_specification})


                                  3 - 25








    enumeration_literal_specification ::=  enumeration_literal

    enumeration_literal ::=  identifier | character_literal

The  identifiers  and  character  literals  listed  by  an enumeration type
definition must be distinct.  Each enumeration literal specification is the
declaration of the corresponding enumeration literal:  this declaration  is
equivalent  to  the declaration of a parameterless function, the designator
being the enumeration literal, and the result type  being  the  enumeration
type.   The  elaboration  of  an  enumeration  type  definition  creates an
enumeration type;  this elaboration  includes  that  of  every  enumeration
literal specification.













































                                  3 - 26








Each  enumeration  literal  yields  a  different  enumeration  value.   The
predefined order relations between enumeration values follow the  order  of
corresponding  position  numbers.   The position number of the value of the
first listed enumeration literal is zero;  the  position  number  for  each
other enumeration literal is one more than for its predecessor in the list.

If  the  same identifier or character literal is specified in more than one
enumeration type definition, the corresponding  literals  are  said  to  be
overloaded.  At any place where an overloaded enumeration literal occurs in
the  text  of  a  program,  the  type  of  the  enumeration literal must be
determinable from the context (see 8.7).

Examples:

    type DAY    is (MON, TUE, WED, THU, FRI, SAT, SUN);
    type SUIT   is (CLUBS, DIAMONDS, HEARTS, SPADES);
    type GENDER is (M, F);
    type LEVEL  is (LOW, MEDIUM, URGENT);
    type COLOR  is (WHITE, RED, YELLOW, GREEN, BLUE, BROWN, BLACK);
    type LIGHT  is (RED, AMBER, GREEN); -- RED and GREEN are overloaded

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

    subtype WEEKDAY is DAY   range MON .. FRI;
    subtype MAJOR   is SUIT  range HEARTS .. SPADES;
    subtype RAINBOW is COLOR range RED .. BLUE;  --  the color RED, not the light

Note:

If an enumeration literal occurs in  a  context  that  does  not  otherwise
suffice  to  determine  the  type of the literal, then qualification by the
name of the enumeration type is one way to resolve the ambiguity (see 8.7).


References:   character  literal  2.5,  declaration  3.1,  designator  6.1,
elaboration  3.9,  6.1, function 6.5, identifier 2.3, name 4.1, overloading
6.6 8.7, position number 3.5, qualified expression 4.7, relational operator
4.5 4.5.2, type 3.3, type definition 3.3.1



3.5.2  Character Types


An enumeration type is said to be a character type if at least one  of  its
enumeration literals is a character literal.  The predefined type CHARACTER
is  a  character  type  whose  values  are  the 128 characters of the ASCII
character set.  Each of the 95 graphic characters of this character set  is
denoted by the corresponding character literal.

Example:

    type ROMAN_DIGIT is ('I', 'V', 'X', 'L', 'C', 'D', 'M');



                                  3 - 27








Notes:

The predefined package ASCII includes the declaration of constants denoting
control  characters  and  of constants denoting graphic characters that are
not in the basic character set.




















































                                  3 - 28








A conventional character set such as EBCDIC can be declared as a  character
type;   the  internal  codes  of  the  characters  can  be  specified by an
enumeration representation clause as explained in section 13.3.

References:  ascii predefined package C,  basic  character  2.1,  character
literal  2.5,  constant  3.2.1,  declaration  3.1,  enumeration type 3.5.1,
graphic character 2.1, identifier 2.3, literal 4.2, predefined type C, type
3.3



3.5.3  Boolean Types


There is a predefined enumeration type named BOOLEAN.  It contains the  two
literals  FALSE and TRUE ordered with the relation FALSE < TRUE.  A boolean
type is either the type BOOLEAN or a type  that  is  derived,  directly  or
indirectly, from a boolean type.

References:   derived type 3.4, enumeration literal 3.5.1, enumeration type
3.5.1, relational operator 4.5 4.5.2, type 3.3



3.5.4  Integer Types


An integer type definition defines an integer  type  whose  set  of  values
includes at least those of the specified range.

    integer_type_definition ::=  range_constraint

If  a range constraint is used as an integer type definition, each bound of
the range must be defined by a static expression of some integer type,  but
the  two  bounds need not have the same integer type.  (Negative bounds are
allowed.)

A type declaration of the form:

    type T is range L .. R;

is, by definition, equivalent to the following declarations:

    type integer_type is new predefined_integer_type;
    subtype T is integer_type range integer_type(L) .. integer_type(R);

where integer_type is an anonymous type, and where the  predefined  integer
type  is  implicitly  selected  by the implementation, so as to contain the
values L to R inclusive.  The integer type declaration is illegal  if  none
of  the  predefined  integer  types  satisfies  this requirement, excepting
universal_integer.  The elaboration of the declaration of an  integer  type
consists   of   the   elaboration   of  the  equivalent  type  and  subtype
declarations.




                                  3 - 29








The predefined integer types include the type INTEGER.   An  implementation
may  also  have  predefined  types  such as SHORT_INTEGER and LONG_INTEGER,
which have (substantially) shorter and longer  ranges,  respectively,  than
INTEGER.   The  range  of each of these types must be symmetric about zero,
excepting an extra negative value which may exist in some  implementations.
The base type of each of these types is the type itself.



















































                                  3 - 30








Integer  literals  are the literals of an anonymous predefined integer type
that is called universal_integer in this reference manual.   Other  integer
types  have  no  literals.   However, for each integer type there exists an
implicit conversion  that  converts  a  universal_integer  value  into  the
corresponding  value (if any) of the integer type.  The circumstances under
which these implicit conversions are invoked are described in section  4.6.

The  position  number of an integer value is the corresponding value of the
type universal_integer.

The same arithmetic operators are predefined for  all  integer  types  (see
4.5).   The  exception  NUMERIC_ERROR  is  raised  by  the  execution of an
operation (in particular an implicit conversion) that  cannot  deliver  the
correct  result  (that  is,  if the value corresponding to the mathematical
result is not a  value of the integer type).  However, an implementation is
not required to raise the exception NUMERIC_ERROR if the operation is  part
of a larger expression whose result can be computed correctly, as described
in section 11.6.

Examples:

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

    subtype SMALL_INT   is INTEGER   range -10 .. 10;
    subtype COLUMN_PTR  is LINE_SIZE range 1 .. 10;
    subtype BUFFER_SIZE is INTEGER   range 0 .. MAX;

Notes:

The name declared by an integer type declaration is a subtype name.  On the
other  hand,  the  predefined  operators of an integer type deliver results
whose range is defined by the parent predefined type;  such a  result  need
not  belong to the declared subtype, in which case an attempt to assign the
result  to  a  variable  of  the  integer  subtype  raises  the   exception
CONSTRAINT_ERROR.

The  smallest  (most  negative)  value  supported by the predefined integer
types of an implementation is  the  named  number  SYSTEM.MIN_INT  and  the
largest (most positive) value is SYSTEM.MAX_INT (see 13.7).

References:   anonymous  type  3.3.1,  belong  to a subtype 3.3, bound of a
range 3.5, constraint_error exception 11.1, conversion 4.6, identifier 2.3,
integer literal 2.4, literal 4.2, numeric_error exception 11.1, parent type
3.4, predefined operator 4.5, range constraint 3.5, static expression  4.9,
subtype  declaration  3.3.2, system predefined package 13.7, type 3.3, type
declaration 3.3.1, type definition 3.3.1, universal type 4.10



3.5.5  Operations of Discrete Types


The basic operations of a discrete type include the operations involved  in
assignment,  the  membership  tests, and qualification;  for a boolean type


                                  3 - 31








they include the short-circuit control forms;  for  an  integer  type  they
include  the  explicit  conversion  of values of other numeric types to the
integer  type,  and  the  implicit  conversion  of  values  of   the   type
universal_integer to the type.

Finally, for every discrete type or subtype T, the basic operations include
the  attributes  listed  below.   In this presentation, T is referred to as
being  a  subtype  (the  subtype  T)  for  any  property  that  depends  on
constraints imposed by T;  other properties are stated in terms of the base
type of T.















































                                  3 - 32








The first group of attributes yield characteristics of the subtype T.  This
group  includes  the  attribute  BASE (see 3.3.2), the attributes FIRST and
LAST (see 3.5), the representation attribute SIZE (see  13.7.2),  and   the
attribute WIDTH defined as follows:

T'WIDTH     Yields the maximum image length over all values of the  subtype
            T  (the  image  is  the  sequence of characters returned by the
            attribute IMAGE, see below).  Yields zero  for  a  null  range.
            The  value  of this attribute is of the type universal_integer.

All attributes of the second group are functions with a  single  parameter.
The corresponding actual parameter is indicated below by X.

T'POS       This attribute is a function.  The parameter X must be a  value
            of   the  base  type  of  T.   The  result  type  is  the  type
            universal_integer.  The result is the position  number  of  the
            value of the parameter.

T'VAL       This attribute is a special function with  a  single  parameter
            which  can be of any integer type.  The result type is the base
            type of T.  The result is the value whose  position  number  is
            the  universal_integer value corresponding to X.  The exception
            CONSTRAINT_ERROR  is  raised  if  the  universal_integer  value
            corresponding  to  X is not in the range T'POS(T'BASE'FIRST) ..
            T'POS(T'BASE'LAST).

T'SUCC      This attribute is a function.  The parameter X must be a  value
            of  the base type of T.  The result type is the base type of T.
            The result is the value whose position number  is  one  greater
            than  that of X.  The exception CONSTRAINT_ERROR is raised if X
            equals T'BASE'LAST.

T'PRED      This attribute is a function.  The parameter X must be a  value
            of  the base type of T.  The result type is the base type of T.
            The result is the value whose position number is one less  than
            that  of  X.   The  exception  CONSTRAINT_ERROR  is raised if X
            equals T'BASE'FIRST.

T'IMAGE     This attribute is a function.  The parameter X must be a  value
            of  the base type of T.  The result type is the predefined type
            STRING.  The result is the image of the value of X, that is,  a
            sequence  of characters representing the value in display form.
            The image of an integer  value  is  the  corresponding  decimal
            literal;   without  underlines,  leading  zeros,  exponent,  or
            trailing spaces;  but with a single leading character  that  is
            either  a  minus sign or a space.  The lower bound of the image
            is one.

            The image of an enumeration value is either  the  corresponding
            identifier in upper case or the corresponding character literal
            (including  the two apostrophes);  neither leading nor trailing
            spaces are included.  The image of a character C, other than  a
            graphic   character,   is   implementation-defined;   the  only
            requirement is that the  image  must  be  such  that  C  equals
            CHARACTER'VALUE(CHARACTER'IMAGE(C)).


                                  3 - 33








T'VALUE     This attribute is a function.  The parameter X must be a  value
            of  the  predefined  type  STRING.  The result type is the base
            type of T.  Any leading and any trailing spaces of the sequence
            of characters that corresponds to the parameter are ignored.

            For an enumeration type, if the sequence of characters has  the
            syntax of an enumeration literal and if this literal exists for
            the base type of T, the result is the corresponding enumeration
            value.   For an integer type, if the sequence of characters has
            the syntax of an  integer  literal,  with  an  optional  single
            leading character that is a plus or minus sign, and if there is
            a corresponding value in the base type of T, the result is this
            value.   In  any  other case, the exception CONSTRAINT_ERROR is
            raised.











































                                  3 - 34








In addition, the attributes A'SIZE and A'ADDRESS are defined for an  object
A of a discrete type (see 13.7.2).

Besides the basic operations, the operations of a discrete type include the
predefined relational operators.  For enumeration types, operations include
enumeration literals.  For boolean types, operations include the predefined
unary  logical negation operator not, and the predefined logical operators.
For integer types, operations include the predefined arithmetic  operators:
these  are  the  binary and unary adding operators - and +, all multiplying
operators, the unary operator abs, and the exponentiating operator.

The operations of a subtype are the corresponding operations  of  its  base
type   except   for   the   following:    assignment,   membership   tests,
qualification, explicit type conversions, and the attributes of  the  first
group;   the  effect  of  each  of  these operations depends on the subtype
(assignments, membership tests, qualifications, and conversions  involve  a
subtype check;  attributes of the first group yield a characteristic of the
subtype).

Notes:

For  a  subtype of a discrete type, the results delivered by the attributes
SUCC, PRED, VAL, and VALUE need not belong to the subtype;  similarly,  the
actual  parameters  of  the  attributes POS, SUCC, PRED, and IMAGE need not
belong to the subtype.  The  following  relations  are  satisfied  (in  the
absence of an exception) by these attributes:

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

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

Examples:

    --  For the types and subtypes declared in section 3.5.1 we have:

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

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


References:   abs operator 4.5 4.5.6, assignment 5.2, attribute 4.1.4, base
type 3.3, basic operation 3.3.3, binary adding operator 4.5 4.5.3,  boolean
type  3.5.3,  bound  of a range 3.5, character literal 2.5, constraint 3.3,
constraint_error  exception  11.1,  conversion  4.6,  discrete  type   3.5,
enumeration literal 3.5.1, exponentiating operator 4.5 4.5.6, function 6.5,
graphic character 2.1, identifier 2.3, integer type 3.5.4, logical operator
4.5  4.5.1,  membership test 4.5 4.5.2, multiplying operator 4.5 4.5.5, not
operator 4.5 4.5.6, numeric literal 2.4,  numeric  type  3.5,  object  3.2,
operation  3.3,  position  number  3.5, predefined operator 4.5, predefined
type  C,  qualified  expression  4.7,  relational   operator   4.5   4.5.2,


                                  3 - 35








short-circuit  control form 4.5 4.5.1, string type 3.6.3, subtype 3.3, type
3.3,  unary  adding  operator  4.5  4.5.4,  universal_integer  type  3.5.4,
universal type 4.10






















































                                  3 - 36








3.5.6  Real Types


Real types provide approximations to the real numbers, with relative bounds
on  errors  for  floating  point  types, and with absolute bounds for fixed
point types.

    real_type_definition ::=
       floating_point_constraint | fixed_point_constraint

A set of numbers called model numbers is associated with  each  real  type.
Error  bounds  on the predefined operations are given in terms of the model
numbers.  An implementation of the type must include at least  these  model
numbers and represent them exactly.

An  implementation-dependent  set  of  numbers, called the safe numbers, is
also associated with each real type.  The set of safe  numbers  of  a  real
type must include at least the set of model numbers of the type.  The range
of  safe  numbers  is allowed to be larger than the range of model numbers,
but error bounds on the predefined operations for safe numbers are given by
the same rules as  for  model  numbers.   Safe  numbers  therefore  provide
guaranteed error bounds for operations on an implementation-dependent range
of  numbers;   in  contrast, the range of model numbers depends only on the
real type definition and is therefore independent of the implementation.

Real literals are the literals of an anonymous predefined real type that is
called universal_real in this reference manual.  Other real types  have  no
literals.  However, for each real type, there exists an implicit conversion
that  converts  a  universal_real value into a value of the real type.  The
conditions under which these implicit conversions are invoked are described
in section 4.6.   If  the  universal_real  value  is  a  safe  number,  the
implicit conversion delivers the corresponding value;  if it belongs to the
range  of  safe  numbers but is not a safe number, then the converted value
can be any value within the range defined by the safe  numbers  next  above
and below the universal_real value.

The  execution of an operation that yields a value of a real type may raise
the exception NUMERIC_ERROR, as explained in section 4.5.7,  if  it  cannot
deliver a correct result (that is, if the value corresponding to one of the
possible  mathematical  results  does  not  belong  to  the  range  of safe
numbers);  in particular, this exception  can  be  raised  by  an  implicit
conversion.   However,  an  implementation  is  not  required  to raise the
exception NUMERIC_ERROR if the operation is part  of  a  larger  expression
whose result can be computed correctly (see 11.6).

The  elaboration  of a real type definition includes the elaboration of the
floating or fixed point constraint and creates a real type.

Note:

An algorithm written to rely only upon  the  minimum  numerical  properties
guaranteed  by  the  type  definition  for  model  numbers will be portable
without further precautions.




                                  3 - 37








References:  conversion 4.6, elaboration 3.9, fixed point constraint 3.5.9,
floating point constraint 3.5.7, literal 4.2, numeric_error exception 11.1,
predefined operation 3.3.3, real literal 2.4,  type  3.3,  type  definition
3.3.1, universal type 4.10





















































                                  3 - 38








3.5.7  Floating Point Types


For  floating  point  types,  the  error  bound  is specified as a relative
precision by giving the required  minimum  number  of  significant  decimal
digits.

    floating_point_constraint ::=
       floating_accuracy_definition [range_constraint]

    floating_accuracy_definition ::=  digits static_simple_expression

The  minimum number of significant decimal digits is specified by the value
of the static simple expression of the floating accuracy definition.   This
value  must belong to some integer type and must be positive (nonzero);  it
is denoted by D in the remainder of this section.  If  the  floating  point
constraint  is  used  as  a  real  type  definition  and  includes  a range
constraint, then each bound of the  range  must  be  defined  by  a  static
expression  of  some  real  type, but the two bounds need not have the same
real type.

For a given radix, the following canonical form is defined for any floating
point model number other than zero:

    sign * mantissa * (radix ** exponent)

In this form: sign is either +1 or -1;  mantissa is expressed in  a  number
base  given by radix; and exponent is an integer number (possibly negative)
such that the integer part of mantissa is zero and the first digit  of  its
fractional part is not a zero.

The  specified  number  D  is the minimum number of decimal digits required
after the point in the decimal mantissa (that is, if radix  is  ten).   The
value  of D in turn determines a corresponding number B that is the minimum
number of binary digits required after the point  in  the  binary  mantissa
(that is, if radix is two).  The number B associated with D is the smallest
value  such  that the relative precision of the binary form is no less than
that specified for the decimal form.  (The number B  is  the  integer  next
above (D*log(10)/log(2)) + 1.)

The  model  numbers defined by a floating accuracy definition comprise zero
and all numbers whose binary canonical form has exactly B digits after  the
point  in  the  mantissa  and  an  exponent in the range -4*B .. +4*B.  The
guaranteed minimum accuracy of operations  of  a  floating  point  type  is
defined in terms of the model numbers of the floating point constraint that
forms the corresponding real type definition (see 4.5.7).

The   predefined   floating   point  types  include  the  type  FLOAT.   An
implementation may also have  predefined  types  such  as  SHORT_FLOAT  and
LONG_FLOAT,   which   have   (substantially)   less   and   more  accuracy,
respectively, than FLOAT.  The base type of each predefined floating  point
type  is  the  type  itself.  The model numbers of each predefined floating
point type are defined in terms of the number D of decimal digits  returned
by the attribute DIGITS (see 3.5.8).



                                  3 - 39








For  each  predefined  floating point type (consequently also for each type
derived therefrom), a set of safe numbers is defined as follows.  The  safe
numbers  have  the same number B of mantissa digits as the model numbers of
the type  and  have  an  exponent  in  the  range  -E  ..  +E  where  E  is
implementation-defined  and  at  least  equal  to the 4*B of model numbers.
(Consequently, the safe numbers include  the  model  numbers.)   The  rules
defining  the  accuracy of operations with model and safe numbers are given
in section 4.5.7.  The safe numbers of a subtype  are  those  of  its  base
type.
















































                                  3 - 40








A floating point type declaration of one of the two forms (that is, with or
without the optional range constraint indicated by the square brackets):

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

is, by definition, equivalent to the following declarations:

    type floating_point_type is new predefined_floating_point_type;
    subtype T is floating_point_type digits D
       [range floating_point_type(L) .. floating_point_type(R)];

where  floating_point_type  is  an anonymous type, and where the predefined
floating point type is implicitly selected by the  implementation  so  that
its  model numbers include the model numbers defined by D;  furthermore, if
a range L .. R is supplied, then both L and R must belong to the  range  of
safe  numbers.   The  floating  point declaration is illegal if none of the
predefined floating point types  satisfies  these  requirements,  excepting
universal_real.   The  maximum  number of digits that can be specified in a
floating accuracy definition is given by the system-dependent named  number
SYSTEM.MAX_DIGITS (see 13.7.1).

The  elaboration  of  a  floating  point  type  declaration consists of the
elaboration of the equivalent type and subtype declarations.

If a floating point constraint follows a type mark in a subtype indication,
the type mark must denote a floating point type or subtype.   The  floating
point  constraint  is  compatible  with  the type mark only if the number D
specified in the floating accuracy  definition  is  not  greater  than  the
corresponding  number  D  for the type or subtype denoted by the type mark.
Furthermore, if the floating point constraint includes a range  constraint,
the  floating point constraint is compatible with the type mark only if the
range constraint is, itself, compatible with the type mark.

The elaboration of such a subtype indication includes  the  elaboration  of
the range constraint, if there is one;  it creates a floating point subtype
whose  model  numbers  are  defined  by the corresponding floating accuracy
definition.  A value of a floating point type belongs to a  floating  point
subtype if and only if it belongs to the range defined by the subtype.

The  same  arithmetic operators are predefined for all floating point types
(see 4.5).

Notes:

A range constraint is allowed  in  a  floating  point  subtype  indication,
either  directly  after  the  type  mark,  or  as  part of a floating point
constraint.  In either case the bounds of the range must belong to the base
type of the type mark (see  3.5).   The  imposition  of  a  floating  point
constraint on a type mark in a subtype indication cannot reduce the allowed
range  of  values unless it includes a range constraint (the range of model
numbers that correspond to the specified number of digits  can  be  smaller
than  the  range  of  numbers of the type mark).  A value that belongs to a
floating point subtype need not be a model number of the subtype.




                                  3 - 41








Examples:

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

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

    subtype SHORT_COEFF is COEFFICIENT digits 5;    --   a subtype with less accuracy
    subtype PROBABILITY is REAL range 0.0 .. 1.0;   --   a subtype with a smaller range
















































                                  3 - 42








Notes on the examples:

The implemented accuracy for COEFFICIENT  is  that  of  a  predefined  type
having  at least 10 digits of precision.  Consequently the specification of
5 digits of precision for the subtype SHORT_COEFF is allowed.  The  largest
model number for the type MASS is approximately 1.27E30 and hence less than
the  specified  upper bound (1.0E35).  Consequently the declaration of this
type is legal only if this upper bound is in the range of the safe  numbers
of  a predefined floating point type having at least 7 digits of precision.

References:  anonymous type 3.3.1, arithmetic  operator  3.5.5  4.5,  based
literal  2.4.2,  belong  to a subtype 3.3, bound of a range 3.5, compatible
3.3.2, derived type 3.4, digit 2.1, elaboration 3.1 3.9, error bound 3.5.6,
exponent 2.4.1 integer type  3.5.4,  model  number  3.5.6,  operation  3.3,
predefined operator 4.5, predefined type C, range constraint 3.5, real type
3.5.6,  real  type  definition  3.5.6, safe number 3.5.6, simple expression
4.4, static expression 4.9, subtype declaration 3.3.2,  subtype  indication
3.3.2, subtype 3.3, type 3.3, type declaration 3.3.1, type mark 3.3.2



3.5.8  Operations of Floating Point Types


The  basic  operations  of  a  floating  point  type include the operations
involved in  assignment,  membership  tests,  qualification,  the  explicit
conversion of values of other numeric types to the floating point type, and
the  implicit  conversion of values of the type universal_real to the type.

In addition, for  every  floating  point  type  or  subtype  T,  the  basic
operations include the attributes listed below.  In this presentation, T is
referred  to  as  being  a  subtype  (the  subtype T) for any property that
depends on constraints imposed by T;  other properties are stated in  terms
of the base type of T.

The  first group of attributes yield characteristics of the subtype T.  The
attributes of this group are the attribute BASE (see 3.3.2), the attributes
FIRST and LAST (see 3.5), the representation attribute SIZE  (see  13.7.2),
and the following attributes:

T'DIGITS     Yields the number of decimal digits in the decimal mantissa of
             model  numbers  of  the subtype T.  (This attribute yields the
             number D of section 3.5.7.)  The value of this attribute is of
             the type universal_integer.

T'MANTISSA   Yields the number of binary digits in the binary  mantissa  of
             model  numbers  of  the subtype T.  (This attribute yields the
             number B of section 3.5.7.)  The value of this attribute is of
             the type universal_integer.

T'EPSILON    Yields the absolute value of the difference between the  model
             number 1.0 and the next model number above, for the subtype T.
             The value of this attribute is of the type universal_real.




                                  3 - 43








T'EMAX       Yields the largest exponent value in the binary canonical form
             of model numbers of the subtype T.  (This attribute yields the
             product 4*B of section 3.5.7.)  The value of this attribute is
             of the type  universal_integer.

T'SMALL      Yields the smallest positive (nonzero)  model  number  of  the
             subtype  T.   The  value  of  this  attribute  is  of the type
             universal_real.

T'LARGE      Yields the largest positive model number  of  the  subtype  T.
             The value of this attribute is of the type universal_real.














































                                  3 - 44








The  attributes  of the second group include the following attributes which
yield characteristics of the safe numbers:

T'SAFE_EMAX  Yields the largest exponent value in the binary canonical form
             of safe numbers of the base type of T.  (This attribute yields
             the number E of section 3.5.7.)  The value of  this  attribute
             is of the type universal_integer.

T'SAFE_SMALL Yields the smallest positive (nonzero) safe number of the base
             type  of  T.   The  value  of  this  attribute  is of the type
             universal_real.

T'SAFE_LARGE Yields the largest positive safe number of the base type of T.
             The value of this attribute is of the type universal_real.

In addition, the attributes A'SIZE and A'ADDRESS are defined for an  object
A  of a floating point type (see 13.7.2).  Finally, for each floating point
type there are machine-dependent attributes that are not related  to  model
numbers  and  safe  numbers.   They correspond to the attribute designators
MACHINE_RADIX,      MACHINE_MANTISSA,      MACHINE_EMAX,      MACHINE_EMIN,
MACHINE_ROUNDS, and MACHINE_OVERFLOWS (see 13.7.3).

Besides  the  basic  operations,  the  operations  of a floating point type
include the relational operators, and the following  predefined  arithmetic
operators:   the binary and unary adding operators - and +, the multiplying
operators * and /, the unary operator abs, and the exponentiating operator.

The operations of a subtype are the corresponding operations  of  the  type
except  for  the  following:   assignment, membership tests, qualification,
explicit conversion, and the attributes of the first group;  the effects of
these operations are redefined in terms of the subtype.

Notes:

The  attributes  EMAX,  SMALL,  LARGE,  and  EPSILON   are   provided   for
convenience.   They  are all related to MANTISSA by the following formulas:

    T'EMAX    = 4*T'MANTISSA
    T'EPSILON = 2.0**(1 - T'MANTISSA)
    T'SMALL   = 2.0**(-T'EMAX - 1)
    T'LARGE   = 2.0**T'EMAX * (1.0 - 2.0**(-T'MANTISSA))

The attribute MANTISSA, giving the number of binary digits in the mantissa,
is itself related to DIGITS.  The  following  relations  hold  between  the
characteristics of the model numbers and those of the safe numbers:

    T'BASE'EMAX  <= T'SAFE_EMAX
    T'BASE'SMALL >= T'SAFE_SMALL
    T'BASE'LARGE <= T'SAFE_LARGE

The attributes T'FIRST and T'LAST need not yield model or safe numbers.  If
a  certain  number  of  digits is specified in the declaration of a type or
subtype T, the attribute T'DIGITS yields this number.




                                  3 - 45








References:   abs  operator  4.5  4.5.6,  arithmetic  operator  3.5.5  4.5,
assignment  5.2,  attribute  4.1.4,  base  type 3.3, basic operation 3.3.3,
binary adding operator 4.5 4.5.3, bound of a  range  3.5,  constraint  3.3,
conversion  4.6,  digit  2.1,  exponentiating  operator 4.5 4.5.6, floating
point  type  3.5.7,  membership  test  4.5  4.5.2,  model   number   3.5.6,
multiplying  operator  4.5  4.5.5,  numeric type 3.5, object 3.2, operation
3.3, predefined operator 4.5, qualified expression 4.7, relational operator
4.5 4.5.2, safe number 3.5.6, subtype 3.3, type 3.3, unary adding  operator
4.5   4.5.4,   universal   type   4.10,   universal_integer   type   3.5.4,
universal_real type 3.5.6















































                                  3 - 46








3.5.9  Fixed Point Types


For fixed point types, the error bound is specified as an  absolute  value,
called the delta of the fixed point type.

    fixed_point_constraint ::=
       fixed_accuracy_definition [range_constraint]

    fixed_accuracy_definition ::=  delta static_simple_expression

The  delta is specified by the value of the static simple expression of the
fixed accuracy definition.  This value must belong to some  real  type  and
must  be  positive  (nonzero).   If the fixed point constraint is used as a
real type definition, then it must include a range constraint;  each  bound
of  the specified range must be defined by a static expression of some real
type but the two bounds need not have the same real  type.   If  the  fixed
point  constraint  is used in a subtype indication, the range constraint is
optional.

A canonical form is defined for any fixed point  model  number  other  than
zero.   In  this  form:   sign  is either +1 or -1;  mantissa is a positive
(nonzero) integer;  and any  model  number  is  a  multiple  of  a  certain
positive real number called small, as follows:

    sign * mantissa * small

For the model numbers defined by a fixed point constraint, the number small
is chosen as the largest power of two that is not greater than the delta of
the  fixed  accuracy  definition.  Alternatively, it is possible to specify
the value of small by a length clause  (see  13.2),  in  which  case  model
numbers  are  multiples  of  the  specified  value.  The guaranteed minimum
accuracy of operations of a fixed point type is defined  in  terms  of  the
model  numbers  of  the fixed point constraint that forms the corresponding
real type definition (see 4.5.7).

For a fixed point constraint that includes a range  constraint,  the  model
numbers  comprise  zero  and  all  multiples of small whose mantissa can be
expressed using exactly B binary digits, where the value of B is chosen  as
the  smallest integer number for which each bound of the specified range is
either a model number or lies at most small distant from  a  model  number.
For a fixed point constraint that does not include a range constraint (this
is  only  allowed  after  a  type mark, in a subtype indication), the model
numbers are defined by the delta of the fixed accuracy  definition  and  by
the range of the subtype denoted by the type mark.

An  implementation  must have at least one anonymous predefined fixed point
type.  The base type of each such fixed point type is the type itself.  The
model numbers of each predefined fixed point type  comprise  zero  and  all
numbers for which mantissa (in the canonical form) has the number of binary
digits  returned  by the attribute MANTISSA, and for which the number small
has the value returned by the attribute SMALL.

A fixed point type declaration of the form:



                                  3 - 47








    type T is delta D range L .. R;

is, by definition, equivalent to the following declarations:

    type fixed_point_type is new predefined_fixed_point_type;
    subtype T is fixed_point_type
       range fixed_point_type(L) .. fixed_point_type(R);


















































                                  3 - 48








In these declarations, fixed_point_type  is  an  anonymous  type,  and  the
predefined fixed point type is implicitly selected by the implementation so
that its model numbers include the model numbers defined by the fixed point
constraint  (that  is,  by  D,  L,  and  R, and possibly by a length clause
specifying small).

The fixed point declaration is illegal  if  no  predefined  type  satisfies
these  requirements.   The safe numbers of a fixed point type are the model
numbers of its base type.

The  elaboration  of  a  fixed  point  type  declaration  consists  of  the
elaboration of the equivalent type and subtype declarations.

If  the fixed point constraint follows a type mark in a subtype indication,
the type mark must denote a fixed point type or subtype.  The  fixed  point
constraint  is compatible with the type mark only if the delta specified by
the fixed accuracy definition is not smaller than the delta for the type or
subtype denoted  by  the  type  mark.   Furthermore,  if  the  fixed  point
constraint  includes  a  range  constraint,  the  fixed point constraint is
compatible with the type mark only if  the  range  constraint  is,  itself,
compatible with the type mark.

The  elaboration  of  such a subtype indication includes the elaboration of
the range constraint, if there is one;  it creates a  fixed  point  subtype
whose model numbers are defined by the corresponding fixed point constraint
and  also  by the length clause specifying small, if there is one.  A value
of a fixed point type belongs to a fixed point subtype if and  only  if  it
belongs to the range defined by the subtype.

The same arithmetic operators are predefined for all fixed point types (see
4.5).  Multiplication and division of fixed point values deliver results of
an  anonymous predefined fixed point type that is called universal_fixed in
this reference manual;  the accuracy of this type is arbitrarily fine.  The
values of this type must be converted explicitly to some numeric type.

Notes:

If S is a subtype of a fixed point type or subtype T, then the set of model
numbers of S is a subset of those of T.  If a length clause has been  given
for  T,  then both S and T have the same value for small.  Otherwise, since
small is a power of two, the small  of  S  is  equal  to  the  small  of  T
multiplied by a nonnegative power of two.

A  range  constraint is allowed in a fixed point subtype indication, either
directly after the type mark, or as part of a fixed point  constraint.   In
either  case  the  bounds  of the range must belong to the base type of the
type mark (see 3.5).

Examples:

    type VOLT is delta 0.125 range 0.0 .. 255.0;
    subtype ROUGH_VOLTAGE is VOLT delta 1.0;  --  same range as VOLT

    --  A pure fraction which requires all the available space in a word
    --  on a two's complement machine can be declared as the type FRACTION:


                                  3 - 49








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

References:  anonymous type 3.3.1, arithmetic operator 3.5.5 4.5, base type
3.3, belong to a subtype 3.3, bound  of  a  range  3.5,  compatible  3.3.2,
conversion  4.6,  elaboration  3.9,  error bound 3.5.6, length clause 13.2,
model number 3.5.6, numeric type 3.5, operation  3.3,  predefined  operator
4.5,  range  constraint  3.5,  real type 3.5.6, real type definition 3.5.6,
safe number 3.5.6, simple expression 4.4, static  expression  4.9,  subtype
3.3,  subtype  declaration  3.3.2, subtype indication 3.3.2, type 3.3, type
declaration 3.3.1, type mark 3.3.2














































                                  3 - 50








3.5.10  Operations of Fixed Point Types


The basic operations of a fixed point type include the operations  involved
in  assignment, membership tests, qualification, the explicit conversion of
values of other numeric types to the fixed point  type,  and  the  implicit
conversion of values of the type universal_real to the type.

In  addition,  for every fixed point type or subtype T the basic operations
include the attributes listed below.  In this presentation T is referred to
as being a subtype (the  subtype  T)  for  any  property  that  depends  on
constraints imposed by T;  other properties are stated in terms of the base
type of T.

The  first group of attributes yield characteristics of the subtype T.  The
attributes  of  this  group  are  the  attributes  BASE  (see  3.3.2),  the
attributes FIRST and LAST (see 3.5), the representation attribute SIZE (see
13.7.2) and the following attributes:

T'DELTA      Yields the value of the delta specified in the fixed  accuracy
             definition  for the subtype T.  The value of this attribute is
             of the type universal_real.

T'MANTISSA   Yields the number of binary digits in the  mantissa  of  model
             numbers of the subtype T.  (This attribute yields the number B
             of section 3.5.9.)  The value of this attribute is of the type
             universal_integer.

T'SMALL      Yields the smallest positive (nonzero)  model  number  of  the
             subtype  T.   The  value  of  this  attribute  is  of the type
             universal_real.

T'LARGE      Yields the largest positive model number  of  the  subtype  T.
             The value of this attribute is of the type universal_real.

T'FORE       Yields the minimum number of characters needed for the integer
             part of the decimal representation of any value of the subtype
             T,  assuming  that  the  representation  does  not  include an
             exponent, but includes a one-character prefix that is either a
             minus sign or a space.  (This minimum number does not  include
             superfluous  zeros  or  underlines, and is at least two.)  The
             value of this attribute is of the type universal_integer.

T'AFT        Yields the number of decimal digits needed after the point  to
             accommodate  the  precision of the subtype T, unless the delta
             of the subtype T is  greater  than  0.1,  in  which  case  the
             attribute  yields  the  value  one.   (T'AFT  is  the smallest
             positive integer N for which (10**N)*T'DELTA is  greater  than
             or  equal to one.)  The value of this attribute is of the type
             universal_integer.

The attributes of the second group include the following  attributes  which
yield characteristics of the safe numbers:




                                  3 - 51








T'SAFE_SMALL Yields the smallest positive (nonzero) safe number of the base
             type  of  T.   The  value  of  this  attribute  is of the type
             universal_real.

T'SAFE_LARGE Yields the largest positive safe number of the base type of T.
             The value of this attribute is of the type universal_real.

In addition, the attributes A'SIZE and A'ADDRESS are defined for an  object
A  of  a fixed point type (see 13.7.2).  Finally, for each fixed point type
or subtype T, there are the machine-dependent  attributes  T'MACHINE_ROUNDS
and T'MACHINE_OVERFLOWS (see 13.7.3).














































                                  3 - 52








Besides  the basic operations, the operations of a fixed point type include
the  relational  operators,  and  the   following   predefined   arithmetic
operators:   the binary and unary adding operators - and +, the multiplying
operators * and /, and the operator abs.

The operations of a subtype are the corresponding operations  of  the  type
except  for  the  following:   assignment, membership tests, qualification,
explicit conversion, and the attributes of the first group;  the effects of
these operations are redefined in terms of the subtype.

Notes:

The value of the attribute T'FORE depends only on the range of the  subtype
T.   The value of the attribute T'AFT depends only on the value of T'DELTA.
The following relations exist between attributes of a fixed point type:

    T'LARGE      = (2**T'MANTISSA - 1) * T'SMALL
    T'SAFE_LARGE = T'BASE'LARGE
    T'SAFE_SMALL = T'BASE'SMALL

References:   abs  operator  4.5  4.5.6,  arithmetic  operator  3.5.5  4.5,
assignment  5.2,  base  type  3.3,  basic  operation  3.3.3,  binary adding
operator 4.5 4.5.3, bound of a range  3.5,  conversion  4.6,  delta  3.5.9,
fixed  point  type  3.5.9,  membership  test 4.5 4.5.2, model number 3.5.6,
multiplying operator 4.5 4.5.5, numeric type  3.5,  object  3.2,  operation
3.3,  qualified  expression 4.7, relational operator 4.5 4.5.2, safe number
3.5.6, subtype 3.3, unary adding operator 4.5 4.5.4, universal_integer type
3.5.4, universal_real type 3.5.6



3.6  Array Types


An array object is a composite object consisting of  components  that  have
the  same  subtype.   The name for a component of an array uses one or more
index values belonging to specified discrete types.  The value of an  array
object is a composite value consisting of the values of its components.

    array_type_definition ::=
       unconstrained_array_definition | constrained_array_definition

    unconstrained_array_definition ::=
       array(index_subtype_definition {, index_subtype_definition}) of
                component_subtype_indication

    constrained_array_definition ::=
       array index_constraint of component_subtype_indication

    index_subtype_definition ::= type_mark range <>

    index_constraint ::=  (discrete_range {, discrete_range})

    discrete_range ::= discrete_subtype_indication | range



                                  3 - 53








An   array   object   is  characterized  by  the  number  of  indices  (the
dimensionality of the array), the type and  position  of  each  index,  the
lower and upper bounds for each index, and the type and possible constraint
of the components.  The order of the indices is significant.





















































                                  3 - 54








A  one-dimensional  array  has a distinct component for each possible index
value.  A multidimensional array has a distinct component for each possible
sequence of index values that can be formed by  selecting   one  value  for
each  index position (in the given order).  The possible values for a given
index are all the values between the lower  and  upper  bounds,  inclusive;
this range of values is called the index range.

An  unconstrained  array definition defines an array type.  For each object
that has the array type, the number of indices, the type  and  position  of
each  index,  and  the  subtype  of  the  components  are  as  in  the type
definition;  the values of the lower and upper bounds for each index belong
to the corresponding index subtype, except for null arrays as explained  in
section  3.6.1.   The  index  subtype  for  a  given  index position is, by
definition, the subtype denoted by the type mark of the corresponding index
subtype definition.  The compound delimiter <> (called a box) of  an  index
subtype  definition stands for an undefined range (different objects of the
type need not have the same bounds).  The elaboration of  an  unconstrained
array  definition creates an array type;  this elaboration includes that of
the component subtype indication.

A constrained array definition defines both an array type and a subtype  of
this type:

  -  The array type is an implicitly declared anonymous type;  this type is
     defined  by an (implicit) unconstrained array definition, in which the
     component  subtype  indication  is  that  of  the  constrained   array
     definition,  and  in  which  the  type  mark  of  each  index  subtype
     definition denotes the subtype defined by the  corresponding  discrete
     range.

  -  The array subtype is the subtype obtained by imposition of  the  index
     constraint on the array type.

If  a  constrained  array  definition  is given for a type declaration, the
simple name declared by this declaration denotes the array subtype.

The elaboration of a constrained array definition creates the corresponding
array type and array subtype.  For this elaboration, the  index  constraint
and  the  component  subtype  indication are elaborated.  The evaluation of
each discrete range of the index constraint  and  the  elaboration  of  the
component  subtype  indication  are  performed  in  some  order that is not
defined by the language.

Examples of type declarations with unconstrained array definitions:

    type VECTOR     is array(INTEGER  range <>) of REAL;
    type MATRIX     is array(INTEGER  range <>, INTEGER range <>) of REAL;
    type BIT_VECTOR is array(INTEGER  range <>) of BOOLEAN;
    type ROMAN      is array(POSITIVE range <>) of ROMAN_DIGIT;

Examples of type declarations with constrained array definitions:

    type TABLE    is array(1 .. 10) of INTEGER;
    type SCHEDULE is array(DAY) of BOOLEAN;
    type LINE     is array(1 .. MAX_LINE_SIZE) of CHARACTER;


                                  3 - 55








Examples of object declarations with constrained array definitions:

    GRID : array(1 .. 80, 1 .. 100) of BOOLEAN;
    MIX  : array(COLOR range RED .. GREEN) of BOOLEAN;
    PAGE : array(1 .. 50) of LINE;  --  an array of arrays




















































                                  3 - 56








Note:

For a one-dimensional array, the rule given means that a  type  declaration
with a constrained array definition such as

    type T is array(POSITIVE range MIN .. MAX) of COMPONENT;

is  equivalent  (in  the  absence  of an incorrect order dependence) to the
succession of declarations

    subtype INDEX_SUBTYPE is POSITIVE range MIN .. MAX;
    type ARRAY_TYPE is array(INDEX_SUBTYPE range <>) of COMPONENT;
    subtype T is ARRAY_TYPE(INDEX_SUBTYPE);

where index_subtype and array_type are both anonymous.  Consequently, T  is
the  name  of  a  subtype  and all objects declared with this type mark are
arrays that  have  the  same  bounds.   Similar  transformations  apply  to
multidimensional arrays.

A  similar transformation applies to an object whose declaration includes a
constrained array definition.  A consequence of this is that  no  two  such
objects have the same type.

References:   anonymous  type  3.3.1,  bound of a range 3.5, component 3.3,
constraint 3.3, discrete type 3.5, elaboration 3.1 3.9, in some order  1.6,
name  4.1,  object  3.2,  range 3.5, subtype 3.3, subtype indication 3.3.2,
type 3.3, type declaration 3.3.1, type definition 3.3.1, type mark 3.3.2



3.6.1  Index Constraints and Discrete Ranges


An index constraint determines the range of possible values for every index
of an array type, and thereby the corresponding array bounds.

For a discrete range used in a constrained array definition and defined  by
a  range,  an implicit conversion to the predefined type INTEGER is assumed
if each bound is either a numeric literal, a named number, or an attribute,
and the type of both bounds (prior to the implicit conversion) is the  type
universal_integer.   Otherwise,  both  bounds  must be of the same discrete
type,  other  than  universal_integer;   this  type  must  be  determinable
independently  of  the  context,  but  using the fact that the type must be
discrete and that both bounds must have the same type.  These  rules  apply
also  to  a  discrete  range  used in an iteration rule (see 5.5) or in the
declaration of a family of entries (see 9.5).

If an index constraint follows a type mark in a  subtype  indication,  then
the  type  or  subtype  denoted by the type mark must not already impose an
index constraint.  The type mark must denote either an unconstrained  array
type  or  an  access  type whose designated type is such an array type.  In
either case, the index constraint must provide a discrete  range  for  each
index  of  the  array  type and the type of each discrete range must be the
same as that of the corresponding index.



                                  3 - 57








An index constraint is compatible with the type denoted by the type mark if
and only if the constraint defined by each  discrete  range  is  compatible
with  the  corresponding  index  subtype.   If  any  of the discrete ranges
defines a null range, any array thus constrained is a null array, having no
components.  An array value satisfies an index constraint if at each  index
position  the  array  value  and  the  index constraint have the same index
bounds.  (Note,  however, that assignment and certain other  operations  on
arrays involve an implicit subtype conversion.)

















































                                  3 - 58








The bounds of each array object are determined as follows:

  -  For  a  variable  declared  by  an  object  declaration,  the  subtype
     indication  of  the  corresponding  object  declaration  must define a
     constrained array  subtype  (and,  thereby,  the  bounds).   The  same
     requirement   exists   for  the  subtype  indication  of  a  component
     declaration, if the type of the record component  is  an  array  type;
     and  for the component subtype indication of an array type definition,
     if the type of the array components is itself an array type.

  -  For a constant declared by an object declaration, the  bounds  of  the
     constant  are  defined  by  the  initial  value  if the subtype of the
     constant is unconstrained;  they are otherwise defined by this subtype
     (in the latter case, the initial value is the result  of  an  implicit
     subtype  conversion).   The  same  rule  applies  to  a generic formal
     parameter of mode in.

  -  For an array object designated by an access value, the bounds must  be
     defined  by  the  allocator  that  creates  the  array  object.   (The
     allocated object is constrained with the corresponding values  of  the
     bounds.)

  -  For a formal parameter of  a  subprogram  or  entry,  the  bounds  are
     obtained   from  the  corresponding  actual  parameter.   (The  formal
     parameter is constrained with the corresponding values of the bounds.)

  -  For a renaming declaration and for a generic formal parameter of  mode
     in  out,  the  bounds  are  those  of  the  renamed  object  or of the
     corresponding generic actual parameter.

For the elaboration  of  an  index  constraint,  the  discrete  ranges  are
evaluated in some order that is not defined by the language.

Examples of array declarations including an index constraint:

    BOARD     : MATRIX(1 .. 8,  1 .. 8);  --  see 3.6
    RECTANGLE : MATRIX(1 .. 20, 1 .. 30);
    INVERSE   : MATRIX(1 .. N,  1 .. N);  --  N need not be static

    FILTER    : BIT_VECTOR(0 .. 31);

Example of array declaration with a constrained array subtype:

    MY_SCHEDULE : SCHEDULE;  --  all arrays of type SCHEDULE have the same bounds

Example of record type with a component that is an array:

    type VAR_LINE(LENGTH : INTEGER) is
       record
          IMAGE : STRING(1 .. LENGTH);
       end record;

    NULL_LINE : VAR_LINE(0);  --  NULL_LINE.IMAGE is a null array




                                  3 - 59








Notes:

The  elaboration of a subtype indication consisting of a type mark followed
by an index constraint checks the compatibility  of  the  index  constraint
with the type mark (see 3.3.2).

All  components  of  an array have the same subtype.  In particular, for an
array of components that are one-dimensional arrays, this  means  that  all
components have the same  bounds and hence the same length.
















































                                  3 - 60








References:  access type 3.8, access type definition 3.8, access value 3.8,
actual  parameter  6.4.1,  allocator  4.8, array bound 3.6, array component
3.6, array type 3.6, array type definition  3.6,  bound  of  a  range  3.5,
compatible  3.3.2,  component  declaration 3.7, constant 3.2.1, constrained
array definition  3.6,  constrained  array  subtype  3.6,  conversion  4.6,
designate  3.8,  designated  type 3.8, discrete range 3.6, entry 9.5, entry
family declaration 9.5, expression 4.4, formal parameter 6.1, function 6.5,
generic actual parameter 12.3, generic formal parameter 12.1 12.3,  generic
parameter  12.1,  index  3.6,  index  constraint  3.6.1, index subtype 3.6,
initial value 3.2.1, integer literal 2.4,  integer  type  3.5.4,  iteration
rule  5.5,  mode  12.1.1,  name  4.1,  null  range  3.5, object 3.2, object
declaration 3.2.1, predefined type C,  range  3.5,  record  component  3.7,
renaming  declaration  8.5,  result subtype 6.1, satisfy 3.3, subprogram 6,
subtype  conversion  4.6,  subtype  indication  3.3.2,  type  mark   3.3.2,
unconstrained  array  type  3.6,  unconstrained subtype 3.3, universal type
4.10, universal_integer type 3.5.4, variable 3.2.1



3.6.2  Operations of Array Types


The basic operations of an array type include the  operations  involved  in
assignment  and  aggregates  (unless the array type is limited), membership
tests, indexed components, qualification,  and  explicit  conversion;   for
one-dimensional  arrays  the  basic  operations also include the operations
involved in slices, and also string literals if the  component  type  is  a
character type.

If  A  is  an array object, an array value, or a constrained array subtype,
the basic operations also  include  the  attributes  listed  below.   These
attributes are not allowed for an unconstrained array type.  The argument N
used  in  the attribute designators for the N-th dimension of an array must
be a static expression of type universal_integer.  The value of N  must  be
positive (nonzero) and no greater than the dimensionality of the array.

A'FIRST         Yields the lower bound of the first index range.  The value
                of this attribute has the same type as this lower bound.

A'FIRST(N)      Yields the lower bound of the N-th index range.  The  value
                of this attribute has the same type as this lower bound.

A'LAST          Yields the upper bound of the first index range.  The value
                of this attribute has the same type as this upper bound.

A'LAST(N)       Yields the upper bound of the N-th index range.  The  value
                of this attribute has the same type as this upper bound.

A'RANGE         Yields the first index range, that is, the range A'FIRST ..
                A'LAST.

A'RANGE(N)      Yields the N-th index range, that is, the range  A'FIRST(N)
                .. A'LAST(N).




                                  3 - 61








A'LENGTH        Yields the number of values of the first index range  (zero
                for  a  null range).  The value of this attribute is of the
                type universal_integer.

A'LENGTH(N)     Yields the number of values of the N-th index  range  (zero
                for  a  null range).  The value of this attribute is of the
                type universal_integer.

In addition, the attribute T'BASE is defined for an array type or subtype T
(see 3.3.3);  the attribute T'SIZE is defined for an array type or  subtype
T,  and the attributes A'SIZE and A'ADDRESS are defined for an array object
A (see 13.7.2).













































                                  3 - 62








Besides the basic operations, the operations of an array type  include  the
predefined comparison for equality and inequality, unless the array type is
limited.   For  one-dimensional  arrays, the operations include catenation,
unless the array type is limited;  if the  component  type  is  a  discrete
type,  the operations also include all predefined relational operators;  if
the component type is a boolean type, then the operations also include  the
unary logical negation operator not, and the logical operators.

Examples (using arrays declared in the examples of section 3.6.1):

    --  FILTER'FIRST       =    0   FILTER'LAST        =  31   FILTER'LENGTH  =  32
    --  RECTANGLE'LAST(1)  =   20   RECTANGLE'LAST(2)  =  30

Notes:

The  attributes  A'FIRST  and  A'FIRST(1)  yield the same value.  A similar
relation exists for the attributes  A'LAST,  A'RANGE,  and  A'LENGTH.   The
following  relations  are  satisfied (except for a null array) by the above
attributes if the index type is an integer type:

    A'LENGTH    = A'LAST    - A'FIRST    + 1
    A'LENGTH(N) = A'LAST(N) - A'FIRST(N) + 1

An array type is limited if its component type is limited (see 7.4.4).

References:  aggregate 4.3,  array  type  3.6,  assignment  5.2,  attribute
4.1.4, basic operation 3.3.3, bound of a range 3.5, catenation operator 4.5
4.5.3, character type 3.5.2, constrained array subtype 3.6, conversion 4.6,
designator  6.1, dimension 3.6, index 3.6, indexed component 4.1.1, limited
type 7.4.4, logical operator 4.5 4.5.1,  membership  test  4.5  4.5.2,  not
operator  4.5  4.5.6, null range 3.5, object 3.2, operation 3.3, predefined
operator 4.5, qualified expression  4.7,  relational  operator  4.5  4.5.2,
slice  4.1.2,  static expression 4.9, string literal 2.6, subcomponent 3.3,
type  3.3,   unconstrained   array   type   3.6,   universal   type   4.10,
universal_integer type 3.5.4



3.6.3  The Type String


The  values of the predefined type STRING are one-dimensional arrays of the
predefined type CHARACTER, indexed by  values  of  the  predefined  subtype
POSITIVE:

    subtype POSITIVE is INTEGER range 1 .. INTEGER'LAST;
    type STRING is array(POSITIVE range <>) of CHARACTER;

Examples:

    STARS      : STRING(1 .. 120) := (1 .. 120 => '*' );
    QUESTION   : constant STRING  := "HOW MANY CHARACTERS?";
    --  QUESTION'FIRST = 1, QUESTION'LAST = 20 (the number of characters)




                                  3 - 63








    ASK_TWICE  : constant STRING  := QUESTION & QUESTION;
    NINETY_SIX : constant ROMAN   := "XCVI";        --  see 3.6

Notes:

String  literals  (see  2.6 and 4.2) are basic operations applicable to the
type STRING and to any other one-dimensional  array  type  whose  component
type is a character type.  The catenation operator is a predefined operator
for the type STRING and for one-dimensional array types;  it is represented
as  &.  The relational operators <, <=, >, and >= are defined for values of
these types, and correspond to lexicographic order (see 4.5.2).














































                                  3 - 64








References:  aggregate 4.3,  array  3.6,  catenation  operator  4.5  4.5.3,
character  type  3.5.2,  component  type  (of an array) 3.6, dimension 3.6,
index 3.6, lexicographic order 4.5.2, positional aggregate 4.3,  predefined
operator  4.5,  predefined  type  C,  relational operator 4.5 4.5.2, string
literal 2.6, subtype 3.3, type 3.3



3.7  Record Types


A record object is a composite object consisting of named components.   The
value  of  a record object is a composite value consisting of the values of
its components.

    record_type_definition ::=
       record
          component_list
       end record

    component_list ::=
          component_declaration {component_declaration}
       | {component_declaration} variant_part
       |  null;

    component_declaration ::=
       identifier_list : component_subtype_definition [:= expression];

    component_subtype_definition ::=  subtype_indication

Each component  declaration  declares  a  component  of  the  record  type.
Besides  components declared by component declarations, the components of a
record type include any components declared by discriminant  specifications
of  the  record  type  declaration.  The identifiers of all components of a
record type must be distinct.  The use of a  name  that  denotes  a  record
component  other  than a discriminant is not allowed within the record type
definition that declares the component.

A component  declaration  with  several  identifiers  is  equivalent  to  a
sequence  of  single  component  declarations, as explained in section 3.2.
Each single component declaration declares a record component whose subtype
is specified by the component subtype definition.

If a component  declaration  includes  the  assignment  compound  delimiter
followed  by an expression, the expression is the default expression of the
record component;  the default expression  must  be  of  the  type  of  the
component.   Default expressions are not allowed for components that are of
a limited type.

If a record type does not have a discriminant part, the same components are
present in all values of the type.  If the component list of a record  type
is  defined  by  the  reserved word null and there is no discriminant part,
then the record type has no components and all records of the type are null
records.



                                  3 - 65








The elaboration of a record type definition  creates  a  record  type;   it
consists  of  the  elaboration  of  any  corresponding  (single)  component
declarations, in the order in which they appear,  including  any  component
declaration  in a variant part.  The elaboration of a component declaration
consists of the elaboration of the component subtype definition.

For the elaboration of a component subtype definition,  if  the  constraint
does  not depend on a discriminant (see 3.7.1), then the subtype indication
is elaborated.  If,  on  the  other  hand,  the  constraint  depends  on  a
discriminant,  then  the  elaboration  consists  of  the  evaluation of any
included expression that is not a discriminant.














































                                  3 - 66








Examples of record type declarations:

    type DATE is
       record
          DAY   : INTEGER range 1 .. 31;
          MONTH : MONTH_NAME;
          YEAR  : INTEGER range 0 .. 4000;
       end record;

    type COMPLEX is
       record
          RE : REAL := 0.0;
          IM : REAL := 0.0;
       end record;

Examples of record variables:

    TOMORROW, YESTERDAY : DATE;
    A, B, C : COMPLEX;

    -- both components of A, B, and C are implicitly initialized to zero

Notes:

The default expression of a record component is implicitly evaluated by the
elaboration of the declaration of a record object, in  the  absence  of  an
explicit  initialization  (see  3.2.1).   If  a  component  declaration has
several identifiers,  the  expression  is  evaluated  once  for  each  such
component  of the object (since the declaration is equivalent to a sequence
of single component declarations).

Unlike the components of an array, the components of a record need  not  be
of the same type.

References:   assignment  compound  delimiter 2.2, component 3.3, composite
value 3.3, constraint 3.3, declaration 3.1, depend on a discriminant 3.7.1,
discriminant 3.3, discriminant part 3.7 3.7.1, elaboration 3.9,  expression
4.4,  identifier  2.3,  identifier  list 3.2, limited type 7.4.4, name 4.1,
object 3.2, subtype 3.3, type 3.3, type mark 3.3.2, variant part 3.7.3



3.7.1  Discriminants


A discriminant part specifies the discriminants of a type.  A  discriminant
of  a record is a component of the record.  The type of a discriminant must
be discrete.

    discriminant_part ::=
       (discriminant_specification {; discriminant_specification})

    discriminant_specification ::=
       identifier_list : type_mark [:= expression]



                                  3 - 67








A discriminant part is only allowed in the type declaration  for  a  record
type,  in a private type declaration or an incomplete type declaration (the
corresponding full declaration must then declare a record type), and in the
generic parameter declaration for a formal private type.





















































                                  3 - 68








A discriminant specification with several identifiers is  equivalent  to  a
sequence  of  single  discriminant  specifications, as explained in section
3.2.  Each single discriminant specification declares a discriminant.  If a
discriminant  specification  includes  the  assignment  compound  delimiter
followed  by an expression, the expression is the default expression of the
discriminant;   the  default  expression  must  be  of  the  type  of   the
discriminant.   Default  expressions must be provided either for all or for
none of the discriminants of a discriminant part.

The use of the name of a discriminant is not allowed in default expressions
of a discriminant part if the specification of the discriminant  is  itself
given in the discriminant part.

Within  a  record  type  definition  the only allowed uses of the name of a
discriminant of the record type are:  in the default expressions for record
components;  in a  variant  part  as  the  discriminant  name;   and  in  a
component  subtype definition, either as a bound in an index constraint, or
to  specify  a  discriminant  value  in  a  discriminant   constraint.    A
discriminant  name  used in these component subtype definitions must appear
by itself, not as part of a  larger  expression.   Such  component  subtype
definitions and such constraints are said to depend on a discriminant.

A component is said to depend on a discriminant if it is a record component
declared  in  a variant part, or a record component whose component subtype
definition depends on a discriminant, or finally, one of the  subcomponents
of a component that itself depends on a discriminant.

Each  record value includes a value for each discriminant specified for the
record type;  it also includes a value for each record component that  does
not  depend  on  a discriminant.  The values of the discriminants determine
which other component values are in the record value.

Direct  assignment  to  a  discriminant  of  an  object  is  not   allowed;
furthermore a discriminant is not allowed as an actual parameter of mode in
out  or  out,  or  as  a generic actual parameter of mode in out.  The only
allowed way to change the value of a  discriminant  of  a  variable  is  to
assign a (complete) value to the variable itself.  Similarly, an assignment
to  the variable itself is the only allowed way to change the constraint of
one of its components, if the component subtype  definition  depends  on  a
discriminant of the variable.

The elaboration of a discriminant part has no other effect.

Examples:

    type BUFFER(SIZE : BUFFER_SIZE := 100) is        -- see 3.5.4
       record
          POS   : BUFFER_SIZE := 0;
          VALUE : STRING(1 .. SIZE);
       end record;

    type SQUARE(SIDE : INTEGER) is
       record
          MAT : MATRIX(1 .. SIDE, 1 .. SIDE);       -- see 3.6
       end record;


                                  3 - 69








    type DOUBLE_SQUARE(NUMBER : INTEGER) is
       record
          LEFT  : SQUARE(NUMBER);
          RIGHT : SQUARE(NUMBER);
       end record;




















































                                  3 - 70








    type ITEM(NUMBER : POSITIVE) is
       record
          CONTENT : INTEGER;
          --  no component depends on the discriminant
       end record;

References:   assignment 5.2, assignment compound delimiter 2.2, bound of a
range 3.5, component 3.3, component declaration 3.7, component of a  record
3.7,  declaration  3.1,  discrete  type 3.5, discriminant 3.3, discriminant
constraint 3.7.2, elaboration 3.9,  expression  4.4,  generic  formal  type
12.1,  generic  parameter declaration 12.1, identifier 2.3, identifier list
3.2, incomplete type declaration 3.8.1, index constraint 3.6.1,  name  4.1,
object  3.2,  private  type  7.4, private type declaration 7.4, record type
3.7, scope 8.2, simple  name  4.1,  subcomponent  3.3,  subtype  indication
3.3.2, type declaration 3.3.1, type mark 3.3.2, variant part 3.7.3




3.7.2  Discriminant Constraints


A  discriminant constraint is only allowed in a subtype indication, after a
type mark.  This type mark must denote either a type with discriminants, or
an access type whose designated type  is  a  type  with  discriminants.   A
discriminant constraint specifies the values of these discriminants.

    discriminant_constraint ::=
       (discriminant_association {, discriminant_association})

    discriminant_association ::=
       [discriminant_simple_name {| discriminant_simple_name} =>] expression

Each  discriminant  association  associates  an expression with one or more
discriminants.  A discriminant association is  said  to  be  named  if  the
discriminants  are  specified  explicitly  by their names;  it is otherwise
said  to  be  positional.   For  a  positional  association,  the  (single)
discriminant  is implicitly specified by position, in textual order.  Named
associations can be given in any order, but if both  positional  and  named
associations  are used in the same discriminant constraint, then positional
associations must occur first, at their  normal  position.   Hence  once  a
named association is used, the rest of the discriminant constraint must use
only named associations.

For  a  named  discriminant association, the discriminant names must denote
discriminants of the type for which the discriminant constraint  is  given.
A  discriminant  association  with  more than one discriminant name is only
allowed if the named discriminants are all of the same type.   Furthermore,
for  each  discriminant  association  (whether  named  or  positional), the
expression and the associated discriminants must have  the  same  type.   A
discriminant   constraint   must   provide   exactly  one  value  for  each
discriminant of the type.

A discriminant constraint is compatible with the type  denoted  by  a  type
mark,  if and only if each discriminant value belongs to the subtype of the


                                  3 - 71








corresponding discriminant.   In  addition,  for  each  subcomponent  whose
component   subtype   specification   depends   on    a  discriminant,  the
discriminant value is substituted for the discriminant  in  this  component
subtype  specification  and  the  compatibility  of  the  resulting subtype
indication is checked.

A composite value satisfies a discriminant constraint if and only  if  each
discriminant   of  the  composite  value  has  the  value  imposed  by  the
discriminant constraint.
















































                                  3 - 72








The initial values of the  discriminants  of  an  object  of  a  type  with
discriminants are determined as follows:

  -  For  a  variable  declared  by  an  object  declaration,  the  subtype
     indication  of  the  corresponding  object  declaration  must impose a
     discriminant constraint  unless  default  expressions  exist  for  the
     discriminants;   the  discriminant  values  are  defined either by the
     constraint or, in its absence, by the default expressions.   The  same
     requirement   exists   for  the  subtype  indication  of  a  component
     declaration, if the type of the record  component  has  discriminants;
     and for the component subtype indication of an array type, if the type
     of the array components is a type with discriminants.

  -  For a constant declared by an object declaration, the  values  of  the
     discriminants  are  those  of  the initial value if the subtype of the
     constant is unconstrained;  they are otherwise defined by this subtype
     (in the latter case, an exception is raised if the initial value  does
     not  belong  to  this  subtype).   The  same rule applies to a generic
     parameter of mode in.

  -  For an object designated by an access value, the  discriminant  values
     must  be  defined  by  the  allocator  that  creates the object.  (The
     allocated object is constrained with  the  corresponding  discriminant
     values.)

  -  For a formal parameter of a subprogram or entry, the discriminants  of
     the  formal  parameter are initialized with those of the corresponding
     actual  parameter.   (The  formal  parameter  is  constrained  if  the
     corresponding  actual parameter is constrained, and in any case if the
     mode is in or if the subtype of the formal parameter is  constrained.)

  -  For a renaming declaration and for a generic formal parameter of  mode
     in  out,  the  discriminants are those of the renamed object or of the
     corresponding generic actual parameter.

For the elaboration of a discriminant constraint, the expressions given  in
the  discriminant  associations  are  evaluated  in  some order that is not
defined by  the  language;   the  expression  of  a  named  association  is
evaluated once for each named discriminant.

Examples (using types declared in the previous section):

    LARGE   : BUFFER(200);  --  constrained, always 200 characters (explicit discriminant value)
    MESSAGE : BUFFER;       --  unconstrained, initially 100 characters (default discriminant value)

    BASIS   : SQUARE(5);    --  constrained, always 5 by 5
    ILLEGAL : SQUARE;       --  illegal, a SQUARE must be constrained

Note:

The  above  rules  and  the  rules  defining  the  elaboration of an object
declaration (see 3.2) ensure that discriminants always have  a  value.   In
particular,   if   a  discriminant  constraint  is  imposed  on  an  object
declaration, each discriminant is initialized with the value  specified  by
the   constraint.    Similarly,  if  the  subtype  of  a  component  has  a


                                  3 - 73








discriminant  constraint,  the   discriminants   of   the   component   are
correspondingly initialized.

References:  access type 3.8, access type definition 3.8, access value 3.8,
actual  parameter 6.4.1, allocator 4.8, array type definition 3.6, bound of
a range 3.5, compatible 3.3.2, component 3.3,  component  declaration  3.7,
component  subtype  indication  3.7,  composite  value 3.3, constant 3.2.1,
constrained  subtype  3.3,  constraint  3.3,   declaration   3.1,   default
expression  for  a  discriminant  3.7,  depend  on  a  discriminant  3.7.1,
designate 3.8, designated type  3.8,  discriminant  3.3,  elaboration  3.9,
entry  9.5,  evaluation  4.5, expression 4.4, formal parameter 6.1, generic
actual parameter 12.3, generic formal parameter 12.1  12.3,  mode  in  6.1,
mode  in  out 6.1, name 4.1, object 3.2, object declaration 3.2.1, renaming
declaration  8.5,  reserved  word  2.9,  satisfy  3.3,  simple  name   4.1,
subcomponent 3.3, subprogram 6, subtype 3.3, subtype indication 3.3.2, type
3.3, type mark 3.3.2, variable 3.2.1









































                                  3 - 74








3.7.3  Variant Parts


A   record  type  with  a  variant  part  specifies  alternative  lists  of
components.  Each variant defines  the  components  for  the  corresponding
value or values of the discriminant.

    variant_part ::=
       case discriminant_simple_name is
           variant
          {variant}
       end case;

    variant ::=
       when choice {| choice} =>
          component_list

    choice ::= simple_expression
       | discrete_range | others | component_simple_name

Each  variant  starts with a list of choices which must be of the same type
as the discriminant of the variant part.  The type of the discriminant of a
variant part must not be a generic formal type.   If  the  subtype  of  the
discriminant is static, then each value of this subtype must be represented
once  and only once in the set of choices of the variant part, and no other
value is allowed.   Otherwise,  each  value  of  the  (base)  type  of  the
discriminant  must be represented once and only once in the set of choices.

The simple expressions and discrete ranges given as choices  in  a  variant
part  must  be static.  A choice defined by a discrete range stands for all
values in the corresponding range (none  if  a  null  range).   The  choice
others  is  only  allowed  for the last variant and as its only choice;  it
stands for all values (possibly none) not given in the choices of  previous
variants.   A component simple name is not allowed as a choice of a variant
(although it is part of the syntax of choice).

A record value contains the values of the components of a given variant  if
and  only if the discriminant value is equal to one of the values specified
by the choices of the variant.  This rule applies in turn  to  any  further
variant  that  is,  itself,  included  in  the  component list of the given
variant.  If the component list of a variant  is  specified  by  null,  the
variant has no components.

Example of record type with a variant part:

    type DEVICE is (PRINTER, DISK, DRUM);
    type STATE  is (OPEN, CLOSED);

    type PERIPHERAL(UNIT : DEVICE := DISK) is
       record
          STATUS : STATE;
          case UNIT is
             when PRINTER =>
                LINE_COUNT : INTEGER range 1 .. PAGE_SIZE;
             when others =>


                                  3 - 75








                CYLINDER   : CYLINDER_INDEX;
                TRACK      : TRACK_NUMBER;
          end case;
       end record;





















































                                  3 - 76








Examples of record subtypes:

    subtype DRUM_UNIT is PERIPHERAL(DRUM);
    subtype DISK_UNIT is PERIPHERAL(DISK);

Examples of constrained record variables:

    WRITER  : PERIPHERAL(UNIT => PRINTER);
    ARCHIVE : DISK_UNIT;

Note:

Choices  with discrete values are also used in case statements and in array
aggregates.  Choices  with  component  simple  names  are  used  in  record
aggregates.

References:  array aggregate 4.3.2, base type 3.3, component 3.3, component
list 3.7, discrete range 3.6, discriminant 3.3, generic formal type 12.1.2,
null  range 3.5, record aggregate 4.3.1, range 3.5, record type 3.7, simple
expression  4.4,  simple  name  4.1,  static  discrete  range  4.9,  static
expression 4.9, static subtype 4.9, subtype 3.3




3.7.4  Operations of Record Types


The  basic  operations  of a record type include the operations involved in
assignment and aggregates (unless the type is limited),  membership  tests,
selection  of  record  components,  qualification, and type conversion (for
derived types).

For any object A of a type with discriminants, the  basic  operations  also
include the following attribute:

A'CONSTRAINED   Yields the value TRUE if a discriminant constraint  applies
                to  the object A, or if the object is a constant (including
                a formal parameter or generic formal parameter of mode in);
                yields the value FALSE otherwise.  If A is a generic formal
                parameter of mode in out, or if A is a formal parameter  of
                mode  in  out  or  out  and  the  type  mark  given  in the
                corresponding   parameter    specification    denotes    an
                unconstrained  type  with  discriminants, then the value of
                this attribute is obtained from that of  the  corresponding
                actual  parameter.   The  value of this attribute is of the
                predefined type BOOLEAN.

In addition, the attributes T'BASE and T'SIZE are defined for a record type
or subtype T (see 3.3.3);  the attributes A'SIZE and A'ADDRESS are  defined
for a record object A (see 13.7.2).

Besides  the  basic operations, the operations of a record type include the
predefined comparison for equality  and  inequality,  unless  the  type  is
limited.


                                  3 - 77








Note:

A  record  type  is limited if the type of any of its components is limited
(see 7.4.4).

References:   actual  parameter  6.4.1,  aggregate  4.3,  assignment   5.2,
attribute 4.1.4, basic operation 3.3.3, boolean type 3.5.3, constant 3.2.1,
conversion 4.6, derived type 3.4, discriminant 3.3, discriminant constraint
3.7.2,  formal parameter 6.1, generic actual parameter 12.3, generic formal
parameter 12.1 12.3, limited type 7.4.4, membership test  4.5  4.5.2,  mode
6.1,  object 3.2.1, operation 3.3, predefined operator 4.5, predefined type
C, qualified expression 4.7,  record  type  3.7,  relational  operator  4.5
4.5.2, selected component 4.1.3, subcomponent 3.3, subtype 3.3, type 3.3












































                                  3 - 78








3.8  Access Types


An  object  declared by an object declaration is created by the elaboration
of the object declaration and is denoted by a simple name or by some  other
form  of  name.   In  contrast,  there  are objects that are created by the
evaluation of allocators (see 4.8) and that have no simple name.  Access to
such an object is achieved by an access value  returned  by  an  allocator;
the access value is said to designate the object.

    access_type_definition ::= access subtype_indication

For each access type, there is a literal null which has a null access value
designating  no  object  at  all.   The null value of an access type is the
default initial value of the type.  Other values  of  an  access  type  are
obtained  by  evaluation  of  a  special  operation  of the type, called an
allocator.  Each such access value designates  an  object  of  the  subtype
defined  by  the  subtype  indication  of the access type definition;  this
subtype is called the designated subtype;  the base type of this subtype is
called the designated type.  The objects designated by  the  values  of  an
access type form a collection implicitly associated with the type.

The elaboration of an access type definition consists of the elaboration of
the subtype indication and creates an access type.

If  an  access  object  is  constant,  the contained access value cannot be
changed and always designates the same object.   On  the  other  hand,  the
value  of the designated object need not remain the same (assignment to the
designated object is allowed unless the designated type is limited).

The only forms of constraint that are allowed after the name of  an  access
type  in  a  subtype  indication  are  index  constraints  and discriminant
constraints.  (See sections 3.6.1 and 3.7.2 for  the  rules  applicable  to
these  subtype  indications.)   An  access value belongs to a corresponding
subtype of an access type either if the access value is the null  value  or
if the value of the designated object satisfies the constraint.

Examples:

    type FRAME is access MATRIX;        --  see 3.6

    type BUFFER_NAME is access BUFFER;  --  see 3.7.1

Notes:

An access value delivered by an allocator can be assigned to several access
objects.   Hence it is possible for an object created by an allocator to be
designated by more than one variable or constant of the  access  type.   An
access  value  can  only  designate  an object created by an allocator;  in
particular,  it  cannot  designate  an  object  declared   by   an   object
declaration.

If the type of the objects designated by the access values is an array type
or a type with discriminants, these objects are constrained with either the
array  bounds  or the discriminant values supplied implicitly or explicitly


                                  3 - 79








for the corresponding allocators (see 4.8).

Access values are called pointers or references in some other languages.

References:  allocator 4.8, array type 3.6, assignment  5.2,  belong  to  a
subtype 3.3, constant 3.2.1, constraint 3.3, discriminant constraint 3.7.2,
elaboration  3.9,  index constraint 3.6.1, index specification 3.6, limited
type 7.4.4, literal 4.2, name 4.1, object 3.2.1, object declaration  3.2.1,
reserved  word 2.9, satisfy 3.3, simple name 4.1, subcomponent 3.3, subtype
3.3, subtype indication 3.3.2, type 3.3, variable 3.2.1















































                                  3 - 80








3.8.1  Incomplete Type Declarations


There are no particular limitations on the designated type   of  an  access
type.  In particular, the type of a component of the designated type can be
another  access  type, or even the same access type.  This permits mutually
dependent and recursive access types.  Their declarations require  a  prior
incomplete (or private) type declaration for one or more types.

    incomplete_type_declaration ::= type identifier [discriminant_part];

For  each  incomplete  type  declaration,  there  must  be  a corresponding
declaration  of  a  type  with  the  same  identifier.   The  corresponding
declaration  must be either a full type declaration or the declaration of a
task type.  In the rest of this section, explanations are given in terms of
full type declarations;  the same rules apply also to declarations of  task
types.  If the incomplete type declaration occurs immediately within either
a declarative part or the visible part of a package specification, then the
full  type  declaration  must  occur  later  and  immediately  within  this
declarative part or visible  part.   If  the  incomplete  type  declaration
occurs immediately within the private part of a package, then the full type
declaration must occur later and immediately within either the private part
itself, or the declarative part of the corresponding package body.

A  discriminant part must be given in the full type declaration if and only
if one is given in the incomplete type declaration;  if discriminant  parts
are  given,  then  they must conform (see 6.3.1 for the conformance rules).
Prior to the end of the full type declaration, the only allowed  use  of  a
name  that  denotes a type declared by an incomplete type declaration is as
the type mark in the subtype indication of an access type definition;   the
only   form   of  constraint  allowed  in  this  subtype  indication  is  a
discriminant constraint.

The elaboration of an incomplete type declaration creates a type.   If  the
incomplete  type  declaration  has  a  discriminant  part, this elaboration
includes that of the discriminant part:  in such a case,  the  discriminant
part of the full type declaration is not elaborated.

Example of a recursive type:

    type CELL;  --  incomplete type declaration
    type LINK is access CELL;

    type CELL is
       record
          VALUE : INTEGER;
          SUCC  : LINK;
          PRED  : LINK;
       end record;

    HEAD : LINK := new CELL'(0, null, null);
    NEXT : LINK := HEAD.SUCC;

Examples of mutually dependent access types:



                                  3 - 81








    type PERSON(SEX : GENDER);  --  incomplete type declaration
    type CAR;                   --  incomplete type declaration

    type PERSON_NAME is access PERSON;
    type CAR_NAME    is access CAR;

    type CAR is
       record
          NUMBER : INTEGER;
          OWNER  : PERSON_NAME;
       end record;














































                                  3 - 82








    type PERSON(SEX : GENDER) is
       record
          NAME    : STRING(1 .. 20);
          BIRTH   : DATE;
          AGE     : INTEGER range 0 .. 130;
          VEHICLE : CAR_NAME;
          case SEX is
             when M => WIFE    : PERSON_NAME(SEX => F);
             when F => HUSBAND : PERSON_NAME(SEX => M);
          end case;
       end record;

    MY_CAR, YOUR_CAR, NEXT_CAR : CAR_NAME;  --  implicitly initialized with null value

References:   access  type  3.8, access type definition 3.8, component 3.3,
conform 6.3.1, constraint  3.3,  declaration  3.1,  declarative  item  3.9,
designate  3.8,  discriminant  constraint  3.7.2,  discriminant part 3.7.1,
elaboration 3.9, identifier 2.3, name 4.1, subtype indication  3.3.2,  type
3.3, type mark 3.3.2



3.8.2  Operations of Access Types


The  basic  operations of an access type include the operations involved in
assignment,   allocators   for   the   access   type,   membership   tests,
qualification,   explicit   conversion,  and  the  literal  null.   If  the
designated type is a type with discriminants, the basic operations  include
the  selection  of the corresponding discriminants;  if the designated type
is  a  record  type,  they  include  the  selection  of  the  corresponding
components;   if  the  designated  type  is an array type, they include the
formation of indexed components and slices;  if the designated  type  is  a
task   type,   they  include  selection  of  entries  and  entry  families.
Furthermore, the basic operations  include  the  formation  of  a  selected
component with the reserved word all (see 4.1.3).

If  the  designated type is an array type, the basic operations include the
attributes that have the attribute  designators  FIRST,  LAST,  RANGE,  and
LENGTH  (likewise,  the  attribute designators of the N-th dimension).  The
prefix of each of these attributes must be a  value  of  the  access  type.
These  attributes yield the corresponding characteristics of the designated
object (see 3.6.2).

If the designated type is a task type, the  basic  operations  include  the
attributes that have the attribute designators TERMINATED and CALLABLE (see
9.9).  The prefix of each of these attributes must be a value of the access
type.   These  attributes  yield  the  corresponding characteristics of the
designated task objects.

In addition, the  attribute  T'BASE  (see  3.3.3)  and  the  representation
attributes T'SIZE and T'STORAGE_SIZE (see 13.7.2) are defined for an access
type  or subtype T;  the attributes A'SIZE and A'ADDRESS are defined for an
access object A (see 13.7.2).



                                  3 - 83








Besides the basic operations, the operations of an access type include  the
predefined comparison for equality and inequality.

References:   access  type  3.8,  allocator 4.8, array type 3.6, assignment
5.2, attribute 4.1.4, attribute designator  4.1.4,  base  type  3.3,  basic
operation  3.3.3, collection 3.8, constrained array subtype 3.6, conversion
4.6,  designate  3.8,  designated  subtype  3.8,   designated   type   3.8,
discriminant 3.3, indexed component 4.1.1, literal 4.2, membership test 4.5
4.5.2,  object 3.2.1, operation 3.3, private type 7.4, qualified expression
4.7, record type 3.7, selected component 4.1.3, slice 4.1.2,  subtype  3.3,
task type 9.1, type 3.3














































                                  3 - 84








3.9  Declarative Parts


A declarative part contains declarative items (possibly none).

    declarative_part ::=
       {basic_declarative_item} {later_declarative_item}

    basic_declarative_item ::= basic_declaration
       | representation_clause | use_clause

    later_declarative_item ::= body
       | subprogram_declaration | package_declaration
       | task_declaration       | generic_declaration
       | use_clause             | generic_instantiation

    body ::= proper_body | body_stub

    proper_body ::= subprogram_body | package_body | task_body

The  elaboration  of  a declarative part consists of the elaboration of the
declarative items, if any, in the order in which  they  are  given  in  the
declarative  part.  After its elaboration, a declarative item is said to be
elaborated.  Prior to the completion of its elaboration  (including  before
the elaboration), the declarative item is not yet elaborated.

For  several  forms  of declarative item, the language rules (in particular
scope and visibility rules) are  such  that  it  is  either  impossible  or
illegal  to  use  an  entity before the elaboration of the declarative item
that declares this entity.  For example, it is not possible to use the name
of a type for an object declaration if the corresponding  type  declaration
is  not  yet  elaborated.   In the case of bodies, the following checks are
performed:

  -  For a subprogram call, a check is made that the body of the subprogram
     is already elaborated.

  -  For the activation of a task, a check is made that  the  body  of  the
     corresponding task unit is already elaborated.

  -  For the instantiation of a generic unit that has a body,  a  check  is
     made that this body is already elaborated.

The exception PROGRAM_ERROR is raised if any of these checks fails.

If  a subprogram declaration, a package declaration, a task declaration, or
a generic declaration is a declarative item of a  given  declarative  part,
then  the  body  (if  there  is  one)  of  the program unit declared by the
declarative item must itself be a declarative item of this declarative part
(and must appear later).  If the body is a body  stub,  then  a  separately
compiled  subunit  containing the corresponding proper body is required for
the program unit (see 10.2).

References:  activation 9.3, instantiation  12.3,  program_error  exception
11.1, scope 8.2, subprogram call 6.4, type 3.3, visibility 8.3


                                  3 - 85








Elaboration  of  declarations:   3.1,  component  declaration 3.7, deferred
constant  declaration  7.4.3,  discriminant  specification   3.7.1,   entry
declaration   9.5,   enumeration   literal   specification  3.5.1,  generic
declaration 12.1, generic instantiation 12.3, incomplete  type  declaration
3.8.1,  loop  parameter specification 5.5, number declaration 3.2.2, object
declaration 3.2.1, package declaration 7.2,  parameter  specification  6.1,
private  type  declaration  7.4.1,  renaming  declaration  8.5,  subprogram
declaration 6.1, subtype declaration  3.3.2,  task  declaration  9.1,  type
declaration 3.3.1
















































                                  3 - 86








Elaboration  of type definitions:  3.3.1, access type definition 3.8, array
type  definition  3.6,  derived  type  definition  3.4,  enumeration   type
definition  3.5.1,  integer  type  definition  3.5.4,  real type definition
3.5.6, record type definition 3.7

Elaboration of other constructs:  context  clause  10.1,  body  stub  10.2,
compilation  unit 10.1, discriminant part 3.7.1, generic body 12.2, generic
formal  parameter  12.1  12.3,  library  unit  10.5,  package   body   7.1,
representation  clause  13.1,  subprogram body 6.3, subunit 10.2, task body
9.1, task object 9.2, task specification 9.1, use clause 8.4,  with  clause
10.1.1














































                                  3 - 87