Comments 7
Поинтересуюсь: а сейчас подпрограммы - рекурсивные? (Когда появился RPG, аппаратного стека не было, и адрес возврата записывался в фиксированное место в памяти, что приводило к зацикливанию программы при рекурсивных вызовах.)
Честно скажу -не знаю. Не задумывался об этом и не пробовал.
Надо будет попробовать ради интереса.
Одну подпрограмму из другой вызвать не проблема. Т.е. какой-то стек точек возврата там есть.
Можно ли сабрутину саму из себя вызвать - не знаю...
Не только саму из себя, кстати. Может ещё быть косвенная рекурсия, самый сложный вариант для поиска ошибки, когда не организован полноценный стек вызовов-возвратов.
Ну в рекурсиях вообще ошибки сложнее искать.
Впрочем, сейчас сабрутины скорее как средство структурирования кода внутри прцедур испольются. Ну и чтобы избежать дублирования одинаковыз участков кода.
Одно время было модно делать выход из процедуры через сабрутину - такая единая точка выхода которую можно из любого места процедуры вызывать. Сейчас не актуально т.к. появился on-exit и можно просто ставить return где надо, а в точке выхода уже всю необходимую финализацию делать.
Так что сабрутины сейчас на второй план отшли.
Так и осталось
Пробуем
dcl-s recLevel int(5);
dcl-s counter int(5) inz(5);
exsr srRecursion;
return;
begsr srRecursion;
recLevel += 1;
dsply ('Recursion Level - ' + %char(recLevel));
dsply ('Counter - ' + %char(counter));
if counter > 0;
counter -= 1;
exsr srRecursion;
endif;
recLevel -= 1;
dsply ('Recursion Level - ' + %char(recLevel));
endsr;
Не компилируется - *RNF7112 30 EXSR or CASxx in subroutine SRRECUR... calls the same subroutine; the specification is ignored.
Пытаемся обмануть
dcl-s recLevel int(5);
dcl-s counter int(5) inz(5);
exsr srRecCall;
return;
begsr srRecCall;
recLevel += 1;
dsply ('Recursion Level - ' + %char(recLevel));
exsr srRecursion;
recLevel -= 1;
dsply ('Recursion Level - ' + %char(recLevel));
endsr;
begsr srRecursion;
dsply ('Counter - ' + %char(counter));
if counter > 0;
counter -= 1;
exsr srRecCall;
endif;
endsr;
Так компилируется, но...
DSPLY Recursion Level - 1
DSPLY Counter - 5
DSPLY Recursion Level - 2
DSPLY Counter - 4
DSPLY Recursion Level - 3
DSPLY Counter - 3
DSPLY Recursion Level - 4
DSPLY Counter - 2
DSPLY Recursion Level - 5
DSPLY Counter - 1
DSPLY Recursion Level - 6
DSPLY Counter - 0
DSPLY Recursion Level - 6
DSPLY Recursion Level - 5
DSPLY Recursion Level - 4
DSPLY Recursion Level - 3
DSPLY Recursion Level - 2
DSPLY Recursion Level - 1
DSPLY Recursion Level - 0
DSPLY Recursion Level - -1
DSPLY Recursion Level - -2
...
И дальше только ENDJOB помогает.
Современный RPG — что может и зачем нужен