Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world

Software Engineers
Handbook/Language
Dictionary/PLI/procedures
Note: This article requires basic knowledge of PL/I which can be found in Software Engineers
Handbook/Language Dictionary/PLI.

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 1/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world

Contents
Procedures
Procedures as Subroutines
Procedures as Functions
Changes of Parameter Variables
Asterisk Notation
Locale Variables
Scope
Storage Class
Multiple Entries
Multiple Parm Lists
Recursive Procedures
Entry Variables and Parameters
External Procedures
Static Linking
Fetched Procedures
"Pseudo-Fetching"
Notes

Procedures

Procedures as Subroutines
A PL/I program may contain user defined subroutines:

The definition of a (internal) subroutine starts with


The name of the subroutine followed by ':'
The keyword PROCEDURE (abbreviation: PROC)
Optionally a parameter-descriptor list in brackets
The subroutine will be invoked by CALL statements
The subroutine may be left by optionally return statements

example: proc options ( main );


call proc_1 ( 0 ); /* output: 'zero' */
call proc_1 ( 7 ); /* output: 'the number is 7' */
proc_1: proc ( parm );
dcl parm bin fixed (15);
if parm = 0 then
do;
put skip list ( 'zero' );
return;
end;
put skip list ( 'the number is' || parm );
end proc_1;
end example;

Procedures as Functions

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 2/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world

A PL/I programm may contain user defined functions:

The definition of a (internal) function starts with


The name of the function followed by ':'
The keyword PROCEDURE (abbreviation: PROC)
Optionally a parameter-descriptor list in brackets
The keyword RETURNS followed by the type of the return value in brackets
The result of the function may be used in expressions
The subroutine must have at least one return statements which returns the result

example: proc options ( main );


dcl number bin fixed (31);
put skip list ( hundred ( 0 ) ) ; /* output: 0 */
put skip list ( hundred ( 3 ) ) ; /* output: 300 */
number = hundred ( 5 ) + 55;
put skip list ( number ); /* output: 555 */
hundred: proc ( parm ) returns ( bin fixed (31) );
dcl parm bin fixed (15);
if parm = 0 then return ( 0 );
return ( parm * 100 );
end hundred;
end example;

Changes of Parameter Variables


When a procedure is invoked with variables as parameter this parameters may be passed in one of
the following ways:

"By reference" (also known as "by name") which means changes inside the procedure alters
the original variable.
"By value" (or "as dummy") which means changes inside the procedure alters only a copy of
the original variable.
In PL/I a variable which is

of simple type, e.g. char, number, ...


an array of simple type variables
a structure of simple type variables [1]
is passed by reference if and only if the variable matches exactly the argument definition inside the
procedure.

example: proc options ( main );


dcl bifi_15 bin fixed (15);
dcl bifi_31 bin fixed (31);
bifi_15 = 15;
call change ( bifi_15 );
put skip list ( bifi_15 ); /* output: 99 */
bifi_31 = 31;
call change ( bifi_31 );
put skip list ( bifi_31 ); /* output: 31 */
change: proc ( parm_15 );
dcl parm_15 bin fixed (15);
parm_15 = 99;

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 3/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world
end change;
end example;

Asterisk Notation
If the size attribute of the parameter definition is an asterisk every matching variable with any
size is passed by reference.
If the dimension of the parameter definition is an asterisk every matching variable with any
dimension is passed by reference.

example: proc options ( main );


dcl a_ch (2) char (10);
dcl b_ch (5) char (20);
dcl v_ch (5) char (20) varying;
a_ch (1) = 'BEFORE'
call change ( a_ch );
put skip list ( a_ch (1) ); /* output: 'AFTER ' */
b_ch (1) = 'BEFORE'
call change ( b_ch );
put skip list ( b_ch (1) ); /* output: 'AFTER ' */
v_ch (1) = 'BEFORE'
call change ( v_ch );
put skip list ( v_ch (1) ); /* output: 'BEFORE' because v_ch-strings are varying */
change: proc ( ch_array );
dcl ch_array (*) char (*);
ch_array (1) = 'AFTER';
end change;
end example;

