Глава 3

КАК РАБОТАТЬ НА ФОРТЕ

До сих пор вы компилировали новые определения в словарь, набирая их на клавиатуре вашего терминала. Здесь же вам предлагается другой вариант создания определений — с использованием дисковой памяти и текстового редактора Форта.

Настоящая глава состоит из двух частей. В первой части обсуждаются вопросы применения дисковой памяти для хранения исходных текстов программ на Форте, а также правила оформления этих исходных текстов. Первая часть рассчитана на читателей с любым уровнем подготовки. Во второй части рассматривается конкретный текстовый редактор. Если текстовый редактор, с которым вы работаете, отличается от рассматриваемого, мы рекомендуем вам обратиться к документации по вашей Форт-системе.

Часть 1

ОБЩИЕ СВЕДЕНИЯ

ЕЩЕ РАЗ О СЛОВАРЕ

Поработав с настоящим компьютером, вы, возможно, сделали бы для себя кое-какие открытия, о которых еще не упоминалось.

Открытие первое: вы можете дать одному и тому же слову несколько определений, приписывая ему всякий раз новый смысл, но выполняться будет только последнее определение.

Например, если вы определили слово ВСТРЕЧА:

: ВСТРЕЧА . " Привет. Я говорию на форте. " ; _ок

то при его выполнении получите следующий результат:

ВСТРЕЧА привет. Я говорю на Форте. ок

Но если вы переопределите это слово:

: ВСТРЕЧА ." Алло, я слушаю вас! " ; ок

то при его выполнении сработает более позднее определение:

ВСТРЕЧА Алло, я слушаю вас. ок

Исчезло ли первое определение ВСТРЕЧА? Нет, оно сохранилось, но текстовый интерпретатор всегда начинает просмотр словаря с конца с элемента, занесенного в словарь последним. Из нескольких определений с одним и тем же именем интерпретатор передает слову EXECUTE первое встретившееся. Вы можете убедиться в том, что прежнее определение ВСТРЕЧА все еще находится в словаре. Для этого наберите на клавиатуре

    FORGET ВСТРЕЧА ок

и

    ВСТРЕЧИ Привет. Я говорю на Форте, ок

(Действует снова старое определение!) 

Слово FORGET (ЗАБЫТЬ) ищет указанное слово в словаре и удаляет из словаря (это его основная функция) само слово, а также все то, что вы успели определить после него. FORGET, как и интерпретатор, начинает свой поиск с конца: он удаляет только последний вариант определения данного слова (вместе со всеми словами, специфицированными после него). Поэтому теперь, если вы наберете на клавиатуре слово ВСТРЕЧА, интерпретатор найдет первоначальное слово ВСТРЕЧА. FORGET — очень полезное слово. Оно помогает вам очищать ваш словарь во избежание его переполнения. (Словарь занимает память, а мы должны ее экономить.)

Открытие второе: если вы вводите определение с помощью клавиатуры (как вы сейчас это делаете), то исходный текст1 его не сохраняется.

1 Для начинающих. Исходным текстом называется текстовый вариант определения, например:

: ПЛЮС-ЧЕТЫРЕ ( n — n+4) 4 + ;

Этот первоначальный, исходный, вариант преобразуется в словарную форму и становится элементом словаря.

В словаре запоминается только скомпилированная форма вашего определения. А как быть, если вы захотите внести изменение в уже определенное слово? Вы должны повторно набрать полностью все определение, внеся в него соответствующие изменения. Это может показаться вам достаточно утомительным, не так ли? И даже хуже:

Открытие третье: если вы выключите компьютер, а затем снова включите его, то все набранные вами определения исчезнут.

Очевидно, что необходим какой-то способ запоминания исходного текста с тем, чтобы его можно было изменять и перекомпилировать в любое время. Здесь-то и приходит вам на помощь редактор. Он позволяет запомнить ваш исходный текст на диске. Поэтому давайте выясним, что представляет собой диск и как Форт-система работает с ним.

ИСПОЛЬЗОВАНИЕ ДИСКОВОЙ ПАМЯТИ

Почти все Форт-системы используют дисковую память. Чтобы понять, что такое дисковая память, ее можно сравнить с оперативной памятью (ЗУПВ — запоминающее устройство с произвольной выборкой). Они различаются между собой примерно так же, как стационарная картотека (шкаф) и вращающаяся. До сих пор вы имели дело с памятью компьютера, которая подобна вращающейся картотеке. Компьютер может получить доступ к этой памяти почти мгновенно, поэтому программы, хранимые в ОЗУ, выполняются очень быстро. К сожалению, объем такой памяти ограничен и ее использование обходится относительно дорого. Кроме того, при выключении компьютера содержимое памяти теряется. 

С другой стороны, диск называют устройством с большим объемом памяти, так как аналогично шкафу с картотекой он может хранить значительный объем информации при меньших затратах на единицу данных, чем оперативная память компьютера. Как и магнитная лента, диск сохраняет информацию при отключении питания.

Когда вы определяете некоторое слово, компилятор помещает определение этого слова в ЗУПВ, чтобы доступ к нему осуществлялся достаточно быстро. Постоянным же местом хранения исходного текста данного определения является диск. Вы можете средствами Форта записать ваш исходный текст на диске, а впоследствии считывать его с диска и передавать для обработки текстовому интерпретатору1.

