Программирование на языке Форт в среде AFS.
Часть 6. Манипуляции в стеке. Продолжаем рисовать.


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

Предыдущую статью мы закончили определением слова H-LINE , которое рисует горизонтальную линию заданной длины с началом в указанных координатах. Длина и координаты передаются в стеке.

Нам также необходимо слово V-LINE , рисующее вертикальную линию. Для единообразия слово должно получать в стеке длину и координаты, в том же порядке, что и H-LINE . Рисовать будем символом "восклицательный знак".

Разница между H-LINE и V-LINE заключается в том, что для каждого символа вертикальной линии мы должны устанавливать новую координату y. Нам понадобится слово, сохраняющее копию координат на вершине стека, потому что слово GO-XY , перемещающее курсор, удаляет их.

В Форте имеются слова DUP и 2DUP . Слово DUP (от duplicate) создает дубликат числа, лежащего на вершине стека. Если вернуться к аналогии с кирпичами, при выполнении слова DUP кирпич с вершины стека "клонируется" и его брат-близнец кладется поверх него. Таким образом, в стеке становится одним числом больше, причем на вершине оказывается пара идентичных чисел:

Действие слова DUP

Слово 2DUP создает дубликат пары ячеек, лежащих на вершине стека, сохраняя порядок следования ячеек в паре. Это как раз то, что нам нужно для копирования координат.

Еще одно слово, которое нам пригодится, ROT . Это слово "вращает" три верхних ячейки стека таким образом, что третий сверху "кирпич" оказывается на вершине, а два верхних опускаются вниз:

Действие слова ROT

И последняя пара слов, DROP и 2DROP . Слово DROP просто удаляет число, находящееся на вершине стека:

Действие слова DROP

Слово 2DROP удаляет из стека верхнюю пару ячеек.

Теперь мы можем определить слово V-LINE :

:  V-LINE  \  len  x  y  --  \
   ROT
   0  DO  2DUP  GO-XY  [CHAR]  !  EMIT  1+  LOOP
   2DROP  ;

Пройдем по определению. Первым делом, с помощью ROT , на вершину стека перемещается длина линии, которая становится пределом цикла в следующей строке. В начале цикла на вершине находятся координаты x и y, которые мы копируем с помощью 2DUP . Копию координат использует слово GO-XY для перемещения курсора. Далее выводится символ ! .

После перемещения курсора в стеке находятся исходные координаты, причем на вершине лежит y. Слово 1+ увеличивает значение y на 1. Если слово LOOP не обнаруживает признака завершения цикла, выполнение повторяется сразу после слова DO , но с новой парой координат в стеке.

После выхода из цикла выполняется слово 2DROP , которое освобождает стек от оставшихся там координат.

Если вы выполняете рассматриваемые примеры, загрузите слова из прошлых статей и добавьте определение V-LINE . Теперь можно проверить, как это работает:

Вывод вертикальных линий словом V-LINE

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

:  FRAME  
   66  7  3  H-LINE  66  7  20  H-LINE
   16  7  4  V-LINE  16  72  4  V-LINE  ;

Слово FRAME рисует рамку, имеющую размер внутреннего поля 16 символов по высоте и 64 символа в ширину. Рамка расположена в центре экрана, поэтому верхний левый угол внутреннего поля будет иметь координаты x=8, y=4.

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

CLRSCR  FRAME

Вы должны увидеть вот такую картину:

Рамка, нарисованная словом FRAME

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

:  FRAME-XY  \  x  y  --  \
   4  +  SWAP  8  +  SWAP  GO-XY  ;

Это слово перемещает курсор внутри рамки. Координаты 0;0 соответствуют верхнему левому углу внутреннего поля.

Нам потребовалось использовать новое слово, перемещающее данные в стеке. Слово SWAP меняет местами две ячейки на вершине стека:

Действие слова SWAP

После того, как мы добавили смещение 4 к y, мы меняем x и y местами (первое слово SWAP ), добавляем смещение 8 к x, после чего восстанавливаем порядок координат в стеке (второе слово SWAP ).

Проверим, как это работает, создав небольшой шедевр компьютерной графики. Определим новое слово:

:  SKY  CLRSCR  FRAME
   64  0  DO
        16  0  DO
             J  I  FRAME-XY  STAR
        LOOP
   64  LOOP  ;

Начинается определение очисткой экрана и выводом рамки.

Мы специально расположили текст "ступеньками", чтобы было видно два счетных цикла, вложенных один в другой.

Первый цикл имеет предел 64, он используется для перечисления координат x внутри рамки. Внутри этого цикла выполняется второй цикл, имеющий предел 16, что дает перебор координат y.

В определении появилось два новых слова. Слово I возвращает на вершине стека значение счетчика текущего цикла, а слово J – значение счетчика цикла, внешнего по отношению к текущему. Таким образом в стек помещаются координаты внутри рамки, которые мы передаем слову FRAME-XY для установки курсора. Слово STAR рисует звездочку в указанном месте.

Выполним слово SKY и понаблюдаем, как рамка заполняется "звездочками":

Заполнение рамки звездочками

Конечно, считать это изображением звездного неба можно весьма условно, слово SKY – всего лишь шутка. Обратите внимание, развертка изображения по вертикали выполняется заметно медленнее, чем по горизонтали. Этот эффект должен учитываться при выводе больших массивов данных на терминал.

Спасибо за внимание.


[Начало статьи] [Предыдущая статья] [Все статьи]

Вы можете оставить комментарий к статье и задать вопросы на нашей странице в соцсети ВКонтакте

Вы можете оставить комментарий к статье и задать вопросы на нашей странице в соцсети Facebook