[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Pascal for OpenVMS
Language Reference Manual


Previous Contents Index

6.3.8 Parameter Association

In most cases, a routine call must pass exactly one actual parameter for each formal parameter. The actual parameter is either listed explicitly in the routine call or supplied by means of a default value in the routine declaration.

One way of establishing the correspondence between actual and formal parameters is to give the parameters in each list the same position. That is, the association of actual and formal parameters proceeds from left to right, item by item, through both lists. This form of association is called positional syntax.

Another way of establishing correspondence is to specify the formal parameter name and the actual parameter being passed to it. In HP Pascal, you can associate an actual parameter with a formal parameter using the assignment operator (:=). The actual parameters in the call do not have to appear in the same order as the formal parameters appeared in the declaration. This form of association is called nonpositional syntax.

You can use both positional and nonpositional actual parameters in the same call. However, after you specify one parameter in nonpositional syntax, all remaining parameters must be in nonpositional syntax (all parameters in positional syntax must be at the front of the list).

Consider the following example:


PROCEDURE Compute_Sum( x, y : INTEGER; VAR z : INTEGER ); {Body...}

{In the executable section:}
{Positional syntax:}
Compute_Sum( Quantity + 6, 15, Total );

{Nonpositional syntax:}
Compute_Sum(

z := Total, x := Quantity + 6, y := 15


{Both syntaxes:}
Compute_Sum( Quantity + 6,

z := Total, y := 15

For More Information:

  • On using the LIST and TRUNCATE attributes to specify variable-length parameter lists (Sections 10.2.24 and 10.2.37)
  • On scope ( Section 7.2)

6.3.9 Default Formal Parameters

HP Pascal allows you to supply default values for formal parameters. Using default parameter values, you do not need to pass actual parameters. Also, you can specify an actual parameter in the position of a formal parameter whose default value you want to override. To specify a default value, use the following format:


parameter-spec := [[mechanism-specifier]] constant-expression;

parameter-spec

The parameter specification. The syntax for a parameter specification depends on its semantics.

mechanism-specifier

The mechanism by which HP Pascal associates a default value with a formal parameter. You can only specify a mechanism-specifier on a foreign routine.

constant-expression

A constant expression representing the default value for the formal parameter.

This default value, plus the optional mechanism specifier, must be a legal actual parameter for the kind of formal parameter with which the default is associated. Table 6-4 shows when HP Pascal allows a default value.

Table 6-4 Default Values on Formal Parameters
Formal Parameter Type External Routine HP Pascal Routine
Variable Requires foreign
mechanism specifier
Error
Value Allowed Allowed
Routine Requires foreign
mechanism specifier
Error

When you declare a formal parameter with a default value, you can either omit it from the routine call or, if you use positional syntax, you can indicate its position with a comma.

Consider the following example:



FUNCTION Net_Pay( Hours    : INTEGER;
                  Tax      : REAL := 0.05;
                  Rate     : REAL;
                  Fica     : REAL := 0.07;
                  Overtime : INTEGER )  : REAL;  {Body...}
{In the executable section:}
{Nonpositional syntax:}
Take_Home_Year := Take_Home_Year +
                  Net_Pay ( Overtime := Overtime_Week,
                            Rate := Pay_Rate,
                            Hours := Hours_Week );
{Positional syntax:}
Take_Home_Year := Take_Home_Year +
                  Net_Pay( Hours_Week, , Pay_Rate, ,
                           Overtime_Week );

The formal parameters Tax and Fica are given the default values 0.05 and 0.07, respectively.

You can override a formal parameter's default value by associating the formal parameter with an actual parameter in a routine call. For example, if you want to replace the default value of the formal parameter Tax in the previous example for one call, you can call Net_Pay as follows:



Take_Home_Year:= Take_Home_Year +
   Net_Pay( Hours_Week, 0.06, Pay_Rate, , Overtime_Week );

As a result of this routine call, the default value of Tax will be replaced by the value 0.06 supplied in the actual parameter list.

For More Information:


Chapter 7
Program Structure and Scope

This chapter describes the following topics:

7.1 Blocks

A block is a declaration section and an executable section. Programs, modules, and routines are structured in blocks. A declaration section can contain routine blocks nested within the outer program or module block; routine blocks can also be nested within other routines.

The declaration section contains data definitions and declarations, and nested routine declarations that are local to the enclosing block. The executable section contains the statements that specify the block's actions. You can cause an exit from a block with the last executable statement of the block, which causes normal termination, or with a GOTO statement, which transfers control to an outer block.

For More Information:

7.2 Scope of Identifiers

The scope of an identifier is the part of the program in which the identifier has a particular meaning. In Pascal, the scope of an identifier is the block in which it is defined or declared, including nested blocks (but excluding any nested blocks that redeclare the same identifier). Outside its scope and assuming that it is not declared elsewhere, an identifier has no meaning; in this case, attempts to use the identifier generate an error.

All Pascal identifiers observe the following scope rules:

  • An identifier can be declared only once within a particular scope.
  • A previously declared identifier can be redeclared in a nested block.
  • An identifier declared in the main program or module block is accessible in all nested blocks (except where it is redeclared).

Some Pascal identifiers observe additional scope rules:

  • A procedure identifier can be redeclared within its own declaration section.
  • A function identifier can also be redeclared, but not in a declaration section of the function's outermost block. The identifier can be redeclared only in a nested block because you need to be able to assign a value to it in the outermost block unless a RETURN statement is used.
  • A formal parameter name follows the same rules of scope as a function identifier and can be redeclared only in a nested block.
  • A label declaration must respect GOTO statement restrictions. These restrictions prevent control passing from an outer to an inner block.

7.3 Redeclaring Routine Names

Routine names can be redeclared like any other identifier. A block, in its declaration section, can specify routines with the same names as those outside the block. This changes the meaning of function and procedure calls when they occur within the block.

A procedure can redeclare its own identifier. For example, the declaration section of the procedure Sum can declare a different procedure called Sum. The scope of this second declaration is only within the first block; calls to Sum within the block are not recursive but are calls to the locally declared routine.

You can also redeclare a function identifier within its own declaration. However, the function then cannot use the function identifier in an assignment to return a value to the caller. A function that redeclares its own identifier must use the RETURN statement (see Section 5.12) to specify a return value.

In the declaration section you cannot redeclare an identifier used in the formal parameter list of the routine. However, a block nested in the declaration section can do so. The following example shows the scope of identifiers that appear in several blocks in a program.

Figure 7-1 shows the scope of identifiers that appear in several blocks in a program. Pascal scope rules make the following statements about Figure 7-1 true:

  • Variable identifiers a and b are declared at the outer level of the example. Scope rules make them accessible throughout the example. In the main program, Level1a, and Level1b, identifiers a and b represent integers. In Level2, variable identifer a still represents an integer variable, but b is redeclared as a Boolean variable.
  • Type identifier c and variable identifiers d and e are declared at the next lower level, Level1a. Scope rules make them accessible only in this block. They cannot be accessed from the higher-level main program. They cannot be accessed from a lower-level block because Level1a contains no nested routine.
  • Formal parameter identifiers v, u, and t are declared at the same level, Level1b. They cannot be redeclared within this block. They can be redeclared as local identifiers in the nested block of FUNCTION Level2.
  • Procedure identifier Level1a is declared in the outermost block of the example. This identifier can be redeclared within its own declaration section.
  • Function identifier Level2 is declared in the next-highest level, Level1b. It cannot be declared within this block. Level2 can be redeclared as a local identifier within a nested block.

Figure 7-1 Scope of Identifiers


For More Information:

7.4 Modules and Programs

A module is a set of instructions that can be compiled, but not executed, by itself. Module blocks contain only a declaration section and TO BEGIN DO and TO END DO sections. A program is a set of instructions that can be compiled and executed by itself. Program blocks contain a declaration and an executable section. A compilation unit is a unit of HP Pascal code that can be compiled independently; the term compilation unit refers to either a program or a module.

Each module and program must be in a separate file; you cannot place multiple modules (or a module and a program) in the same file. You can compile modules and a program together or separately (the syntax of compilation depends on the operating system you are using).

The formats for compilation units are as follows:


[[attribute-list]] PROGRAM comp-unit-identifier [[({file-identifier},...)]];
   [[declaration-section]]
   BEGIN
   {statement};...
   END.

[[attribute-list]] MODULE comp-unit-identifier
   [[({file-identifier},...)]];
   [[declaration-section]]
   [[TO BEGIN DO statement;]]
   [[TO END DO statement;]]
   END.

The module syntax of HP Pascal is slightly different than that of Extended Pascal. However, the concepts in both languages are the same.

attribute-list

One or more identifiers that provide additional information about the compilation unit.

comp-unit-identifier

Specifies the name of the program or module. The identifier appears only in the heading and has no other purpose within the compilation unit.

file-identifier

Specifies the names of any file variables associated with the external files used by the compilation unit.

declaration-section

A Pascal declaration section.

statement

A Pascal statement.

The program or module heading includes all information preceding the program or module block. If your program contains any input or output routines, you must list all the external file variables that you are using in the compilation unit's heading. File variables listed in a heading must also be declared locally in the block, except for the predeclared file variables INPUT and OUTPUT. The INPUT identifier corresponds to a predefined external file that accepts input from the default device (usually, your terminal). The OUTPUT identifier corresponds to a predefined external file that sends output to the default device (usually, your terminal). the ERR identifier corresponds If you redeclare INPUT and OUTPUT in a nested block, you lose access to the default input and output devices.

Consider the following example:


PROGRAM Write_Var(OUTPUT);   {Header}
VAR                          {Declaration section}
   Number : INTEGER VALUE 3;
BEGIN                        {Executable section}
WRITELN( Number );           {Writes 3 to the default device}
END.

For More Information:

  • On INPUT and OUTPUT ( Section 9.5)
  • On compilation and command-line syntax (HP Pascal for OpenVMS User Manual)
  • On the TO BEGIN DO section ( Section 3.3)
  • On the TO END DO section ( Section 3.4)

7.5 Compilation Units and Data Sharing

When dividing code into programs and modules, you may want to share declarations among compilation units. The following sections discuss ways of sharing data.

7.5.1 Environment Files

Environment files contain the definitions and declarations, from the outermost level of declaration section of a compilation unit, that can be shared with other compilation units that inherit the environment file. Environment files exist in a form that the compiler can process more easily. The following example shows how to use environment files:


{Contained in one file:}
[INHERIT ('file_name')]
PROGRAM a( INPUT, OUTPUT );
BEGIN
READ( Amount );
Calc;
WRITELN( 'Purchase Amount:  ', Amount:10:2)
WRITELN( '              +   ', Tax:10:2)
WRITELN( 'Pay This Total:   ', Total:10:2)
END.

{Contained in a separate file:}
[ENVIRONMENT('file_name')]
MODULE B;        {Keep all global data in one module}
CONST            {Compile this unit first to create file}
   Rate = 0.06;
VAR
   Amount, Total, Tax: REAL;
PROCEDURE Glf; BEGIN...END;
PROCEDURE Calc;
   BEGIN
   Tax := Amount * Rate;
   Total := Tax + Amount;
   Glf;
   END;
END.

Since the declarations in module b compose the environment file to be inherited by another compilation unit, you must compile module b first to create the environment file. When compiling module b, HP Pascal creates an environment file by the name of file_name. HP Pascal adds a file type of .PEN (for Pascal Environment).

The environment file contains declaration information about the constant Rate; about the variables Amount, Total, and Tax; and about the procedures Glf and Calc. If there are identifiers in a compilation unit that you do not want to be included in an environment file, use the HIDDEN attribute.

When you compile program a, which contains the INHERIT attribute, HP Pascal uses the specified environment file to allow the program access to the data and routines declared in the module. Variables that are inherited from an environment file are not newly created variables, but are the same variables that were allocated storage by the declaring compilation unit.

A compilation unit may create only one environment file, but may inherit multiple files that must have been created by earlier compilations. Declarations from inherited files are not included in any environment files created by the compilation unit. An environment file must have been created by a version of the compiler that is compatible with the version that is compiling the compilation unit.

The identifiers in the outermost level of the declaration section of a compilation unit and all inherited identifiers must be unique. However, HP Pascal allows the following exceptions to the redeclaration rules:

  • A variable identifier can be multiply declared if all declarations of the variable have the same type, and all but one declaration at most are external.
  • A procedure identifier can be multiply declared if all declarations of the procedure have congruent parameter lists, and all but one declaration at most are external.
  • A function identifier can be multiply declared if all declarations of the function have congruent parameter lists and identical result types, and all but one declaration at most are external.

Consider the following example:



{In one compilation unit:}
[ENVIRONMENT('extern.pen')] MODULE Mod1;
[EXTERNAL] PROCEDURE Inst; EXTERN;
END.

{In another compilation unit:}
[INHERIT('extern.pen')] MODULE Mod2;
[GLOBAL] PROCEDURE Inst;  {Body...}
END.

For More Information:

7.5.2 Global and External Identifiers

Global and external identifiers are accessible to other compilation units (even to compilation units written in other languages) that make up one executable unit. The GLOBAL attribute allows a declared identifier to be globally accessible by other compilation units; the EXTERNAL attribute specifies that another compilation unit allocates storage for the data or routine. The compiler does not check to make sure that global and external identifiers are declared as being of the same data type; you must ensure that the data types are compatible.

You cannot use global and external names to share the declarations of user-defined types. However, you can use the VALUE attribute to share global and external literals.

The following example shows how to use global and external identifiers:



{Contained in one file:}
PROGRAM a( INPUT, OUTPUT );
VAR
   Amount, Total, Tax : [EXTERNAL] REAL;  {Defined elsewhere}
[EXTERNAL] PROCEDURE Calc; EXTERNAL;      {Defined elsewhere}
[GLOBAL]   PROCEDURE Glf; {Body...}       {Available outside}
BEGIN
READ( Amount );
Calc;
WRITELN( 'Purchase Amount:  ', Amount:10:2)
WRITELN( '              +   ', Tax:10:2)
WRITELN( 'Pay This Total:   ', Total:10:2)
END.

{Contained in a separate file:}
MODULE B;
CONST
   Rate = 0.06;
VAR
   Amount, Total, Tax: [GLOBAL] REAL; {Available outside}
[EXTERNAL] PROCEDURE Glf; EXTERNAL;   {Defined elsewhere}
[GLOBAL] PROCEDURE Calc;              {Available outside}
   BEGIN
   Tax := Amount * Rate;
   Total := Tax + Amount;
   Glf;
   END;
END.

The file containing the module can be compiled separately from the file containing the program.

For More Information:


Previous Next Contents Index