Le problème, c'est que DO ... LOOP
conserve les paramètres de la boucle (index et valeur de terminaison) sur la pile de retour et les rejette à la fin de la boucle. C'est pourquoi >R
y R>
debe être en paires équilibrées au cours d'une boucle.
Votre code place une valeur sur la pile de retour pendant la boucle, qui est ensuite rejetée à la fin de la boucle, laissant un paramètre de boucle égaré encore là, et le tout devient détraqué.
Vous pouvez obtenir le résultat que vous souhaitez comme ceci ...
: REVERSE ( i*x i -- i*y ) 0 DO I ROLL LOOP ;
... bien que je sois un peu perplexe quant à la raison pour laquelle vous voudriez le faire !
EDIT (après lecture des commentaires et de la réponse de ruvim) :
-
Votre algorithme initial d'inversion de la pile n'aurait de toute façon pas fonctionné, car une série de R>
inverse l'ordre sur la pile de retour, et la commande >R
s l'inverse à nouveau sur la pile de paramètres en laissant l'ordre tel qu'il était.
-
Une autre approche, similaire à celle de ruvim mais sans récursivité, est la suivante
: 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
;
Cela ne fonctionnera pas (à cause de l'utilisation de ROLL
) avec tout ce qui affecte la profondeur de la pile comme DROP
o DUP
mais ' 2* 4 APPLY
fonctionne parfaitement !