СТЕК ВОЗВРАТОВ
Ранее мы рассмотрели несколько операций со стеком. Однако существует еще целый ряд операций, с которыми, вам предстоит познакомиться. До сих пор речь шла лишь о конкретном стеке так, как если бы он был один. Но на самом деле их два: стек данных и стек возвратов. Стек данных используется при программировании на Форте чаще, поэтому в тех случаях, когда это не вызывает недоразумений, он называется просто стеком.
Как вы уже видели, в стеке данных хранятся параметры (или аргументы), передаваемые от слова к слову. Стек же возвратов содержит любое число указателей, используемых Форт-системой для нахождения оптимального пути в лабиринте слов, которые вызывают выполнение других слов. Подробнее этот вопрос мы обсудим позднее.
Пользователь может рассматривать стек возвратов в качестве некоторого рода «дополнительной руки», которая «держит» значения в то время, когда вы работаете со стеком данных.
Подобно стеку данных, стек возвратов организован по принципу «последним внесен - первым выбран», поэтому в нем может храниться много значений. Но здесь имеется одна тонкость: данные, внесенные в стек возвратов, вы должны выбрать из него прежде, чем дойдете до конца соответствующего определения (точки
с запятой), так как в этот момент в вершине стека должен находиться некоторый указатель, используемый самой Форт-системой. Вы не имеете права обращаться к стеку возврата для передачи параметров от одного слова к другому.
Ниже дается перечень слов, связанных со стеком возвратов. Помните, что описание состояния стека относится здесь к стеку данных.
>R ( n -- ) Выборка значения из стека данных и занесение его в стек возвратов.
R> ( -- n ) Выборка значения из стека возвратов и занесение его в стек данных.
R@ ( -- n ) Копирование содержимого вершины стека возвратов без изменения его значения.
Слова >R и R> перемещают элемент стека данных в стек возвратов и элемент стека возвратов в стек данных соответственно. Показанные выше забавные рисунки иллюстрируют операции со стеком в состоянии (2 3 1 -- 3 2 1),
заданные выражением>R SWAP R>
Каждое слово >R и соответствующее ему слово R> должны выполняться совместно в одном и том же определении или, если они выполняются в диалоговом режиме, в одной и той же вводимой строке (прежде чем вы нажмете клавишу RETURN).
Слово R@ только копирует значение из стека возвратов, но не удаляет его. Так что, введя выражение >R SWAP R@
вы получите ожидаемый результат, но если при этом не уберете «мусор» до следующего двоеточия (или до того, как нажмете клавишу возврата каретки), то выведите систему из строя.
Поясним изложенное на примере. Допустим, вам настолько не повезло, что приходится вычислять значение полинома ах2 + bx+с, причем задаваемые величины хранятся в стеке в следующем порядке: ( а b с х -- )
(Напоминаем, что операция возведения в степень должна выполняться первой.) ОПЕРАЦИЯ СТЕК ДАННЫХ СТЕК ВОЗВРАТОВ
а b с х >R a b с х SWAP ROT с b а х R@ с b а х х * с b ах х + с (ax+b) х R> * с x(ax+b) + x(ax+b)+c
Попытаемся вычислить его. Загрузите следующее определение: : ПОЛИНОМ ( a b c x -- n) >R SWAP ROT R@ * + R> * + ;
Теперь проверим его: 2 7 9 3 ПОЛИНОМ 48 ok