Проблема, с которой вы столкнулись, состоит в том, что DO ... LOOP
сохраняет параметры l oop (индекс и значение завершения) в стеке возврата и отбрасывает их в конце l oop. Вот почему >R
и R>
должны быть сбалансированными парами в течение всего oop.
Ваш код помещает значение в стек возврата в течение l oop, что затем сбрасывается в конце l oop, оставляя безразличный параметр l oop все еще там, и все становится бесполезным.
Вы можете получить желаемый результат, как этот ...
: REVERSE ( i*x i -- i*y ) 0 DO I ROLL LOOP ;
... хотя я немного озадачен тем, почему вы захотите!
РЕДАКТИРОВАТЬ (после прочтения комментариев и ответа ruvim):
-
Ваш первоначальный алгоритм стекового изменения стека не сработал бы в любом случае, поскольку серия R>
s меняет порядок в стеке возврата, а соответствующие >R
s снова возвращают его обратно в стек параметров, оставляя порядок как это было.
Здесь есть альтернативный подход, аналогичный ruvim, но без рекурсии
: APPLY ( n*x xt n -- n*x' )
DUP 1- -ROT ( n*x n-1 xt n )
0 DO ( n*x n-1 xt )
2>R \ park n-1 xt on return stack
2R@ DROP ROLL \ bring next item to top
2R@ NIP EXECUTE \ apply the function to it
2R> \ clear junk off return stack for now
LOOP ( n*x n-1 xt )
2DROP
;
Это не сработает (потому что использования ROLL
) со всем, что влияет на глубину стека, например DROP
или DUP
, но ' 2* 4 APPLY
работает просто отлично!