Полезная программа
Хотя из соображений удобства мы знакомим вас с языком Форт на примере арифметических операций, нужно подчеркнуть, что компьютеры приносят большую пользу не только в математике. Например, рукопись этой книги была подготовлена с помощью программы обработки текстов, написанной на языке Форт. Одно из наиболее полезных применений компьютера состоит в преобразовании огромного количества данных в такую форму, которая легче воспринимается человеком. В частности один из лучших способов -- представление данных в графической форме. Несмотря на то, что многие языки программирования (включая некоторые версии Форта) имеют множество сложных графических команд, одним из наиболее распространенных способов представления графических данных является "быстрый и грубый" график, построенный из прямых линий или столбиков. Возможно, вы привыкли к представлению столбиков в виде сплошных вертикальных прямоугольников, однако неплохо выглядят также столбики, построенные из рядом стоящих букв, которые печатаются по горизонтали. Например,
хххххххххх ххххххххххххх ХХХХХХХХХХХХХХХХ ххххххххххх ххххххх
представляет собой вполне наглядную гистограмму. Мы проследим весь процесс составления программы для построения подобной гистограммы, а затем рассмотрим ее с точки зрения структуры Форта, после чего вы сможете модифицировать программу в следующей серии упражнений. В самом начале определим слово
: TASK ;
TASK -- это слово, которое ровным счетом ничего не делает, кроме того, что помечает позицию в словаре. Но если ввести
FORGET TASK
то слово TASK будет удалено из словаря вместе со всеми теми словами, которые были определены после слова TASK. Поэтому, если вы сделали ошибку в программе и хотите.начать ее сначала, достаточно ввести
FORGET TASK
чтобы снова оказаться в том месте, с которого вы начали. Считается хорошей манерой начинать программу с подобного, не имеющего другого смысла слова, обычно для этого используется именно слово TASK.
Теперь нам нужно описать слово, которое будет печатать на экране строку литер "X" или "столбик".
Мы будем традиционно считать, что ширина экрана равна 64 позициям, таким образом, пределы длины столбика от 1 до 64. Прежде всего нам нужно узнать, как напечатать один символ "X". Самый простой способ -- это использовать слово ." . Вначале определим слово, которое должно печатать "X" один раз, т.е.
: .Х ." X" ;
(В данном случае точкой в названии .X мы отмечаем, что это слово должно что-то напечатать, это общепринятое соглашение на языке Форт). Теперь определим следующее слово:
: TEST 40 О DO .X LOOP ;
и, когда вы введете TEST , вы увидите на экране :
ХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХ Ok
т.е. 40 букв "X", после которых выведено подтверждение. Слова DO и LOOP, предписывают Форту повторить исполнение слов, находящихся между ними, причем число повторений определяется двумя числами, находящимися в стеке, когда встречается слово DO, в данном случае 40 раз. Зацикливание программы, или многократное исполнение набора инструкций, очень важная возможность языка Форт, как и других компьютерных языков.
Но слово TEST -- это еще не то, что нам нужно: оно печатает столбик из 40 литер "X", а нам необходимо печатать столбики различной длины, в зависимости от числа, находящегося на вершине стека. Чтобы сделать это, нужно просто вынести из определения число, задающее верхний предел цикла DO-LOOP, т.е. мы можем определить слово
: BAR 0 DO .X LOOP CR ;
Так как для слова DO необходимо иметь в стеке два числа, то для исполнения слова BAR (столбик) вам нужно задавать одно из них -- предел цикла. Если вы введете 23 BAR, то на экране увидите
ххххххххххххххххххххххх ok
Обратите внимание, что слово "ok" печатается на следующей строке. Это результат действия слова CR, которое производит перевод строки и возврат каретки. Без слова CR все наши столбики будут выстроены в ряд друг за другом, а не один под другим.
Теперь нам нужно напечатать несколько столбиков различной длины. Другими словами, мы хотим повторить программу BAR несколько раз.
Для этого нам потребуется еще один цикл DO. Определим слово
: TESTGRAPH CR 4 0 DO BAR LOOP ;
и теперь введем строчку
5 10 15 20 TESTGRAPH
Вы увидите гистограмму
хххххххххххххххххххх ххххххххххххххх хххххххххх ххххх
Конечно, данное определение будет исполняться только с четырьмя числами, поскольку в TESTGRAPH задано только четыре повторения цикла.
Мы уже почти пришли к нашей программе построения гистограммы, но в нее нужно ввести еще несколько усовершенствований. Во-первых, мы предполагали, что ширина экрана равна 64 позициям, поэтому число больше 64 недопустимо. Нам нужно как-то ограничить длину столбика. Во-вторых, Форт должен каким-либо образом определить, сколько чисел находится в стеке и, следовательно, сколько нужно построить столбиков. Поэтому число 4 в цикле 4 О DO в программе TESTGRAPH нам не нужно. Будем вводить усовершенствования в программу по одному. Во-первых, как можно ограничить длину столбика ? Вот программа, которая может выполнить это:
: LIMITBAR DUP 64 > IF DROP 64 THEN BAR ;
Рассмотрим, как она работает. Она делает копию числа, находящегося на вершине стека, выражение 64 > сравнивает это число с числом 64, и если оно больше 64, то в стек возвращается значение, которое оператор IF интерпретирует как истину. Если оператор IF встречает значение истина, то исполняется та часть программы, которая находится между словами IF и THEN, в данном случае DROP 64, т.е. убрать из стека число, которое там находится, и положить вместо него число 64. Если число в стеке меньше или равно 64, то выражение 64 > возвращает в стек значение ложь, которое оператор IF воспринимает как указание перейти на слово, следующее после THEN, в данном случае BAR. Если число больше 64, т.е. исполняются слова между IF и THEN, то затем процесс продолжается также после слова THEN, но слово BAR печатает 64 литеры "X", т.е. столбик, занимающий всю ширину экрана.
Этот пример требует некоторого осмысления, но главное, что мы хотели бы в нем подчеркнуть, -- это большая важность в языке Форт конструкции IF...THEN.
Она позволяет программе разветвляться, т.е. производить выбор одной из двух возможностей, как, например, в данном случае: печатать или не печатать столбик из 64 символов "X". Есть и другие способы разветвления программы, но данная конструкция является основной. Ветвление -- это важное свойство любого языка программирования, поскольку оно обеспечивает гибкость и удобство программирования задач любой сложности. Если вы знакомы с другими языками программирования, то, вероятно, обнаружите, что конструкция языка IF-THEN рассматривает слова DUP и BAR как подпрограммы. Подпрограммы (т.е. небольшие программы, находящиеся внутри больших программ) всегда определяются в Форте самостоятельными словами в том смысле, что Форт-программа построена из большого числа коротких подпрограмм.
Второе улучшение состоит в том, чтобы Форт сам определял, сколько чисел нужно отобразить на гистограмме. Это делается с помощью слова DEPTH (глубина), которое возвращает в стек количество чисел в стеке, и не разрушает стек. Например, если ввести
28943 DEPTH .
вы увидите
5 ok
на экране (а сами числа по-прежнему находятся в стеке). Вот теперь мы можем определить слово GRAPH, которое будет строить гистограмму чисел, находящихся в стеке:
: GRAPH CR DEPTH 0 DO LIMITBAR LOOP ;
Теперь посмотрим на всю программу, собранную вместе и с добавленными комментариями:
: TASK ; ( Слово, которое должно забываться при стирании программы) : .X ." X" ; ( Символ для печати) : BAR ( n -- ) 0 DO .X LOOP CR ; (Вывод столбика из X) : LIMITBAR ( n -- ) DUP 64 > IF DROP 64 THEN BAR ; ( Строит столбик из не более 64 символов ) ; GRAPH ( n1 n2 n3 . . . --) CR DEPTH 0 DO LIMITBAR LOOP ;
Чтобы запустить программу GRAPH, вы должны ввести несколько чисел и после этого -- слово GRAPH. Итак, считая, что вначале стек был пустым, после ввода
9 10 12 14 10 6 GRAPH
получаем гистограмму:
ххххххххх хххххххххх хххххххххххх хххххххххххххх хххххххххх хххххх
Несмотря на свою краткость, эта программа демонстрирует несколько важных свойств языка Форт.
Во-первых, хотя числа в Форте могут храниться в виде констант и переменных, как и в других языках программирования (см. ), чаще всего это не требуется. Обычно достаточно использования стека.
Во-вторых, Форт-программа состоит из последовательности определений слов через предшествующие им слова, так, например, для слова GRAPH используется определение слова LIMITBAR, которое основано на определении слова BAR, использующем определение слова .X , в свою очередь, включающее определение слова ." , а последнее является первичным словом любой версии языка Форт. Таким образом, для определения слов применяются ранее данные определения, основанные на первоначально определенных словах языка. В третьих, Форт-программы компактны. Текст программы на Бейсике или Фортране, предназначенной для решения этой задачи, будет намного длиннее. Форт-программы обладают большим быстродействием, хотя пока данное утверждение надо принять на веру. В четвертых, Форт-программа составлена из коротких слов или определений, каждое из которых может быть проверено и отлажено отдельно. Форт-программу сравнительно легко усовершенствовать и изменить без изменения большинства входящих в нее частей. Например, программа GRAPH может быть переделана для экрана, имеющего ширину 80 позиций, простой заме ной числа 64 на 80 в слове LIMITBAR. Наконец, Форт-программу, как правило, проще понять, чем любую другую, просмотрев определение последнего слова. Так, например, глядя на определение слова GRAPH, вы увидите, что нужно понять определение слова LIMITBAR, которое в свою очередь, приводит к слову BAR, а оно уже почти очевидно само по себе. Программы легко читаются (особенно если они снабжены продуманными комментариями и удачно выбраны имена слов), правда, не сверху вниз, как читаются программы на Бейсике, Фортране или Паскале. Форт-программу прочитывают, начиная с какого-либо важного слова, разбирая затем, для чего предназначено каждое слово, входящее в его определение.
В заключение следует сказать несколько слов о методике программирования на языке Форт.Прежде всего вы должны хорошо понять, что будет делать программа, а отсюда вы придете к словам, которые для нее необходимо определить. Например, для программы GRAPH, очевидно, необходимо слово BAR, а для него, в свою очередь, потребуется слово .X . Разработка Форт-программы продвигается одновременно на двух уровнях : на системном уровне, когда на основе понимания конечной цели определяются слова, которые нужно описать, и на уровне подпрограмм, иначе говоря, слов, когда описывается и проверяется каждое слово. Программирование на языке Форт -- это органический интуитивный и творческий процесс, который завершается, как правило, эффективными программами как на уровне большой системы, так и на уровне отдельных слов (подпрограмм).