[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Pascal for OpenVMS
Language Reference Manual


Previous Contents Index

2.10.2 Assignment Compatibility

Assignment compatibility rules apply to the types of values used to initialize variables, the types of expressions assigned to variables with the assignment operator (:=), and the types of actual parameters passed to formal value parameters. A variable or formal parameter is always compatible with expressions of its type.

Table 2-11 shows the contexts in which the type of an expression is assignment compatible with the type of a variable or a formal parameter when the types are not the same.

Table 2-11 Assignment Compatibility
Type of Variable Type of Assignment-Compatible Expression
or Parameter
INTEGER INTEGER, UNSIGNED, INTEGER64, UNSIGNED64
UNSIGNED INTEGER, UNSIGNED, INTEGER64, UNSIGNED64
INTEGER64 INTEGER, UNSIGNED, INTEGER64, UNSIGNED64
UNSIGNED64 INTEGER, UNSIGNED, INTEGER64, UNSIGNED64
Subrange Base type of the subrange
REAL, SINGLE REAL, SINGLE, UNSIGNED, INTEGER, INTEGER64, UNSIGNED64
DOUBLE DOUBLE, REAL, SINGLE, UNSIGNED, INTEGER, INTEGER64, UNSIGNED64
QUADRUPLE QUADRUPLE, DOUBLE, REAL, SINGLE, UNSIGNED, INTEGER
PACKED ARRAY OF
CHAR
CHAR, unpacked array of CHAR, PACKED ARRAY OF CHAR with the same or smaller length, VARYING string whose current length is equal to or less than the packed array
VARYING OF CHAR CHAR, unpacked array of CHAR, PACKED ARRAY OF CHAR, VARYING, STRING, string whose current value does not exceed the maximum length of the variable or parameter
STRING CHAR, unpacked array of CHAR, PACKED ARRAY OF CHAR, VARYING, STRING, string whose current value does not exceed the maximum length of the variable or parameter
Pointer Pointer to a structurally compatible type

Two record types or two array types are assignment compatible if they are structurally compatible. When you assign one record variable to another, or one array variable to another, the HP Pascal compiler does not check for out-of-range assignments to record fields or array components; such assignments do not result in an error message, even if subrange checking is enabled at compile time.

A set expression is assignment compatible with a set variable if the set's base types are compatible. In addition, all elements of the set expression must be included in the range of the variable's base type.

Note that assignment operations are not allowed on objects of file types or structured types that have file components.

Two discriminated schema types are assignment compatible if they are of the same type family and if their actual discriminant values are identical. A dereferenced pointer to an undiscriminated schema type is actually referencing a discriminated schema object whose discriminants were specified in a call to the NEW function. Although STRING is a schema, the rules in Table 2-11 take precedence.

For More Information:


Chapter 3
Declaration Section

The declaration section contains declarations or definitions of constants, labels, user-defined data types, variables, and user-defined functions and procedures. In addition, only modules can contain initialization and finalization sections. Each appears in a subsection introduced by Pascal reserved words.

This chapter discusses the following topics:

These sections appear after the header and before the executable section (if any). The TO BEGIN DO and TO END DO sections can appear only in modules and only once within a module.

The remaining sections can appear in programs, modules, functions, or procedures; they can appear more than once and in any order in a single declaration section. If you use one kind of section more than once in a declaration section, be sure to declare types, variables, and constants before you use them in subsequent sections.

For More Information:

3.1 CONST Section

The CONST section defines symbolic constants by associating identifiers with compile-time expressions; it has the following form:


    CONST
       {constant-identifier = constant-expression};...

constant-identifier

The identifier of the symbolic constant being defined.

constant-expression

Any legal compile-time expression.

Once a constant identifier is associated with an expression, the identifier retains the value of that expression throughout the scope in which it was declared. You can change the value only by changing the definition in the CONST section.

Consider the following example:


TYPE
   array_type1 = ARRAY[1..10] OF INTEGER;
CONST
   Year       = 1984;
   Tiny       = 1.7253;
   Month      = 'November';
   Initial    = 'P';
   Lie        = FALSE;
   Untruth    = Lie;
   Almost_Pi  = 22.0/7.0;
   array_const =
      array_type1[1..3,5 : 1;  4,6 : 2;  7..9 : 3;  10 : 7];

For More Information:

3.2 LABEL Section

A label is a tag that makes an executable statement accessible to a GOTO statement. The LABEL section declares labels and has the following form:


    LABEL
       {label},...;

label

A decimal integer between 0 and 9999 (as an extension, between 0 and MAXINT), or a symbolic name. When declaring several labels, you can specify them in any order. The declaration and the occurrence of the label must be at the same level in the program.

A label can appear only once within the scope of the label declaration. It can precede any executable statement in the program. Use a colon (:) to separate the label from the statement it precedes. Labels can be accessed only by GOTO statements.

Consider the following example:


LABEL
    marker, 5;
{In the executable section: }
IF a <= 150 THEN GOTO 5
ELSE GOTO marker ;
   .
   .
   .
5: a := a + 1;
   .
   .
   .
marker: WHILE x < 20 DO {Statement...}

For More Information:

  • For information on the GOTO statement, see Section 5.8.

3.3 TO BEGIN DO Section

The TO BEGIN DO section allows you to specify a statement, in a module that is to be executed before the executable section of the main program; it has the following form:


TO BEGIN DO statement;

statement

A Pascal statement.

The TO BEGIN DO section can only appear in modules, can only appear once in a module, and must appear as the last section in the declaration section. (If appearing together, the TO BEGIN DO section must precede the TO END DO section at the end of the declaration section.)

Consider the following example:


MODULE x( INPUT, OUTPUT );
VAR
   Debug : BOOLEAN;
PROCEDURE Test(...); {Executable section...}

TO BEGIN DO
   BEGIN
   WRITE('Debug Module x?   ');
   READLN( Debug );
   END;
END.

As a general rule, if a program or module inherits an environment file, the compiler executes the initialization section in the inherited module before the initialization section in the program or module that inherited it. If a module or program inherits more than one module that contains an initialization section, the order of execution of the inherited modules is undefined.

Consider the following example:



[ENVIRONMENT( 'Mod1' )]  MODULE Mod1;
VAR
   i : INTEGER;
TO BEGIN DO
   i := 5;

{In a separate compilation unit:}
[INHERIT( 'Mod1' )]  MODULE Mod2;
VAR
   j : INTEGER;
TO BEGIN DO
   j := i + 1;  {First execute code in Mod1 for correct results}

Figure 3-1 shows the order of execution of initialization and finalization sections. Each circle is a module that contains both a TO BEGIN DO and a TO END DO section, and each arrow indicates the order of inheritance for the environment files.

Figure 3-1 Order of Execution for TO BEGIN DO and TO END DO Sections


The execution order for initialization and finalization sections in Modules 2 and 3 cannot be determined. The headers for the modules in Figure 3-1 are as follows:



[ENVIRONMENT]  MODULE Mod1; ...

[ENVIRONMENT, INHERIT( 'Mod1' )]  MODULE Mod2; ...

[ENVIRONMENT, INHERIT(' Mod1' )]  MODULE Mod3; ...

[INHERIT( 'Mod2', 'Mod3' )]       MODULE Mod4; ...

The name of the compiler-generated initialization routine is formed by taking the module name and appending %INIT . If you wish to provide a different name, you can use the [GLOBAL] attribute on the top of the module to specify a different name. For example:


[ENVIRONMENT,GLOBAL(MYINIT)] MODULE Mod1; ...

This alternate name is encoded in the resulting environment file so all modules that inherit this environment will automatically call the initializaton routine by its new alternate name.

For More Information:

3.4 TO END DO Section

The TO END DO section allows you to specify a statement in a module that is to be executed after the executable section of the main program; it has the following form:


TO END DO statement;

statement

A Pascal statement.

The TO END DO section can only appear in modules, can only appear once in a module, and must appear as the last section in the declaration section. (If appearing together, the TO END DO section must come after the TO BEGIN DO section at the end of the declaration section.)

As a general rule, if a compilation unit inherits an environment file, the finalization section in the inheriting compilation unit must be executed before the finalization section in the inherited compilation unit. Also, if more than one module with a finalization section inherits a single module, the order of finalization of the inheriting modules cannot be determined. Figure 3-1 shows an example of the order of execution of TO END DO sections.

The compiler implements a TO END DO section by creating an invisible TO BEGIN DO section if TO BEGIN DO wasn't used or by augmenting an existing TO BEGIN DO section with a call to the Pascal Run-Time Library to register the finalization routine.

Here is an example using both TO BEGIN DO and TO END DO:


MODULE File_Output;
VAR
   Out_File : TEXT;
   t        : TIMESTAMP;
PROCEDURE Test(...); {Executable section...}

TO BEGIN DO

   OPEN( Out_File, 'foo.dat' );


TO END DO
   BEGIN
   GETTIMESTAMP( t );
   WRITELN( 'foo.dat closed at', TIME( t ) );

   CLOSE( Out_File )

   END;
END.

For More Information:

3.5 TYPE Section

The TYPE section introduces the name and set of values for a user-defined type or schema declaration.

It has the following form:


         [[type-attribute-list]]
         TYPE
              {type-identifier = [[attribute-list]] type-denoter  }
            { {schema-declaration                                 }
              {                                                   }
                [[VALUE initial-state-specifier]]};...

type-attribute-list

One or more attributes that apply to the entire TYPE section. Only the ALIGN, ENUMERATION_SIZE, or HIDDEN attributes can be specified here.

type-identifier

The identifier of the type being defined.

attribute-list

One or more identifiers that provide additional information about the type-denoter.

type-denoter

Any legal Pascal type syntax.

schema-declaration

The declaration of a schema type.

initial-state-specifier

A compile-time expression that is assignment compatible with a variable of the TYPE identifier being defined. HP Pascal initializes all variables declared to be of this type with the constant value or values provided (unless there is an overriding initial-state-specifier in the variable declaration).

The following rules apply to the use of initial-state-specifiers on data types:

  • You must initialize a type with a compile-time expression of an assignment-compatible type. Scalar types require scalar constants; structured types require constant constructors.
  • You cannot initialize file types or types containing file components.
  • The predeclared function ZERO can be used to initialize an entire type (except file types and TIMESTAMP types) to binary zero.
  • The constant identifier NIL or a call to the ZERO function are the only values with which you can initialize a pointer type.

This example declares variables of user-defined types. Note that in the declaration of variable week5, the VALUE Sun overrides the initial state specified in the TYPE declaration by VALUE Mon.


TYPE
   Days_of_Week = ( Sun, Mon, Tues, Wed, Thurs, Fri, Sat )
                    VALUE Mon;
   Array_Template( Upper_Bound : INTEGER ) =
                   ARRAY [1..Upper_Bound] OF INTEGER;
VAR                   {Declaring variables of user-defined types:}
   week1, week2, week3, week4 : Days_of_Week; {Initial value: Mon}
   week5 : Days_of_Week VALUE Sun;            {Initial value: Sun}
   array_type2 : array_template( x ); {x is a run-time expression}

HP Pascal requires that all user-defined type identifiers (except base types of pointers) be defined before they are used in the definitions of other types. A base type must be defined before the end of the TYPE section in which it is first mentioned, as shown in the this example:


TYPE
   Ptr_to_Movie = ^Movie;               {Movie is defined later}
   Name  = PACKED ARRAY[1..20] OF CHAR; {Defined before used}
   Movie = RECORD
           Title, Director : Name;
           Year  : INTEGER;
           Stars : FILE OF Name;
           Next  : Ptr_to_Movie;
           END;

For More Information

3.6 VALUE Section

If you choose, you can use the VALUE section as an HP Pascal extension that initializes ordinal, real, array, record, set, and string variables. (If you require portable code, use the VALUE reserved word in either TYPE definitions or VAR declarations.) The exact format of an initialization depends on the type of the variable being initialized. The VALUE section has the following form:


    VALUE
        {variable-identifier := constant-expression};...

variable-identifier

The name of the variable to be initialized. You cannot specify a list of variable identifiers. You can initialize a variable or variable component only once in the VALUE section. Any variables appearing in the VALUE section must appear in a previous VAR section.

constant-expression

Any constant expression that is assignment compatible with the variable identifier.

Unlike other declaration sections, the VALUE section can appear only in a program or module declaration section. You cannot use the VALUE declaration section in procedures or functions. If you wish to initialize variables in procedures and functions, use an initial-state specifier (by using the VALUE reserved word in either the TYPE or VAR section).

You can assign values to complete structured variables or to a single component of that variable.

For More Information:

3.7 VAR Section

The VAR section declares variables and associates each variable with an identifier, a type, and an optional initial value.

It has the following form:


         [[var-attribute-list]]
         VAR
            {{variable-identifier},... : [[attribute-list]] type-denoter
               {:=     }
            [[ {VALUE  } initial-state-specifier ]] };...

var-attribute-list

One or more attributes that apply to the entire VAR section. Only the ALIGN, ENUMERATION_SIZE or HIDDEN attributes can be specified here.

variable-identifier

The identifier of the variable being declared.

attribute-list

One or more identifiers that provide additional information about the variable.

type-denoter

Any legal Pascal type syntax.

initial-state-specifier

Any constant expression that is assignment compatible with the variable identifier. The variable is initialized to this expression.

You can combine several identifiers in the same variable declaration if the variables are of the same type and are being initialized either with the same value or not at all.

Consider the following example:


TYPE
   Hours_Worked = ARRAY[1..10] OF INTEGER;
VAR
   Answer, Rumor : BOOLEAN;
   Temp          : INTEGER VALUE 60;
   Grade         : 'A'..'D';
   Weekly_Hours  : Hours_Worked VALUE [1..3 : 7; OTHERWISE 5];

The following rules apply to the use of initial-state specifiers on variables:

  • You must initialize a variable with a constant expression of an assignment-compatible type. Scalar variables require scalar constants; structured variables require constant constructors.
  • You cannot initialize file variables or variables containing file components.
  • You can use the predeclared function ZERO to initialize all or part of a variable (except file variables and components) to binary zero.
  • The constant identifier NIL or a call to the ZERO function are the only values with which you can initialize a pointer variable.

A reference to a variable consists of the variable's use in one of the following situations:

  • The variable or one of its components is passed as a VAR, %REF, or %DESCR parameter. The reference lasts throughout the call to the corresponding routine.
  • The variable or one of its components is used on the left side of an assignment statement. The reference lasts throughout the execution of the statement.
  • The variable or one of its components is accessed by a WITH statement. The reference lasts throughout the execution of the statement.

The existence of a variable reference sometimes prohibits certain operations from being performed on the variable. Such restrictions are noted throughout this manual.

For More Information:


Previous Next Contents Index