Locale Variables

Scope
The scope of PL/I variables is confined to procedures in which they are declared.

outer: proc options ( main );


dcl a char (07) init ( 'outer A' );
dcl b char (07) init ( 'outer B' );
call inner;
put skip list ( a );
put skip list ( b );
inner: proc;
dcl b char (07) init ( 'inner B' );
dcl c char (07) init ( 'inner C' );
put skip list ( b );
put skip list ( c );
end inner;
end outer;

output:
'inner B'
'inner C'
'outer A'
'outer B'

outer: proc options ( main );


call hello; /* output: 'hello from outer' */
call inner; /* output: 'hello from inner' */
hello: proc;
put skip list ( 'hello from outer' );
end hello;
inner: proc;
call hello;
hello: proc;
put skip list ( 'hello from inner' );
end hello;

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 4/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world
end inner;
end outer;

Storage Class
There are two storage class locale variables may have.[2]

Automatic storage:

Its value is lost between successive invocations of the procedure


If the variable has the INIT attribute initialisation is done every time the procedure is invoiced
The keyword AUTOMATIC may be abbreviated as AUTO
Locale variables are automatic by default[3]
Static storage:

Its value is saved between successive invocations of the procedure


If the variable has the INIT attribute initialisation is done only once when program starts

example: proc options ( main );


call static_memory ( 7 );
call static_memory ( 0 ); /* output: 7 */
call auto_memory ( 7 );
call auto_memory ( 0 ); /* output: 1 */
static_memory: proc ( parm );
dcl parm bin fixed (15);
dcl memory bin fixed (15) init ( 1 ) STATIC;
if parm = 0 then
put skip list ( memory );
else
memory = parm;
end static_memory;
auto_memory: proc ( parm );
dcl parm bin fixed (15);
dcl memory bin fixed (15) init ( 1 );
if parm = 0 then
put skip list ( memory );
else
memory = parm;
end auto_memory;
end example;

Multiple Entries
Procedures may have more than one entry.

example: proc options ( main );


dcl number bin fixed (15);
call value_set ( 3 );
call value_get ( number );
put skip list ( number ); /* output: 3 */
call value_calc ( 2 , 1 );
call value_write; /* output: 7 */
value_set: PROC ( parm_1 );
dcl parm_1 bin fixed (15);
dcl memory bin fixed (15) static;
memory = parm_1;
return;
value_get: ENTRY ( parm_1 );
/* do NOT declare parm_1 and memory once again ! */
parm_1 = memory;
return;
value_calc: ENTRY ( parm_1 , parm_2 );
dcl parm_2 bin fixed (15);
memory = memory * parm_1 + parm_2;
return;

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 5/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world
value_write: ENTRY;
put skip list ( memory );
end value_set;
end example;

Multiple Parm Lists


Using the attribute GENERIC procedures may have more than one parm list.

Syntax:
DCL procname
GENERIC ( procname_1 WHEN ( parm_descriptor_1 ) ,
procname_2 WHEN ( parm_descriptor_2 ) );
Meaning at compile time:
WHENEVER a call of procname is inside the source
IF the calling parameters are like parm_descriptor_1 THEN replace procname with procname_1
ELSE IF the calling parameters are like parm_descriptor_2 THEN replace procname with procname_2
ELSE throw compile error

Parm descriptor may contain the attributes of the calling parameters:

example: proc options ( main );


dcl twice generic ( twice_C when ( char ) ,
twice_F when ( fixed ) );
put skip list ( twice ( 'hello' ) ); /* output: 'hello hello' */
put skip list ( twice ( 1234321 ) ); /* output: 2468642 */
twice_C: proc ( parm ) returns ( char (11) );
dcl parm char (05);
return ( parm || ' ' || parm );
end twice_C;
twice_F: proc ( parm ) returns ( bin fixed (31) );
dcl parm bin fixed (31);
return ( parm + parm );
end twice_F;
end example;

