: ФАКТОРИАЛ ( N ---> N! ВЫЧИСЛЕНИЕ N ФАКТОРИАЛ) DUP 2 < IF DROP 1 ( 1 ЕСЛИ N<2, ТО N!=1) ELSE ( N ИНАЧЕ ) DUP ( S,K S=N,K=N ) BEGIN ( S,K ) 1- ( S,K' K'=K-1 ) SWAP OWER ( K',S,K' ) * SWAP ( S',K' S'=S*К' ) DUP 1 = ( S',K',К'=1 ) UNTIL ( S',1 S'=N! ) DROP THEN ; ( N! )
Как и ранее, в комментариях, сопровождающих каждую строчку текста, мы указываем значения, которые остаются на вершине стека после ее исполнения. Такое документирование облегчает понимание программы и помогает при ее отладке.
Цикл с проверкой в начале BEGIN-WHILE-REPEAT используется, когда в цикле есть действия, которые не надо выполнять в заключительной итерации. Исполнение слов, составляющих его тело-1, оставляет на стеке логическое значение — условие продолжения цикла. Слово WHILE (пока) снимает это значение со стека и анализирует его. Если это ИСТИНА (не нуль), то исполняются слова, составляющие тело-2 данного цикла до ограничивающего слова REPEAT (повторять), после чего вновь исполняется тело-1 от слова BEGIN. Если же значение условия ЛОЖЬ (нуль), то исполнение данного цикла завершается и начинают выполняться слова, следующие за REPEAT. Заметьте, что в отличие от цикла BEGIN-UNTIL, значение ИСТИНА соответствует продолжению цикла. Для примера рассмотрим программу вычисления наибольшего общего делителя по алгоритму Евклида:
: НОД ( A,B ---> C:НАИБОЛЬШИЙ ОБЩИЙ ДЕЛИТЕЛЬ) 2DUP < IF SWAP THEN ( ТЕПЕРЬ A>=B ) BEGIN DUP ( A,B,B ) WHILE ( ПОКА B НЕ НОЛЬ ) 2DUP MOD ( A,B,C:ОСТАТОК ) ROT ( B,C,A ) DROP ( A',B' A'=B,B'=C ) REPEAT DROP ; ( НОД )