-
Notifications
You must be signed in to change notification settings - Fork 2
Language Specification (5) : Procedures
A procedure is a sequence of statements associated with an identifier and it may be invoked from any scope in which its identifier is visible. A procedure has its own local scope in which local entities may be declared. It may have zero or more associated parameters and it may return a result in its own name. A procedure that returns a result in its own name is called a function procedure, or simply a function. A procedure that does not is called a regular procedure. Collectively, both are referred to as procedures.
A procedure declaration specifies a procedure header only.
alias procedureDeclaration = procedureHeader ;
procedureHeader := PROCEDURE procedureSignature ;
procedureSignature :=
ident ( ’(’ formalParams ( ’;’ formalParams )* ’)’ )? ( ’:’ returnedType )? ;
A procedure definition specifies a procedure header followed by a procedure body.
procedureDefinition := procedureHeader ’;’ block ident ;
A procedure header consists of a procedure’s identifier, its formal parameters if any, and its return type if any. The procedure header represents the interface of the procedure.
A procedure body consists of a local block followed by the procedure’s identifier. The procedure body represents the implementation of the procedure.
Parameter specified within the parameter list of a procedure header are called the procedure’s formal parameters. Formal parameters determine the number, order, type and passing convention of arguments that may be passed to a procedure when it is invoked.
formalParams := ( CONST | VAR )? identList ’:’ nonAttrFormalType ;
The identifier of a formal parameter is the identifier by which the value of the passed in argument or argument list can be referenced within the body of the procedure.
There are three parameter passing conventions.
- pass by value
- pass by reference, mutable
- pass by reference, immutable
The default parameter passing convention is pass by value. It is used when no attribute is specified for a formal parameter or formal parameter list. Such a parameter is called a value parameter. When an argument is passed to a value parameter, a copy is passed to the procedure. The scope of the copy is the procedure’s local scope.
The pass by mutable reference convention is used when the VAR
attribute is specified for a formal parameter or formal parameter list. Such a parameter is called a VAR
parameter. When an argument is passed to a VAR
parameter, a mutable reference to the argument is passed to the procedure. The procedure may or may not modify the argument. Immutable entities may therefore not be passed to VAR
parameters.
The pass by immutable reference convention is used when the CONST
attribute is specified for a formal parameter or formal parameter list. Such a parameter is called a CONST
parameter. When an argument is passed to a CONST
parameter, an immutable reference to the argument is passed to the procedure. The procedure may not modify the argument. That is, within the scope of the procedure the parameter is treated as if it was a constant. Both mutable and immutable entities may be passed to parameters.
A formal open array parameter is a formal parameter of a formal open array type. Its capacity is indeterminate at compile time. Capacity and value count are determined at runtime when an argument is passed to it in a procedure call.
An argument passed to an open array parameter must be an array whose value type is compatible with the value type of the parameter to which it is passed.
Given the declarations
TYPE Chars = ARRAY 100 OF CHAR; Buffer = ARRAY 100 OF OCTET;
VAR chars : Chars; buffer : Buffer;
PROCEDURE PadWithZeroes ( VAR array : ARRAY OF OCTET );
variable buffer
may be passed to parameter array
in a call to procedure PadWithZeroes
because their value types match, but variable chars
may not be passed to array
because their value types are incompatible.
chars := "abc"; buffer := { 1, 2, 3 };
PadWithZeroes(buffer); (* OK *)
PadWithZeroes(chars); (* compile time error : incompatible type *)
The actual capacity is passed as a hidden parameter immediately preceding the open array parameter.
PROCEDURE PadWithZeroes ( (*hidden capacity : LONGCARD;*) VAR array : ARRAY OF OCTET );
A call to function CAPACITY()
with the identifier of the parameter within the procedure body returns this value.
PROCEDURE PadWithZeroes ( VAR array : ARRAY OF OCTET );
BEGIN
WHILE COUNT(array) < CAPACITY(array) DO
APPEND(array, 0)
END (* WHILE *)
END PadWithZeroes;
A casting formal parameter is a formal parameter of a casting formal type. It causes an argument passed to it to be cast to its formal type. There are two kinds.
A casting formal address parameter is a parameter of formal type CAST
ADDRESS
.
For semantics, see chapter Low-Level Facilities.
A casting formal octet sequence parameter is a parameter of formal type CAST
OCTETSEQ
.
For semantics, see chapter Low-Level Facilities.
A variadic formal parameter is a formal parameter of a variadic formal type to which a variable number of arguments may be passed. All arguments must be passing compatible to its value type.
PROCEDURE average ( args : ARGLIST OF REAL ) : REAL;
···
v := average(1.2, 3.4, 5.6); (* <= OK *) v := average(1.2, 3); (* <= incompatible type *)
The actual argument count is passed as a hidden parameter immediately preceding the argument list.
PROCEDURE average ( (*hidden argc : LONGCARD;*) args : ARGLIST OF REAL ) : REAL;
A call to function COUNT()
with the identifier of the parameter within the procedure body returns this value.
PROCEDURE Variadic ( args : ARGLIST OF T );
BEGIN
WRITE "number of arguments: ", COUNT(args);
A variadic parameter is an indexed collection. A FOR
statement may be used to iterate over its values.
PROCEDURE average ( args : ARGLIST OF REAL ) : REAL; VAR sum : REAL;
BEGIN
IF COUNT(args) = 0 THEN RETURN 0.0 END; sum := 0.0;
FOR value IN args DO
sum := sum + value
END; (* FOR *)
RETURN sum / COUNT(args)
END average;
As with other arrays, values may also be addressed by subscript. The index of the first value is always zero.
FOR index, value IN args DO
sum := sum + args[index] (* args[index] is equivalent to value *)
END; (* FOR *)
An argument list passed to a variadic formal parameter may be enclosed in curly braces to delineate it from other arguments. Such delineation is required whenever the arguments passed to a variadic formal parameter are not distinguishable by their type from the argument that follows the list. Given a formal parameter list of the form
PROCEDURE P ( list1, list2 : ARGLIST OF REAL; x : LONGREAL );
arguments to be passed to parameters list1
and list2
in a procedure call to P
are not distinguishable by type from their following arguments and must be delineated by curly braces.
P({0.1, 2.3}, {3.4, 5.6, 7.8}, 9.0);
Copyright © 2015-2018 Modula-2 Software Foundation