Мы завершаем рассмотрение текстового интерпретатора
Мы завершаем рассмотрение текстового интерпретатора и компилятора и в конце этого раздела, возможно, увидим их несколько в ином свете.
В процессе изложения мы неоднократно упоминали слово INTERPRET, имея в виду текстовый интерпретатор. Его строгое описание выглядит так:
INTERPRET | ( -- ) | Интерпретация текста из входного потока по указателю >IN до исчерпания входного потока. |
Несмотря на то что это слово первоначально предназначалось для использования самой Форт-системой, оно может применяться и в ваших программах. Предположим, вы написали цикл, а он выполняется не так, как вам нужно. Для отладки в этой ситуации пригодилось бы слово, которое останавливало бы выполнение программы на каждом шаге цикла и позволяло бы ввести ряд команд в диалоговом режиме, причем после нажатия клавиши RETURN выполнение цикла должно продолжаться. Подобное отладочное средство можно организовать с помощью INTERPRET.
Создадим следующее определение: : ТЕСТ 0 BEGIN DUP . 1+ QUERY INTERPRET 0 UNTIL ;
Введите слово ТЕСТ. Оно выведет нуль, остановится и будет ждать. Если вы нажмете клавишу RETURN, цикл продолжит свое выполнение, и на экране высветится единица. До нажатия клавиши RETURN вы можете ввести любую команду. Прежде чем продолжить выполнение цикла, INTERPRET ее выполнит. Если вы хотите завершить цикл, введите QUIT или сделайте ошибку, вызывающую ABORT. Любое из этих действий очистит стек возвратов и тем самым приведет к выходу как из INTERPRET, так и из ТЕСТ. (Это средство можно использовать гораздо шире [1].)
В разных диалектах Форта слово INTERPRET определено по-разному, но суть этого слова можно передать, изобразив алгоритм его выполнения с помощью D-схемы.
Алгоритм выполнения слова INTERPRET можно описать следующим образом. Начинаем цикл. В теле цикла выбираем очередное слово из входного потока и осуществляем поиск его определения в словаре. Если определение найдено, исполняем слово. Затем проверяем, не исчерпан ли стек.
(В том случае, когда стек исчерпан, завершаем цикл посредством EXIT и выдаем аварийное сообщение.) Если слово в словаре не найдено, пытаемся преобразовать введенный фрагмент в число и внести его значение в вершину стека.
Итак, вы познакомились с масштабированием, методами округления и аппроксимации вещественных чисел и операциями над числами с фиксированной точкой. Для того чтобы вы чувствовали себя увереннее при решении сложных математических задач, где необходимо следить за правильностью выбора масштаба в процессе решения посмотрите второй пример в гл. 12.
Как уже упоминалось, вам ничто не мешает дополнительно ввести в Форт операции над числами с плавающей точкой Но такие средства не очень подходят Форту, поскольку его достоинства - это компактность, высокая скорость выполнения программ, простота и элегантность. Он как бы «отторгает» от себя все то, что не является насущной необходимостью. Разумно используя масштабирование и числа двойной длины, вы избавитесь от дорогостоящих операций над числами с плавающей точкой.
Операции над числами с плавающей точкой имеет смысл применять в следующих случаях:
- если вы хотите использовать ваш компьютер как калькулятор для одноразовых вычислений;
- когда время программирования представляется более существенным фактором, нежели время выполнения вычислений в вашей программе;
- для обработки данных в большом динамическом диапазоне (превышающем диапазон от -2 биллионов до +2 биллионов).
Все перечисленные доводы являются серьезными. Однако существует целый ряд систем, где вы не должны платить за возможность выполнения операций над числами с плавающей точкой.
Ниже приводится список слов Форта, используемых в данной главе: 1+ ( n -- n+1 ) Добавление единицы.
1- ( n -- n-1 ) Вычитание единицы.
2+ ( n -- n+2 ) Добавление двойки.
2- ( n -- n-2 ) Вычитание двойки.
2* ( n -- n*2 ) Умножение на два (арифметический сдвиг влево).
2/ ( n -- n/2 ) Деление на два (арифметический сдвиг вправо).
ABS ( n -- |n| ) Помещение в стек абсолютной величины заданного числа.
NEGATE ( n -- -n ) Изменение знака на противоположный.
MIN ( n1 n2 -- min) Помещение в стек минимального из двух заданных чисел.
МАХ ( n1 n2 -- max) Помещение в стек максимального из двух
>R ( n -- ) Выборка значения из стека данных и занесение его в стек возвратов.
R> ( -- n ) Выборка значения из стека возвратов и занесение его в стек данных.
R@ ( -- n ) Копирование содержимого вершины стека возвратов без изменения его значения.
*/ ( nl n2 nЗ -- Умножение, затем деление (n1*n2/nЗ). результат ) Промежуточный результат 32-разрядный.
*/MOD ( n1 n2 nЗ -- Умножение, затем деление (n1*n2/nЗ). n-остаток n-результат) Помещение на стек остатка и частного. Для промежуточного результата используется слово двойной длины.