Рекурсивный макрос очень нетипичен.Вы получите гораздо лучший опыт рекурсивного программирования, используя Proc DS2
и реализуя в нем методы.
В любом случае, вы должны понимать, что макрос не является нормальным функциональным языком программирования;это генератор исходного кода с побочными эффектами.Ваш макрос может не излучать какой-либо исходный код и быть запрограммирован исключительно для побочных эффектов, или он может быть записан для генерации исходного кода в соответствии с шаблоном и не иметь других побочных эффектов.
%macro fib(n);
%if &n < 0 %then %abort cancel;
%if &n = 0 %then
0 /* emit source code 0. The %if is a recursion sentinel */
;
%else
%if &n = 1 %then
1 /* emit source code 1. The %if is a recursion sentinel */
;
%else %do;
/* emit source code that is side effect of eval summing recursive invocation */
%eval (
%fib(%eval(&n-1)) + %fib(%eval(&n-2))
)
%end;
%mend;
%put %fib(0);
%put %fib(1);
%put %fib(2);
%put %fib(3);
%put %fib(4);
%put %fib(5);
%put %fib(6);
Полученный чистый результат равениз макро объекта (подсистема).
% fib (6) генерация кода будет
%put
%eval (
%eval ( /* 5 */
%eval ( /* 4 */
%eval ( /* 3 */
%eval ( /* 2 */
1 /* 1 */
+
0 /* 1 */
)
+
%eval ( /* 1 */
1
)
)
+
%eval ( /* 2 */
1 /* 1 */
+
0 /* 1 */
)
)
+
%eval ( /* 3 */
%eval ( /* 2 */
1 /* 1 */
+
0 /* 1 */
)
+
%eval ( /* 1 */
1
)
)
)
+
%eval ( /* 4 */
%eval ( /* 3 */
%eval ( /* 2 */
1 /* 1 */
+
0 /* 1 */
)
+
%eval ( /* 1 */
1
)
)
+
%eval ( /* 2 */
1 /* 1 */
+
0 /* 1 */
)
)
)
;