Дисковая память Форт-системы подразделяется на так называемые блоки. Храниться на диске в виде блоков может любая информация. Существует соглашение, по которому блоки, содержащие исходный текст, вмещают 1024 символа и состоят из 16 строк по 64 символа каждая, что согласуется с размерами экрана вашего компьютера. (В некоторых случаях для обозначения блока с исходным текстом применяется термин экран. Для простоты мы будем пользоваться только термином блок.}

Блок с исходным текстом выглядит следующим образом:

Block 50
 0 ( Большая буква "F" )
 1 : STAR 42 EMIT ;
 2 : STARS ( Количество ) 0 DO STAR LOOP ;
 3 : MARGIN CR 30 SPACES ;
 4 : BLIP MARGIN STAR ;
 5 : BAR MARGIN 5 STARS ;
 6 : F BAR BLIP BAR BLIP BLIP CR ;
 7
 8
 9 F
10
11
12
13
14
15

Верхняя строка (Block 50) и числа слева от текста на диске отсутствуют. Они выводятся словом LIST, чтобы вам было легче ориентироваться. Для того чтобы вывести требуемой блок, наберите номер этого блока и слово LIST (РАСПЕЧАТАТЬ), например:

50 LIST

1 Для начинающих. Диск иногда используют для хранения самой Форт-системы. Когда вы активируете, или загружаете, Форт, это, как правило, означает его копирование из некоторого участка дисковой памяти в ЗУПВ, где он представляется в виде словаря. (В других системах Форт хранится в постоянной памяти, предназначенной только для чтения из нее (ПЗУ). Здесь он становится доступным сразу после включения питания.)

Как ввести.в блок исходный текст? Для этого существует редактор. Поскольку каждая Форт-система снабжена собственным редактором, за разъяснениями обращайтесь к документации по вашей системе. (Один из таких редакторов описан во второй части настоящей главы.)

Для простоты предположим, что блок 50 содержит определения, рассмотренные выше. Почти все они вам знакомы: это определения, которые вы использовали для вывода на дисплей большой буквы F. Теперь, имея данные определения в блоке, как передать блок 50 текстовому интерпретатору? С помощью выражения

50 LOAD

Слово LOAD (ЗАГРУЗИТЬ) передает указанный блок текстовому интерпретатору, что приводит к компиляции всех находящихся в блоке определений.

После загрузки определений вы можете набрать новое слово F и получить ожидаемый результат. Но заметьте, что мы уже поместили наше новое слово в строку 9 для того, чтобы показать, что при загрузке блока выполняется его содержимое. При загрузке именно этого блока не только производится компиляция определений, составляющих слово F, но и само слово F будет выполнено и вы увидите букву F на вашем экране.

Как уже отмечалось, текстовый интерпретатор сканирует входной поток. Ранее мы считали, что входным потоком является строка, вводимая с клавиатуры. Теперь вам известно, что можно переключать источник входного потока. Как правило, входной поток поступает с клавиатуры дисплея; когда же вы применяете слово LOAD, входной поток поступает с диска.

Итак, у входного потока два источника: непосредственно клавиатура или диск.

 

В гл. 10 мы более подробно обсудим использование Форт-системой дисковой памяти. Но прежде чем вы приступите к редактированию исходного текста, введем еще одну команду. Слово FLUSH (ВЫБРОС) гарантирует, что все изменения, которые вы пытались внести в некоторый блок, действительно были записаны на диск.

Когда вы редактируете конкретный блок, любое вносимое вами исправление не поступает на диск немедленно. На самом деле вы работаете с некоторой копией этого блока, расположенного в каком-то участке ЗУПВ. В конечном итоге по завершении ваших исправлений Форт-система возвратит откорректированную копию блока на диск. Но представьте себе, что вы отключили компьютер до того, как тот вернул копию блока на диск. Или, предположим, вы сменили диски. Кроме того, в результате допущенной вами программной ошибки вы могли до переноса Фортом ваших исправлений на диск просто испортить систему.

По крайней мере до тех пор, пока вы не прочитаете гл. 10, прежде чем снять диск, отключить питание или предпринять что-нибудь опасное, обязательно введите слово FLUSH1.

Ниже приводится перечень команд, введенных в данном разделе.

FORSET имя ( -- )   С помощью этого слова мы забываем ( удаляем 
                    из словаря ) указанное слово и все слова, 
                    внесенные в словарь после него.
LIST       ( n -- ) Вывод на экран дискового блока.
LOAD       ( n -- ) Загрузка дискового блока ( компиляция или выполнение ).
                    Блок 0 обычно загружен быть не может.
FLUSH      ( -- )   Запись всех обновленных дисковых буферов на диск,
                    после чего освобождение этих буферов.

ПРАВИЛА ЗАПИСИ ФОРТ-ПРОГРАММ

Вернемся к нашему учебному блоку из предыдущего раздела. Хороший стиль программирования на Форте требует отводить строку 0 любого блока под комментарий — краткое описание функционального назначения определений, содержащихся в данном блоке, В комментарий часто включают дату внесения последнего изменения и инициалы программиста.

1 Относительно Форта, функционирующего под управлением других операционных систем. Многие Форт-системы работают под управлением других операционных систем, например, СР/М или MS-DOS. В них блоки Форта представляют собой участки размером в 1К в специально зарезервированном для этих целик файле (или файлах). Как открывать и закрывать такие файлы, объясняется в документации по вашей системе.

