Program Structure
This chapter describes the OpenFrame PL/I program structure and its components.
1. Overview
OpenFrame PL/I is a block-structured language comprised of blocks with one or more packages, procedures, begin-blocks, statements, expressions, and built-in functions. An OpenFrame PL/I application is a shared library made up of one or more linked shared libraries and object files. The source code (compilation unit) is compiled to an object file.
A compilation unit is an OpenFrame PL/I package or external procedure. A package includes zero or more procedures and a procedure consists of zero or more blocks. A block contains zero or more statements, procedures that can include blocks, or begin-blocks.
2. Blocks
A variable can be declared in an OpenFrame PL/I block. The variable can be used only in the block and cannot be referenced by another block.
A block performs the following functions:
-
specifying a variable scope.
-
allocating an automatic variable.
-
specifying a DEFAULT statement scope.
A block may be one of the following types:
-
Package
-
Procedure
-
Begin
Block activation allocates automatic variable storage and initializes variables declared in the block. Block termination removes condition handlers registered in the block for ON-units.
2.1. PACKAGE statement
A PACKAGE statement can only include variable declarations, DEFAULT statements, and procedure blocks. OpenFrame PL/I currently only supports procedure blocks in a PACKAGE statement and does not support PACKAGE statement options.
Component | Description |
---|---|
condition_prefix |
Condition prefix that applies to all procedures of a package. For more information, refer to the description of Condition Prefix in Conditions. |
package_name |
Package name. |
2.2. Procedure
A procedure consists of a PROCEDURE statement and consecutive statements delimited by an END statement. A procedure must be given a name.
A procedure block can be nested in another procedure block or begin-block. A nested procedure is called an internal procedure and an unnested procedure is called an external procedure. An external procedure is called by another procedure from another compilation unit. For more information about a procedure call, refer to Procedure Call.
A procedure can be a main procedure, subroutine, or function. An OpenFrame PL/I application must contain one external procedure that includes the OPTIONS (MAIN) option.
In the following example, FUNC1 is the procedure name, which is the procedure’s entry point name.
FUNC1: PROCEDURE; END FUNC1;
An ENTRY statement defines an additional entry point.
FUNC1: PROCEDURE; FUNC2: ENTRY; END FUNC1;
FUNC2 is an additional entry point for the FUNC1 procedure.
2.2.1. PROCEDURE (PROC) Statement
The PROCEDURE statement defines the start of a procedure.
Component | Description |
---|---|
entry-label |
Procedure’s entry point name. |
parameter-list |
Procedure’s parameters. |
returns-options |
Procedure’s RETURN attribute. |
OPTIONS |
Only MAIN is supported. MAIN indicates a MAIN procedure of an OpenFrame PL/I program. |
2.2.2. ENTRY statement
All non-pointer parameters of any procedures that include an ENTRY statement must be BYADDR (pass by address).
Component | Description |
---|---|
entry-label |
Additional entry point name of the procedure. |
parameter-list |
Parameters of the entry point. |
returns-options |
RETURNS option of the entry point. |
2.2.3. PARAMETER Attribute
When a parameter defined in a PROCEDURE or an ENTRY statement is declared as a variable, it is automatically declared as a PARAMETER but it can also be explicitly declared as a PARAMETER. The variable always has internal attributes.
The PARAMETER attribute can be defined in a DECLARE statement as follows:
2.2.4. RETURNS Option and Attributes
The RETURNS option defines the RETURN attributes for a function procedure. When a procedure includes an ENTRY statement, RETURN attributes of the procedure and the ENTRY statement must match.
Multiple attributes are delimited by a blank space. The attributes must be the same as the attributes specified in the DECLARE statement.
2.3. Begin-block
A begin-block consists of a BEGIN statement and consecutive statements that are delimited by an END statement.
The following is an example of a begin-block:
LAB1: BEGIN; statement statement statement ... END LAB1;
2.3.2. END statement
An END statement specifies the end of one or more blocks or groups. Every block or group must have an END statement.
Component | Description |
---|---|
statement-label |
Label of the nearest preceding DO, SELECT, PACKAGE, BEGIN or PROCEDURE statement before the END statement to indicate the end of a block or group. If omitted, the END statement closes the nearest preceding block or group. |
3. Procedure Call
A procedure can call another procedure. A called procedure is a subroutine without a return value or a function with a return value.
-
Calling a subroutine using a CALL statement
A subroutine is an internal or external procedure called by a CALL statement. It does not return a result value.
When calling a subroutine, consider the following:
-
A PROCEDURE statement cannot have a RETURNS option.
-
If the subroutine is an external procedure, it cannot be declared as an Entry with the RETURNS attribute.
-
The subroutine must be called using a CALL statement, not through a function reference.
-
The subroutine cannot return a result value through a RETURN statement.
The following calls the SUB1 subroutine:
TEST: PROCEDURE OPTIONS(MAIN); CALL SUB1( 20, 20 ); END TEST; SUB1: PROC( PARM1, PARM2 ); DECLARE PARM1 FIXED DEC (7); DECLARE PARM2 FIXED DEC (7); DISPLAY( PARM1 + PARM2 ); END SUB1;
-
-
Calling a function through a function reference
A function is called through a function reference, which is an expression. When evaluating an expression, the control of the program execution is passed to the function through the function reference. At the end of the function, the program execution returns to the original function call and the program continues to evaluate the expression.
When calling a function, consider the following:
-
A PROCEDURE statement must have a RETURNS option.
-
If the function is an external procedure, it must be declared using an ENTRY statement that has the RETURNS attribute.
-
The function can be called either through a function reference or a CALL statement.
-
The RETURNS attributes of a RETURNS option specified in a PROCEDURE or ENTRY statement as well as those declared as an Entry in a DECLARE statement must be the same.
-
The function returns a result value through a RETURN statement.
The following calls the FUNC1 function:
TEST: PROCEDURE OPTIONS(MAIN); DECLARE SUM FIXED DEC(7); SUM = FUNC1( 20, 20 ); END TEST; FUNC1: PROC( PARM1, PARM2 ) RETURNS ( FIXED DEC(7) ); DECLARE PARM1 FIXED DEC (7); DECLARE PARM2 FIXED DEC (7); DECLARE RESULT FIXED DEC (7); RESULT = PARM1 + PARM2; RETURN (RESULT); END FUNC1;
While the ASSIGN statement, SUM = FUNC(20, 20);, is being processed in the TEST procedure, FUNC1 is called through the function reference by passing PARM1 (20) and PARM2 (20) as arguments.
FUNC1 adds the arguments, saves the result to RESULT, and returns it to the calling procedure which continues to execute the ASSIGN statement by saving the return value to SUM.
-
3.1. Passing Arguments to a Procedure
When a subroutine or function is called, arguments are assigned to its parameters.
-
A computational data can be assigned to a computational data parameter of a different type.
Computational data types include FIXED BIN, FIXED DEC, FLOAT DEC, FLOAT BIN, and CHARACTER. A FIXED, DEC or FIXED BIN type data can be assigned to a CHARACTER parameter.
-
A program-control data must be assigned to a parameter of the same type.
The following are exceptions:
-
Pointer and offset arguments can be assigned to offset and pointer parameters respectively.
-
A label constant array cannot be used as an argument.
-
Before a subroutine or function is called, expressions of an argument list in the calling procedure are processed first.
Parameters do not have memory storage, but a called procedure uses it to access memory storage of the calling procedure.
The following describes how to pass arguments to a procedure:
BYVALUE and BYADDR
BYVALUE passes an argument value to the calling procedure’s parameter.
If BYVALUE is specified, a dummy argument is not created. Changes in parameters of the called procedure do not affect parameters of the calling procedure.
BYVALUE can be used for scalar arguments or parameters, the length and size of which become known during compilation. Data aggregates, such as a structure and an array, cannot be used. The following data types can be used:
-
REAL FIXED BIN
-
REAL FLOAT
-
CHAR(1)
BYADDR assigns an argument address to the calling procedure’s parameter. Values in the address are used for the parameters. If parameter values are changed, argument values are also changed.
To use a constant as an argument, a dummy argument is created and passed. Since a parameter references the dummy argument address, the original argument value is not changed.
Dummy Argument
A dummy argument is created if an argument is one of the following:
-
Constant
-
CHAR(1)
-
Variable with data, alignment, or connected attribute differing from those of the parameter
A dummy argument’s attributes are determined as follows:
-
According to the attributes of the parameters of an internal procedure
-
According to the parameter-descriptor attributes in an external entry declaration. (A parameter attribute specified in a DECLARE statement for declaring an entry is called a parameter descriptor.)
-
According to an argument’s array size, string length, or area size if an asterisk (*) is specified in a declared parameter’s attribute
The following rules are applied to a dummy argument:
-
If a parameter is an element (non-structure and non-array variable), the argument must be an element.
-
If a VARYING or VARYINGZ string element is passed to a non-fixed length NONVARYING parameter because the element is specified with an asterisk (*), a dummy argument with the current argument length is created.
-
If a parameter is program-control data except for a locator (pointer or offset), an argument must have the same data type as the parameter.
-
If a parameter is a locator, the argument must be a locator. If the argument has a different type, a dummy argument is created. Related areas must not be defined in an offset parameter’s parameter-descriptor.
-
If a parameter is a controlled data, this must be specified in a parameter-descriptor when declaring an entry.
The following applies to a controlled argument:
-
A subscript cannot be used.
-
A controlled argument must be the element of a structure.
-
A dummy argument cannot be created.
-
3.2. Entry Data
There are two kinds of Entry data: Entry constant and Entry variable.
An Entry constant is a label prefix (name) in a PROCEDURE or ENTRY statement, or a name with the ENTRY attribute but without the VARIABLE attribute in a DECLARE statement. An Entry constant can be saved in an Entry variable.
-
Entry constant
-
An Entry constant is declared explicitly as a label prefix in a PROCEDURE or ENTRY statement.
-
A parameter-descriptor-list can be obtained from parameter declarations in a PROCEDURE or ENTRY statement.
-
An external Entry constant (a procedure or Entry name in another compilation unit) must be declared explicitly using a DECLARE statement. For this, an Entry point is declared for an external procedure.
-
A parameter-descriptor-list can be specified optionally. If a corresponding Entry is a function, attributes can also be specified for a return value.
-
-
Entry variable
-
The VARIABLE attribute is specified in an ENTRY attribute.
-
An internal entry value (Entry point declared using a PROCEDURE or ENTRY statement) or external entry value (data item, declared using a DECLARE statement, with the ENTRY attribute) is saved in a variable declared using a DECLARE statement.
-
An Entry variable can be included in a data aggregate.
-
In the following example, TEST, ENT_CON1 and ENT_CON2 are Entry constants and ENT_VAR is an Entry variable:
TEST: PROC; DECLARE ENT_VAR Entry variable; DECLARE (ENT_CON1, ENT_CON2) ENTRY; ENT_VAR = ENT_CON2; CALL ENT_VAR; ENT_VAR = ENT_CON1; CALL ENT_VAR; END TEST;
The Entry point ENT_CON2 is called in the first CALL statement and the Entry point ENT_CON1 is called in the second CALL statement.
ENTRY attributes
The ENTRY attribute indicates that a variable declared using a DECLARE statement is an Entry constant or variable.
Component | Description |
---|---|
parameter-descriptor |
Attributes of an external entry parameter. These attributes are compared with an argument’s attributes when the program is called, to determine whether a dummy argument needs to be created. If a parameter-descriptor-list is not specified, parameter attributes are determined according to corresponding argument attributes. Therefore, if attributes of an argument are different from those of an external entry parameter specified in another compilation unit, a parameter-descriptor-list must be specified. An asterisk (*) indicates that a parameter attribute is the same as the corresponding argument attribute. |
structure-descriptor |
Attributes of a structure if the parameter is a structure. Since a level number can be specified, member attributes can also be specified. |
VARIABLE |
Indicates that variable declared using a DECLARE statement is an Entry variable. If VARIABLE is not specified, Entry data is used as an Entry constant. |
RETURNS |
Attributes of a return value of an external entry. |
attribute |
Data attributes. A dimension attribute must be specified first. |
3.3. CALL statement
A CALL statement calls a subroutine.
Component | Description |
---|---|
entry-reference |
Subroutine name. |
generic-name |
Variable name declared as GENERIC. |
built-in name |
Built-in function name. |
argument |
List of arguments to pass into the subroutine. |
3.4. RETURN statement
A RETURN statement terminates the execution of a procedure and the control is returned to the calling code.
-
A RETURN statement with an expression cannot be used within a procedure with OPTIONS(MAIN).
-
A RETURN statement without an expression cannot be used within a procedure with RETURNS options.
-
A procedure with RETURNS options must have one or more RETURN statements.