[an error occurred while processing this directive]
HP OpenVMS Systems Documentation |
HP Pascal for OpenVMS
|
Previous | Contents | Index |
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 |
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; |
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.
The parameter specification. The syntax for a parameter specification
depends on its semantics.
parameter-spec
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.
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.
This chapter describes the following topics:
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.
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:
Some Pascal identifiers observe additional scope rules:
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:
Figure 7-1 Scope of Identifiers
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.
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.
One or more identifiers that provide additional information about the compilation unit.attribute-list
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. |
When dividing code into programs and modules, you may want to share declarations among compilation units. The following sections discuss ways of sharing data.
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:
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. |
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.
Previous | Next | Contents | Index |