Мы использовали в приведенном выше примере для выделения комментария круглые скобки. В некоторых системах имеется слово \ (пропуск строки), которое предписывает интерпретатору пропустить остаток строки (все что находится справа от этого слова). По аналогии со словом ( слово \ начинает комментарий, но в отличие от него не требует ограничителя. Вы можете помещать \ в середину любой строки: ее содержимое слева от этого слова будет обработано интерпретатором, справа нет.

Похожее слово \S (пропуск экрана) предписывает интерпретатору игнорировать дальнейший текст в данном блоке. В отдельных Форт-системах для таких целей применяется слово EXIT.

Ниже приводятся еще несколько правил, позволяющих сделать текст в блоке удобочитаемым.

  1. Отделяйте комментарий с обеих сторон двумя пробелами. Если стековый комментарий отсутствует, отделяйте имя определения от содержательной части тремя пробелами.
  2. Разбивайте определения на фрагменты, разделяемые двумя пробелами.
  3. Если определение занимает более одной строки, делайте отступ во всех строках, кроме первой.
  4. Не помещайте на одной строке более одного определения.
  5. Определения должны быть краткими! В среднем определение должно занимать две строки.

В книге автора «Думаем на Форте» [1] хорошему стилю программирования на Форте посвящена целая глава.

Итак, запомните две команды, введенные в этом разделе:

\    ( — ) Пропуск оставшегося текста данной строки. 
\S   ( — ) Пропуск оставшегося текста экрана.

ОСОБЕННОСТИ ПРОГРАММИРОВАНИЯ НА ФОРТЕ

Программист пишет программу на Форте обычно в несколько этапов:

  1. С помощью редактора Форта он делает доступным некоторый блок.
  2. Набирает определение.
  3. Завершает работу с редактором (при необходимости).
  4. Загружает данный блок.
  5. Проверяет новое слово.
  6. Если слово выполняется неправильно, то программист забывает это определение посредством FORGET, редактирует его и повторно загружает. Если же слово выполняется правильно, программист возвращается к п. 1 и принимается за следующее определение.

Основной причиной, по которой программирование на Форте происходит быстрее, чем на других языках, является быстрая оборачиваемость цикла «кодирование—загрузка—тестирование». Загрузка блока занимает менее секунды.

Поэтому программирование на Форте требует несколько иной стратегии, чем на большинстве известных языков программирования, например Си. После того как вы представили себе программу в целом и решили, что будет выполнять каждое слово в отдельности, можете приступать к кодированию. У вас есть возможность проверять ваши определения по мере написания и модифицировать их с целью удаления ошибок, дальнейшего совершенствования и наведения «глянца». Таким образом, все последующие слова создаются на проверенном фундаменте и вы управляете программой с самого начала ее создания. (В книге автора «Думаем на Форте» такой подход называется итеративной разработкой.)

ЗАГРУЗКА ПРОГРАММ

Как вы уже знаете, процесс кодирования может потребовать неоднократной повторной загрузки одного и того же блока или блоков. Но учтите: всякий раз, производя загрузку определений, вы увеличиваете размеры вашего словаря.

Допустим, вы загружаете несколько раз некоторый блок, изменяя в нем по одному определению. В результате ваш словарь будет содержать по варианту каждого слова данного блока для каждой загрузки. Простейший способ избежать этого состоит в применении слова FORGET. Например, если вы только что внесли исправления в определение слова F в блоке 50 и хотите вновь загрузить последний, то вы должны набрать на клавиатуре следующее: 

FORGET STAR ok
50 LOAD ok

Помните, что слово FORGET забывает само указанное слово и все, что было определено после него.

Возможна ситуация, когда из нескольких существующих вариантов одной и той же программы в конкретный момент времени требуется компилировать только один из них. Предположим, вы должны написать программу обработки слов. После создания основы программы вы хотите присоединить к ней фрагменты, по-

зволяющие использовать эту программу в одном случае для обработки корреспонденции, в другом — для работы с журнальными статьями, а в третьем —для обработки адресных наклеек.

 

В Форте три перечисленных варианта фрагментов называются оверлейными структурами, так как они при исполнении не пересекаются и взаимозаменяемы в памяти. Рассмотрим их более подробно.

Последнее определение основы программы должно содержать только имя, например:

: VARIATIONS ;

Это определение называется нулевым, поскольку оно всего лишь отмечает место в вашем словаре. Включите в начало каждого альтернативного фрагмента выражение

FORGET VARIATIONS : VARIATIONS ;

С помощью FORGET каждый раз при загрузке любого из альтернативных фрагментов система забывает все определения начиная с конца словаря до нашего нулевого определения и вновь компилирует нулевое определение, а затем определения, относящиеся к данному фрагменту. Загружая другой фрагмент, вы тем самым замещаете первый оверлейный сегмент вторым2.

1 Для специалистов. Более точно — оверлейными структурами компиляции. Некоторые Форт-системы предлагают возможность загрузки так называемых двоичных оверлейных структур, представляющих собой предварительно скомпилированные программные разделы, которые могут быть присоединены к резидентной части словаря.

2 Для работающих с системами, в которых есть слово EMPTY. Слово EMPTY «забывает» все созданные вами определения. В мультипрограммной системе они составляют лишь ваше собственное расширение словаря.

Мы ввели команду LOAD для загрузки одного блока, а как загружать программу, состоящую из нескольких блоков? Используйте слово THRU, которое загружает заданный диапазон блоков. Например, выражение

180 189 THRU

означает загрузку каждого блока, начиная со 180-го и кончая 189-м. Многие системы при выполнении слова THRU выводят номера загружаемых блоков, что помогает вам следить за ходом загрузки.

Существует еще один пример. Вам известно, что слово .", помещенное в определение, приводит к выводу некоторого сообщения при выполнении данного определения. Другое слово .( можно использовать за пределами определения. Наберите на клавиатуре

.( Что со мной, доктор?)

и нажмите клавишу RETURN. Вы увидите, что набранный текст высветится на экране. Это слово применяется в тех случаях, когда требуется сообщение от некоторого блока во время его загрузки. Например:

Block# 10
0 \ Моя программа
1
2 CR .( Загрузка моей программы...)
3 20 37 THRU \ ШТУЧКИ
4 40 45 THRU \ ДРЮЧКИ
5 50 58 THRU \ ШПУЛЬКИ
6
7 CR .( Моя программа загружена )
8
9

ИНСТРУМЕНТАЛЬНЫЕ СРЕДСТВА РАБОТЫ С БЛОКАМИ

Мы знаем, что слово LIST инициирует печать только одного блока. Введем несколько слов, имеющихся в большинстве Форт-систем, для вывода группы блоков и для доступа к блокам.

Слово TRIAD выводит группу из трех смежных блоков, начиная с блока, номер которого делится на три без остатка. Например,  выражение

30 TRIAD

обеспечит вывод блоков с номерами 30, 31 и 32. (Обращение к TRIAD с аргументами 31 и 32 приведет к выдаче той же самой триады блоков.)

Слово SHOW выводит группу блоков со смежными номерами. Например, выражение

30 38 SHOW

приведет к выводу трех триад блоков, начинающихся с номеров 30, 33 и 36 соответственно.

Эти слова применяются для вывода листингов прикладных программ на печатающее устройство. Каким образом осуществляется вывод? К сожалению, все Форт-системы реализуют его по-разному. Перед работой вы должны ознакомиться с документацией по своей системе. Можем предложить в качестве типовых примеров следующие выражения: 

В результате вывод назначается на печатающее устройство, блок распечатывается, после чего вывод снова назначается на дисплей. Вы можете промоделировать синтаксис, принятый в мультизадачной системе, следующим образом:

: PRINT PRINTER INTERPRET CONSOLE ;

В ряде систем слово SHOW автоматически назначает вывод на печатающее устройство, а после завершения вывода возвращает назначение на дисплей.

Еще одним важным словом является INDEX (КАТАЛОГ), которое распечатывает в блоках из заданного диапазона только строки комментария (нулевые). Например, выражение

30 38 INDEX

инициирует вывод комментария, содержащегося в блоках с 30-го по 38-й включительно.

Ниже приводится список рассмотренных нами команд.

Если вы еще не знакомы с редактором Форта, то, пожалуй, настало время с ним познакомиться. Возможно, что редактор, имеющийся в вашей системе, отличается от описываемого далее. В этом случае пропустите оставшуюся часть главы и изучите его по документации к своей системе.

THRU      ( нач кон — ) Загрузка всех блоков с номерами из диапазона от нач до кон
.( текст) ( — )         Вывод текста сообщения, ограниченного правой круглой скобкой. 
                        Используется, как правило, за пределами определения через двоеточие.
TRIAD     ( n — )       Вывод трех блоков с номерами, включающими n,
                        начиная с номера, делящегося без остатка на 3.
SHOW      ( нач кон — ) Вывод блоков с номерами из диапазона от
                        нач до кон по три блока.
INDEX     ( нам кон — ) Вывод комментария только для блоков, 
                        номера которых входят в диапазон от нач до кон.

Часть 2

ТЕКСТОВЫЙ РЕДАКТОР ФОРТА

Здесь мы рассмотрим вариант текстового редактора, имеющегося в ряде Форт-систем. Этот вариант ориентирован в большей степени на управление с помощью команд (командный редактор), нежели на управление посредством курсора (экранный редактор). Редактор второго вида проще. Он отличается от первого способом доступа к модифицируемому тексту. Вы «входите» в редактор неким присущим только данной системе способом и вносите исправления в текст, перемещая курсор по экрану нажатием функциональных клавиш (или с помощью устройства типа «мышь», если оно имеется).

В командном редакторе текст редактируемого блока остается неизменным в верхней части экрана. Команды редактирования текста вы вводите в оставшемся пространстве экрана. Для редактирования текста в Форте предусмотрен набор специальных слов. Несколько команд из такого набора позволяют подводить курсор либо к строке с заданным номером, либо, с помощью некоторого шаблона, к строке с заданным текстом. Редактор по конкретной команде находит место в тексте, предназначенное для внесения исправлений, как правило, быстрее программиста, который должен нажимать клавиши манипулирования курсором и следить на экране за положением курсора. Другие команды позволяют вставлять или удалять строки с сохранением образцов для многократных вставок/удалений. При этом лучше всего оставаться «в Форте». Вы можете осуществить перевод из шестнадцатеричной системы в десятичную или же загрузить блок, который только что отредактировали, не выходя из Форт-системы, что особенно важно для среды, в которой разрабатываются программы. Кроме того, командные редакторы легко расширяемы.

По мнению автора, рассматриваемый ниже редактор удобен, практичен, гибок и ориентирован на Форт в большей степени, чем экранный редактор.

(Следует заметить, что некоторые ранние Форт-системы снабжены так называемым построчным редактором. Вместо того чтобы работать полным экраном, они высвечивают только модифицируемую строку. Поскольку теперь программисты применяют дисплеи, а не телетайпы, построчные редакторы устарели. Тем не менее последние относятся к редакторам командного типа и используют команды, аналогичные описанным в настоящей главе. Поэтому все изложенное здесь в принципе применимо и к ним.)

ПРОГРАММА-РЕДАКТОР

Для начала найдите пустой блок (если нужно, используйте INDEX) и распечатайте его следующим образом:

180 LIST

При распечатке пустого блока вы увидите слева на экране 16 строк (015), пронумерованных сверху вниз, без какой-либо информации. Приглашение ok в последней строке означает, что текстовый интерпретатор выполнил вашу команду на распечатку данного блока.

Распечатывая блок, вы тем самым выбираете его для дальнейшей работы:

 

Сделав какой-то блок «текущим», вы можете распечатывать его, просто набирая слово

   L

В отличие от LIST для L не нужно указывать номер блока, так как это слово распечатывает текущий блок.

Подготовив блок с помощью LIST к редактированию, неплохо было бы выполнить команду WIPE (СТЕРЕТЬ). Иногда никем не используемый блок, на первый взгляд пустой, содержит разного

рода символы, что может воспрепятствовать его загрузке, Слово WIPE заполняет текущий блок пробелами, после чего тот становится действительно пустым. 

Поскольку у нас есть текущий блок, выберем и текущую строку с помощью слова Т. Предположим, вы должны записать какую-то информацию в строку 31. Наберите на клавиатуре

 

Слово Т выделяет выбранную строку, заменяя ее изображение на негативное. Теперь, после того, как вы зафиксировали место, куда будете вносить исправления, можно в текущую строку занести некоторый текст с помощью команды Р (PUT ВСТАВИТЬ):

    Р МЫ НАХОДИМСЯ ЗДЕСЬ<return>

Рвставляет текст, следующий за этой командой (вплоть до символа возврата каретки), в текущую строку.

 

1 Для любознательных. На самом деле в качестве указателя выступает не номер строки, а позиция курсора. Более подробно это будет показано в следующих сносках.

Помните, что текущая позиция, установленная вами, остается прежней, так что если вы сейчас наберете

   Р А ТЕПЕРЬ МЫ ЗДECb<return>

то увидите, что в строке 3 прежний текст заменен на более поздний. Аналогично если вы введете Р, а затем по меньшей мере два пробела (один — чтобы отделить Р от текста, а другой — в качестве вводимого текста), то на месте прежней строки будет строка из одних пробелов. Другими словами, в этом случае очищается строка. В данной главе символ b означает пробел, так что для заполнения строки пробелами нужно набрать на клавиатуре

   Pbb<return>

КОМАНДЫ СИМВОЛЬНОГО РЕДАКТИРОВАНИЯ

Здесь мы рассмотрим, как вставлять и удалять текст в пределах строки.

F

Прежде чем вставлять или удалять текст, вы должны суметь подвести курсор редактора (не путать с курсором Форта) к месту вставки или удаления. Наш редактор обозначает позицию курсора тем, что дает следующий за ним текст до конца строки в негативном изображении. Предположим, что текущее содержимое строки 3 таково: 

и вам нужно вставить недостающую букву М в слово ПАМЯТЬ. Курсор находится в начале строки. Для того чтобы переместить его за ПА, введите команду F (FIND — НАЙТИ) с фрагментом ПА:

   F ПA<return>

Слово F будет просматривать текст, начиная с текущей позиции курсора, до тех пор, пока не найдет заданный фрагмент (в нашем случае ПА), после чего переместит курсор за найденный фрагмент.

 

I

Так как курсор подведен к требуемому месту, достаточно ввести- 

и I вставит (INSERT —ВСТАВИТЬ) символ М за курсором.

   ЧЕМ ЛУЧШЕ КОМПЬЮТЕР, ТЕМ БОЛЬШЕ ПАМЯТЬ

Е

Чтобы удалить фрагмент с помощью команды Е (ERASE — СТЕРЕТЬ), вы должны его сначала найти, послав команду F. Например, если вы хотите удалить слово ЛУЧШЕ, в первую очередь восстановите положение курсора:

   

после чего введите

     

   

и далее

   

Слово Е удалит фрагмент, который вы только что задали в команде F:

 

После этого Е выведет исправленную строку:

 Курсор указывает место, куда вы можете вставить другое слово:

 

D

По команде D (DELETE — УДАЛИТЬ) находится и удаляется заданный фрагмент. В ней фактически сочетаются две команды:

F и Е. Например, если ваш курсор находится в таком положении:

 

то вы можете удалить слово КОМПЬЮТЕР, набрав 

Однако вы снова можете вставить фрагмент текста в то место строки, на которое указывает сейчас курсор:

 

Применение команды D чревато ошибками более, чем последовательности команд F и D, так как при двухшаговом способе вы сначала четко указываете, что нужно удалить, а затем удаляете.

R

По команде R (REPLACE — ЗАМЕНИТЬ) заменяется фрагмент текста, который вы только что нашли. Эта команда объединяет в себе команды Е и I. Например, если курсор показывает на фрагмент

 

и вы ввели

    F У НУЖЕН<return>
    R CAM<return>

то получите следующее:

Команду R нужно применять в тех случаях, когда требуется сделать вставку перед определенным фрагментом текста. Например, если вы в нулевой строке пропустили символ E:

 

то не так просто с помощью F найти для этой буквы место. Вы должны провести курсор через множество пробелов к требуемому (перед MPTY). В данной ситуации лучше воспользоваться таким приемом:

    F MPTY<return>

затем

   R EMPTY<return>

TILL (ДО)

Самой мощной командой удаления является TILL. Она удаляет все, начиная с текущего положения курсора до указанного фрагмента включительно. Например, после применения к строке

 

(заметьте, где находится курсор) команды TILL

   TILL HA<return>

останется лишь текст:

Эта фраза звучит приятнее, не правда ли? С помощью TILL осуществляется поиск в пределах текущей строки, а не по всей оставшейся части блока.

БУФЕР ПОИСКА И БУФЕР ВСТАВОК

Для того чтобы использовать редактор эффективно, вы должны разобраться в том, как работают его буферы поиска и вставок. Вы можете и не знать, что когда вы набираете на клавиатуре

   F KOМПЬЮTEP<return>

то по команде F фрагмент КОМПЬЮТЕР прежде всего помещается в так называемый буфер поиска. С точки зрения компьютерной терминологий буфер — это участок памяти для временного размещения данных. Буфер поиска находится в оперативной памяти компьютера (ОЗУ).

 

Команда F инициирует поиск такого фрагмента в строке, который соответствует содержимому буфера поиска.

Теперь вам понятно, что происходит, когда вы используете команду F следующим образом:

   F<return>

т. е. в том случае, когда за F непосредственно следует символ возврата каретки. В строке осуществляется поиск такого фрагмента, который уже находится в буфере поиска как результат последнего выполнения команды F 

Это позволяет находить многочисленные «вхождения» одного и того же фрагмента текста без его повторного набора. Например, предположим, что в строке 8 содержится следующее утверждение:

 

Курсор указывает начало строки, и вы хотите удалить последний союз И. Введите следующую фразу:

 

Теперь фрагмент И находится в буфере поиска и вы можете просто несколько раз подряд набрать команду F:

   F<return>
    F<return>

и т. д. до тех пор, пока не доберетесь до того вхождения И, которое вам нужно и вы можете его удалить с помощью команды Е. (По команде Е подсчитывается число символов, находящихся в буфере поисками удаляется такое же число символов, предшествующих курсору.) Между прочим если вы попытались ввести команду F еще раз, то вы бы получили следующий ответ:

   F И none

что означает: «В данной строке вхождений И нет». Иными, словами, команда F не нашла в строке фрагмента, соответствующего содержимому буфера поиска и поэтому возвратила вам слово И с сообщением об ошибке NONE.

Как уже отмечалось выше, команда D сочетает в себе две команды F и Е, поэтому она также использует буфер поиска. Поместив курсор в начало строки

 

и фрагмент И в буфер поиска, вы можете удалить все вхождения И, введя несколько раз команду D:

 

Буфер вставок используется командой I. Для того чтобы вставить содержимое этого буфера в то место, куда указывает курсор, достаточно просто набрать на клавиатуре

   I<return>

Рассмотрим пример, в котором показано, как можно одновременно применять буфер поиска и буфер вставок. Предположим, в какой-то строке содержится следующая информация:

   Я ЖИВУ, Я ЛЮБЛЮ, Я СТРАДАЮ

Теперь подведем курсор

 

и осуществим вставку 

1 Для любознательных. Редактору достаточно хранить только позицию курсора, а не указатель текущей строки. Так как в строке помещается 64 символа, редактор с помощью слова /MOD всегда сможет вычислить положение курсора, скажем, для 16-го символа в строке 3:

208 64 /MOD . . 3 16 ok

В результате получим

 

Наберите на клавиатуре 

КОМАНДЫ РЕДАКТИРОВАНИЯ СТРОК

Итак, вы уже знаете способы изменения символов и слов и можете приступить к корректированию целых строк. Р

Слово Р, которое мы уже ввели ранее, использует тот же буфер вставок, что и команда I. Предположим, что в вашем буфере вставок все еще находится фрагмент ВНОВЬ из предыдущего примера, а строка 14 все еще является текущей. Наберите на клавиатуре следующий текст:

    P<return>

В результате прежнее содержимое строки 14 заменяется содержимым буфера вставок и в ней теперь находится только одно слово ВНОВЬ.

Чтобы получить представление об этой команде, посмотрите три примера ее применения:

1. Р ВЕСЬ ЭТОТ TEKCT<return>
2. Pbb<return>
3. P<return>

В первом примере указанная строка помещается в буфер вставок, а затем в текущую строку, во втором заполняется пробелами буфер вставок, а затем и текущая строка, и, наконец, в третьем содержимое буфера вставок вносится в текущую строку.

U

Подобную функцию выполняет и слово U, Оно помещает содержимое буфера вставок ниже текущей строки. К примеру, допустим, что ваш блок имеет вид: 

Если вы передвинете курсор ко второй строке:

   2 Т

а затем наберете

   U KAPЛИH<return> ok
    U KУПEP<return> ok

то пoлучитe следующее:

 

Вместо того чтобы заменить текущую строку, команда U «втискивает» содержимое буфера вставок между текущей и последующими строками, передвигая их ближе к концу. Если бы в строке 15 находилась какая-то информация, она была бы вытеснена за пределы экрана и потеряна. Когда вы добавляете последовательность строк, проще иметь дело с командой U, а не Р, например:

   1 Т P AДAMC<rеturn> ok
    U БPAУH<return> ok
    U KЬЮДАХИ<return> ok
    U ДЭВИС<return> ok

Перечисленные выше три способа использования команды Р применимы также и к команде U.

X

Команда X по своему действию противоположна команде U. Она извлекает текущую строку. Если в рассмотренном выше примере мы сделаем строку 3 текущей (с помощью предложения 3 Т), а затем введем

   X<return>

то строка 3 будет удалена, а нижние строки передвинутся вверх:

Как видите, по команде \ извлеченная строка тоже помещается в буфер вставок. Это облегчает ее перемещение в дальнейшем. Например, последовательно вводя два предложения

   9 T<return>

и

   P<return>

вы можете поместить КАРЛИН в строку 9.

Для того чтобы вставить новую нулевую строку, а прежнюю нулевую строку опустить ниже, нужно сначала поместить эту новую строку под нулевой:

   0 T U ЭТО НОВАЯ НУЛЕВАЯ СТРОКА.<return>

а затем первые две строки поменять местами:

   0 Т X U<return>

КОМБИНИРОВАННЫЕ КОМАНДЫ РЕДАКТИРОВАНИЯ

N и В

Вводя слово N, вы тем самым добавляете единицу к номеру текущего блока. Таким образом, очередная набранная комбинация символов

   N L

вызовет печать следующего блока. Аналогично слово В 

уменьшит на единицу номер текущего блока. Иными словами, комбинация

   В L

позволяет вам вывести на печать предыдущий блок.

В некоторых системах N объединена с командой L, так что, применяя N, мы переходим к следующему блоку и выводим его содержимое. Вы можете при необходимости переопределить команды N и В с тем, чтобы они выполнялись так же — Форт допускает переопределение команд применительно к вашим потребностям.

COPY

Слово COPY позволяет копировать содержимое одного блока в другой. При этом вытесняются любые данные, находившиеся в приемном блоке до копирования. Эта команда имеет следующий формат:

   откуда куда COPY

Если, к примеру, вы введете

   153 200 COPY

то информация, находящаяся в блоке 153, будет скопирована в блок 200. Пусть у вас войдет в привычку вводить FLUSH после каждого выполнения COPY.

S

Команда S представляет собой расширенную версию команды F. Она дает возможность осуществлять поиск указанного текста в пределах текущего блока, а затем и в пределах последующих блоков вплоть до того блока, который вы указали в команде. Например, если текущим является блок 180 и вы ввели предложение

   185 S СОКРОВИЩА

то S инициирует поиск «сокровища» в блоках начиная с 180-го и заканчивая 184-м. Если искомый фрагмент обнаруживается, то на экран выводится блок, содержащий данный фрагмент, а курсор устанавливается в его начале.

Слово S оставляет в стеке номер блока, на котором закончился поиск, так что если вам требуется продолжить поиск того же самого фрагмента, просто введите команду S.

G и BRING (ПЕРЕНОС)

Слово G берет одну строку из другого блока и вставляет ее перед текущей строкой (перемещая вни? текущую и все последующие строки).

Пусть курсор указывает на строку 3 следующего блока:

1
2 Куда ж ты, милая
3 , девалась? И где искать тебя теперь?

Пропущенный текст находится в строке 10 блока 38. Наберите на клавиатуре

   38 10 8<return>

и вы получите следующее:

1
2 Куда ж ты, милая
3 пропущенная строка
4 , девалась? И где искать тебя теперь?

Слово BRING перемещает сразу группу строк. Выражение

   3 S 10 14 BRING

переместит из блока 38 строки 10—14.

М

Некоторые разработчики Форта вместо команд G и BRING используют команду М, которая инициирует действия, противоположные вызываемым командой G. Она перемещает текущую строку в заданную строку экрана.

  190 2 M<return>

Слово К меняет местами содержимое буферов поиска и вставок. Это полезно в тех ситуациях, когда вы случайно командой D удалили нужный вам текст. Так как удаленный текст находится в буфере поиска, вам достаточно ввести команду К, которая переместит его в буфер вставок, а затем команду I.

Можно выполнить и обратное действие. Если вы ошибочно вставили некоторый фрагмент не на свое место, переместите его посредством К в буфер поиска, а затем удалите с помощью Е.

Попытайтесь самостоятельно поменять местами два слова в одной и той же строке, используя слово К.

В ряде систем вместо того, чтобы нажимать клавишу RETURN, вы можете с помощью символа возврата каретки обозначать конец фрагмента текста и таким образом в одной строке вводить более одной команды. Например, вы можете ввести

    D ФРУКТЫ^  I ОРЕХИ<return>

Весь текст разместился в одной строке, а результат вы получите такой же, как если бы вы набрали на клавиатуре следующее:

   D ФРУКТЫ<return>

И

   I ОРЕХИ<return>

Итак, мы рассмотрели команды редактора. Поскольку Форт по своей природе — язык гибкий, а пользователи при необходимости могут определять собственные команды редактирования, набор команд редактора в вашей системе может отличаться от набора, описываемого в настоящей книге. В конце раздела приводятся все команды, о которых здесь шла речь.

В заключение следует отметить, что редактор применительно к Форту это не программа, как, возможно, принято в других языках, а, скорее, набор слов. Его часто называют словарем, но к вопросу о словарях мы вернемся позднее.

Определение местоположения исходного текста (полезный прием).

В некоторых Форт-системах имеется слово LOCATE (ОПРЕДЕЛИТЬ-МЕСТОПОЛОЖЕНИЕ) или VIEW. Если вы введете следующее предложение:

   LOCATE РАЗМЕР-ЯИЦ

то получите распечатку текста блока, содержащего определение РАЗМЕР-ЯИЦ. При этом указанное слово должно быть загруженным, т. е. находиться в словаре з данный момент. (В отдельных системах вы можете находить местоположение выборочных системных определений и слов вашей прикладной программы, но вы не имеете права определять местоположение слов из предварительно скомпилированного участка.)

Ниже следует перечень слов Форта, приведенных в настоящей главе:
FORGET имя ( -- ) С помощью этого слова мы забываем ( удаляем иа словаря ) указанное слово и все слова, внесенные в словарь после него.
LIST     ( n -- )

Вывод на экран дискового блока.

LOAD     ( n -- ) Загрузка дискового блока ( компиляция или выполнение ) . Блок 0 обычно загружен быть не может.

FLUSH     ( -- )

Запись всех обновленных дисковых буферов на диск, после чего освобождение этих буферов.

\         ( -- ) Пропуск оставшегося текста данной строки.
\S        ( -- ) Пропуск оставшегося текста экрана.
THRU ( мач ком — ) Загрузка всех блоков с номерами из диапазона от нач до кон

.( текст) ( -- )

Вывод текста сообщения, ограниченного правой круглой сковкой. Используется, как правило, за пределами определения через двоеточие.
THRIAD ( n -- )

Вывод трех блоков с номерами, включающими n, начиная с номера, делящегося вез остатка на 3.

SHOW ( нам кон -- ) Вывод блоков с номерами из диапазона от нач до кон по три блока.
INDEX ( нам кон --) Вывод комментария только для блоков , номера которых входят в диапазон от н а ч до кон.
LOCATE xxx ( -- ) или VIEW Вывод содержимого блока, иэ которого было загружено определение слова ххх.
Команды редактирования - работа со строками

Т ( n -- )

Вывод заданной строки.
Р ( — ) Рьь или Р XXX Копирование заданного фрагмента, еcли есть, в буфер вставок, после чего помещение копии буфера вставок в текущую строку.
U ( -- ) Uьь или U ххх Копирование заданной строки, если есть, в буфер вставок  после чего помещение копии буфера вставок в строку, следующую за текущей.
G ( блок строка ) Копирование заданной строки и помещение ее в строку перед текущей, со сдвигом текщей и всех последующих строк вниз.

BRING ( блок нам кон )

Получение строк в указанном диапазоне.

X ( — )

Копирование текщей строки в буфер вставок и извлечение этой строки из блока.

F или ( — ) F ххх

Копирование указанной строки, если заданы, в буфер поиска, после чего поиск данной строки в текущем блоке.

S или S xxx

( n - ) или ( n - n )

Копирование указанной строки, если задана, в буфер поиска, после .чего просмотр блоков от текущего до n-ного в поисках указанной строки. Если строка найдена, на стек помещается номер последнего просмотренного блока.

E ( - ) Используется следом за F. Удаляется столько символов перед курсором, сколько их в данный момент находится в буфере поиска.

I> или Б ххх

( - )

Копирование указанной строки, если задана, в буфер поиска, поиск очередного вхождения этого фрагмента в текущей строке и удаление его.

TILL или TILL xxx

( - )

Копирование указанной строки, если задана, в буфер поиска, после чего удаление всех символов, начиная от курсора и заканчивая последним символом заданной строки.

I или

I XXX

( - )

Копирование умазанного фрагмента, если задан, в буфер вставок, после чего помещение содержимого буфера вставок сразу же после курсора.

R или R xxx

( - )

Объединяются команды Е и I. Замещение найденного фрагмента заданным фрагментом или содержимым буфер вставок.

( - )

Отметка конца текста, помещаемого в буфер.

Комбинированные команды редактировании
WIPE ( -- ) Заполнение текущего блока пробелами.
L

( -- )

Вывод содержимого текущего блока.
( -- ) Делается текучим следующий блок.
В ( -- ) Делается текущим предыдущий блок.
COPY ( откуда куда -- ) Копирование содержимое одного блока в другой.
К ( -- ) Меняются местами содержимое буфера поиска и буфера вставок.

ОСНОВНЫЕ ТЕРМИНЫ

Блок. В Форте представляет собой раздел дисковой памяти, содержащий 1024 символа исходного текста.

Блок, загрузки. Блок, который, будучи загруженным, сам осуществляет загрузку остальных блоков прикладной программы.

Буфер. Участок памяти для временного хранения данных.

Входной поток. Строка символов, предназначенная для обработки текстовым интерпретатором. Входной поток может подавать-

ся либо с текущего устройства ввода, например с клавиатуры (через буфер входного текста), либо с внешнего устройства, такого, как диск (через блочный буфер).

Исходный текст. Определение или несколько определений, написанных на языке, близком к естественному, с соблюдением правил пунктуации в противоположность к компилируемой форме представления определений, в которой те заносятся в словарь.

Нулевое определение. Определение, записываемое в форме

    : ИМЯ ;

и не предусматривающее выполнение каких-либо операций. Оно служит как бы «закладкой» в словаре, отмечая место, до которого весь текст «Забывается» по команде FORGET.

Оверлейный фрагмент. Фрагмент прикладной программы, замещающий при загрузке другой фрагмент в словаре.

Указатель. Участок памяти, куда может быть помещено число (или где оно может быть изменено), предназначенное в дальнейшем для ссылок.

УПРАЖНЕНИЯ

3.1. а) Введите ваши определения слов ДАР, ДАРИТЕЛЬ и СПАСИБО из упр. 1.1 и 1.3 в блок, после чего загрузите и исполните слово СПАСИБО,

б) с помощью редактора измените имя в определении ДАРИТЕЛЬ, после чего загрузите и исполните слово СПАСИБО снова. Что произойдет в этом случае?

3.2. Попытайтесь загрузить некоторые из наших математических определений из гл. 2 в какой-нибудь доступный блок, а затем загрузите его. Поэкспериментируйте.

ЛИТЕРАТУРА

[1] Brodie, Leo, Thinking Forth (Englewood Cliffs, N.J.: Prentice-Hall, 1984).