Parm descriptor may contain the number of the calling parameters:

dcl calc generic ( calc_with_3_parameters when ( * , * , * ) ,


calc_with_2_parameters when ( , ) ,
calc_with_1_parameter when ( * ) );
calc_with_3_parameters: proc ( a , b , c );
...
calc_with_2_parameters: proc ( a , b );
...
calc_with_1_parameter: proc ( a );
...

Parm descriptor may contain the number of dimensions of the calling parameters:

dcl calc generic ( calc_value when ( ( * ) ) ,


calc_vector when ( ( * , * ) ) ,
calc_matrix when ( ( * , * , * ) ) );
calc_value: proc ( v );
dcl v char (12);
...
calc_vector: proc ( v ):
dcl v (5) bit (1);
...
calc_matrix: proc ( v ):
dcl v (5,8) bin fixed (15);
...

Recursive Procedures
A procedure may be invoked recursively if the RECURSIVE option is specified.
https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 6/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world

Every invocation of the procedure has it's own value of the calling parameters
Every invocation of the procedure has it's own value of local variables which are automatic
All invocations of the procedure have a common value of local variables which are static

example: proc options ( main );


dcl number bin fixed (15);
call test ( 1 );
test: proc ( level ) RECURSIVE;
dcl level pic '9';
dcl loc_a pic '99';
dcl loc_s pic '999' static;
dcl pre char (09);
loc_a = level * 11;
loc_s = level * 111;
pre = substr ( ' ' , 1 , 3 * level );
put skip list ( pre || 'Level ' || level || ' started' );
put skip list ( pre || 'loc_a = ' || loc_a );
put skip list ( pre || 'loc_s = ' || loc_s );
if level < 3 call test ( level + 1 );
put skip list ( pre || 'loc_a = ' || loc_a );
put skip list ( pre || 'loc_s = ' || loc_s );
put skip list ( pre || 'Level ' || level || ' ended' );
end test;
end example;

Output:
Level 1 started
loc_a = 11
loc_s = 111
Level 2 started
loc_a = 22
loc_s = 222
Level 3 started
loc_a = 33
loc_s = 333
loc_a = 33
loc_s = 333
Level 3 ended
loc_a = 22
loc_s = 333
Level 2 ended
loc_a = 11
loc_s = 333
Level 1 ended

Entry Variables and Parameters


Like other data procedures may be used as variables and parameters.

example: proc options ( main );


dcl e_var ENTRY;
e_var = proc_1;
call e_var; /* output: 'proc 1' */
e_var = proc_2;
call e_var; /* output: 'proc 2' */
proc_1: proc;
put skip list ( 'proc 1' );
end proc_1;
proc_2: proc;
put skip list ( 'proc 2' );
end proc_2;
end example;

example: proc options ( main );


call list ( 'square' , square_proc );
call list ( 'cube' , cube_proc );
list: proc ( title , calc );
dcl title char (*);
dcl calc entry ( bin fixed (15) ) returns ( bin fixed (15) );
dcl i bin fixed (15);
put skip list ( title || '-table:' );

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 7/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world
do i = 1 to 5;
put skip list ( i || ':' || calc ( i ) );
end;
end list;
square_proc: proc ( v ) returns ( bin fixed (15) );
dcl v bin fixed (15);
return ( v * v );
end square_proc;
cube_proc: proc ( v ) returns ( bin fixed (15) );
dcl v bin fixed (15);
return ( v * square_proc ( v ) );
end cube_proc;
end example;

Output:
square-table:
1: 1
2: 4
3: 9
4: 16
5: 25
cube-table:
1: 1
2: 8
3: 27
4: 64
5: 125

External Procedures
A procedure may be external, i.e. the source may be contained in a separate file.
This approach offers the possibility to use this procedure in more than one main program.
Every program or procedure which uses an external procedure must declare this procedure.

