プロシージャ ブロックは、呼び出されるたびにアクティブになり、呼び出しから戻るまで (またはローカル以外の GOTO から包含するブロックの有効化に制御が移るまで) アクティブな状態となります。それらのプロシージャの有効化により、関連する記憶域ブロックがスタックに割り当てられます。この記憶域ブロックはスタック フレームと呼ばれ、それぞれのプロシージャの有効化に固有の情報 (制御が有効化から戻る位置など) を保持するために使用されます。
スタック フレームには、ブロック内で宣言された自動データ用の記憶域があります。そのため、ブロックが有効化されるたびに自動データの独自のコピーが格納されます。
プロシージャ A からプロシージャ B を呼び出すと、A の有効化に関連するスタック フレームが B の有効化に関連するスタック フレームによってプッシュダウンされます。B から制御が戻ると、B のスタック フレームがスタックから取り出され、A のスタック フレームが現在のスタック フレームになります。
プロシージャ A が呼び出す一連のプロシージャによって A が直接的または間接的に再度呼び出される場合、A のことを再帰プロシージャと呼びます。次に例を示します。
A: PROCEDURE RECURSIVE;
.
.
.
CALL A;
.
.
.
END A;
次の例は、ブロックの有効化および再帰の原則を使用してツリー構造のコピーを作成するプログラムを示しています。
.
.
NEW = COPY(OLD);
.
.
COPY: PROCEDURE(IN) RETURNS(POINTER)| RECURSIVE;
DECLARE (IN,OUT) POINTER;
DECLARE 1 RECORD BASED,
2 FIELD1 FLOAT,
2 FIELD2 FLOAT,
2 DAUGHTER POINTER,
2 SON POINTER;
DECLARE NULL BUILTIN;
IF IN = NULL THEN RETURN(NULL);
ALLOCATE RECORD SET(OUT);
OUT->RECORD.FIELD1 = IN->RECORD.FIELD1;
OUT->RECORD.FIELD2 = IN->RECORD.FIELD2; OUT->RECORD.DAUGHTER =
COPY(IN->RECORD.DAUGHTER);
OUT->RECORD.SON = COPY(IN->RECORD.SON);
RETURN(OUT);
END COPY;
この例で示すように、元のツリー構造の各レコードは SON レコードまたは DAUGHTER レコード (あるいはその両方) へのポインターを使用してリンクされます。SON フィールドと DAUGHTER フィールドは、いずれかが Null ポインター値であってもかまいません。COPY は、元のツリー構造のルートへのポインターを使用して呼び出され、そのコピーである新しいツリー構造のルートへのポインターを返します。COPY プロシージャが有効化されるたびに、変数 IN および OUT の独自のインスタンスが格納されます。
再帰プロシージャの詳細については、「データ型」の章の「エントリ データ」のセクションを参照してください。