Skip to content

Language Specification (5) : Procedures

Benjamin Kowarsch edited this page Jan 12, 2024 · 5 revisions

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.

Procedure Institution

Procedure Declaration

A procedure declaration specifies a procedure header only.

alias procedureDeclaration = procedureHeader ;
procedureHeader := PROCEDURE procedureSignature ;
procedureSignature :=
  ident ( ’(’ formalParams ( ’;’ formalParams )* ’)’ )? ( ’:’ returnedType )? ;

Procedure Definition

A procedure definition specifies a procedure header followed by a procedure body.

procedureDefinition := procedureHeader ’;’ block ident ;

The Procedure Header

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.

The Procedure Body

A procedure body consists of a local block followed by the procedure’s identifier. The procedure body represents the implementation of the procedure.

Formal Parameters

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.

Parameter Passing Conventions

There are three parameter passing conventions.

  • pass by value
  • pass by reference, mutable
  • pass by reference, immutable

Pass By Value

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.

Pass By Reference – Mutable

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.

Pass By Reference – Immutable

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.

Formal Open Array 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;

Casting Formal Parameters

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.

Casting Formal Address Parameter

A casting formal address parameter is a parameter of formal type CAST ADDRESS.

For semantics, see chapter Low-Level Facilities.

Casting Formal Octet Sequence Parameter

A casting formal octet sequence parameter is a parameter of formal type CAST OCTETSEQ.

For semantics, see chapter Low-Level Facilities.

Variadic Formal Parameters

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);
Clone this wiki locally