Source File of external procedure EXT1:


ext1: proc;
put skip list ( 'Hello from EXT-1' );
end ext1;

Source File of external procedure EXT2:


ext2: proc ( message );
dcl message char (*);
dcl ext1 EXTERNAL ENTRY; /* declaration of used external procedure */
put skip list ( 'EXT-2:' );
put skip list ( message );
call ext1;
end EXT2;

Source File of MAIN:


example: proc options ( main );
dcl ext2 EXT ENTRY ( CHAR (*) ); /* keyword EXTERNAL may be abbreviated */
call ext2 ( 'Called by Example' );
end example;

Output running example


EXT-2:
Called by Example
Hello from EXT-1

Static Linking
Making a program executable requires two steps:

1. Compile the program and all the used external procedures in any order.
2. Use the linkage editor to combine the compile objects to an executable program.

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 8/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world

The executable program now contains the binary code of its procedures at linking time,
i.e. if an external procedure is changed and recompiled after linking time this would not change the
behaviour of the executable program.

Fetched Procedures
PL/I allows dynamic linking of external procedures,
i.e. a main program may load the last compiled version of a procedure at run time.

The statement FETCH ABC loads the binary of procedure ABC from auxiliary storage into main
storage (unless ABC already exists in main storage).

The statement RELEASE ABC frees main storage occupied by ABC[4].

example: proc options ( main );


dcl abc EXT ENTRY;
dcl dfg EXT ENTRY;
dcl ( b1 , b2 ) bit (1);
.....
if b1 then
do;
fetch abc;
call abc;
release abc;
end;
.....
if b2 then
do;
fetch abc, dfg;
call abc;
call dfg;
release abc, dfg;
end;
end example;

"Pseudo-Fetching"
If in the example above both b1 and b2 are true ...

abc will be released after the first call


abc will be loaded again before the second call
... which is not very effective.

PL/I has the following properties:

A procedure will be recognised as to_be_loaded_dynamicly iff the program somewhere


contains a fetch or release statement, it is not necessary that this statement will be reached at
any time.
If a procedure recognised as to_be_loaded_dynamicly is invoked at runtime it will be fetched
automatically if necessary.
Using this two properties the program above may be rewritten as:

example: proc options ( main );


dcl abc EXT ENTRY;
dcl dfg EXT ENTRY;
dcl ( b1 , b2 ) bit (1);
if 1 > 2 then /* this will never be true */
fetch abc, dfg; /* but abc and dfg will be MARKED AS TO_BE_LOADED_DYNAMICLY */
.....
if b1 then
do;

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 9/10
5/1/24, 3:54 PM Software Engineers Handbook/Language Dictionary/PLI/procedures - Wikibooks, open books for an open world
/* COMMENT: IF ABC IS NOT YET IN MAIN STORAGE THEN LOAD IT AUTOMATICALLY */
call abc;
end;
.....
if b2 then
do;
/* COMMENT: IF ABC IS NOT YET IN MAIN STORAGE THEN LOAD IT AUTOMATICALLY */
call abc;
/* COMMENT: IF DFG IS NOT YET IN MAIN STORAGE THEN LOAD IT AUTOMATICALLY */
call dfg;
end;
end example;

Notes
[1] or an array of structures of simple type variables ...
[2]
there are two more storage class (based and controlled for dynamically allocated storage)
which will be explained in another wikibooks PL/I special.
[3] in PL/I default values may be altered using the DEFAULT statement.
[4]the FREE statement for a fetched procedure will also free the local static variables of this
procedure.

Retrieved from "https://en.wikibooks.org/w/index.php?


title=Software_Engineers_Handbook/Language_Dictionary/PLI/procedures&oldid=4101798"

This page was last edited on 7 September 2022, at 11:59.

Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using
this site, you agree to the Terms of Use and Privacy Policy.

https://en.wikibooks.org/wiki/Software_Engineers_Handbook/Language_Dictionary/PLI/procedures 10/10

You might also like