День 16. Строчный редактор (продолжение)

День 16. Строчный редактор (продолжение)

Зачем. Управление курсором. Улучшение справки.

Зачем

Вернулся после праздников и нашел ответы в рассылке spf-def по багу, указанному в конце прошлого дня. Насколько я понял по рассылке, шероховатость была в оптимизаторе, ее уже убрали. Ruvim Pinka посоветовал в спорных моментах пробовать отключать оптимизатор словом DIS-OPT , которое нужное ставить в начале листинга. Действительно, все заработало.

Ruvim Pinka задал интересный вопрос: "... тот же редактор текста - уйма написанно." Вопрос правильный, но ниже я объянню причины этого шага:

Управление курсором

В библиотеке ~day/common/console.f нашел, что видом курсора упарвляют две библиотечные функции GetConsoleCursorInfo и SetConsoleCursorInfo Там же нашел как их использовать, скопировал в отдельный файл:

WINAPI: SetConsoleCursorInfo KERNEL32.DLL \ Библиотечные функции
WINAPI: GetConsoleCursorInfo KERNEL32.DLL \ Выдают информаци о курсоре

CREATE CONSOLE_CURSOR_INFO 8 ALLOT \ Область памяти куда информац записывают

:NONAME \ Заполнили струкутру информацией о курсоре CONSOLE_CURSOR_INFO H-STDOUT GetConsoleCursorInfo DROP \ Включили курсор 0 CONSOLE_CURSOR_INFO ! \ Внесли изменения CONSOLE_CURSOR_INFO H-STDOUT SetConsoleCursorInfo DROP ; EXECUTE

Самое интересное и важное – это структура даннах CONSOLE_CURSOR_INFO которая и содержит собственно данные о курсоре. Поиск на Рамблере по названию функции GetConsoleCursorInfo сразу же дал ее описание. Если кратко, то курсор описывается двумя парамерами: разм_курсора – число от 0 до 100, указывающий высоту курсора (0 – самый узкий, 100 - квадрат), видм_курсора – флаг, управляющий видимсотью курсора: 0 - курсор погашен, все отсальное – включен. Вот структура:

  разм_курсора CONSOLE_CURSOR_INFO !
  видм_курсора CONSOLE_CURSOR_INFO 4 + !

\ -------------- Примеры -------------------------- 0 CONSOLE_CURSOR_INFO 4 + ! \ Курсор погашен 16 CONSOLE_CURSOR_INFO 4 + ! \ Курсор включен

1 CONSOLE_CURSOR_INFO ! \ очень тонкий курсор 100 CONSOLE_CURSOR_INFO ! \ квадрат 50 CONSOLE_CURSOR_INFO ! \ полкурсора

\ Можно и так. Без запроса состояния 50 CONSOLE_CURSOR_INFO 4 + ! 1 CONSOLE_CURSOR_INFO ! CONSOLE_CURSOR_INFO H-STDOUT SetConsoleCursorInfo DROP

Вот такой примерно алгоритм поиска сведений о работе функций Винды...

Тут несколько походил и пришла другая мысль. Массив CONSOLE_CURSOR_INFO используется как временный буфер, а что если вместо него использовать стек? И вот что получилось:

 1 15   \ ширина курсора и его видимость
 SP@    \ указатель на вершину 
 H-STDOUT  SetConsoleCursorInfo DROP \ собственно сам вызов функции

Получилось все очень красиво! Лаконично. Без лишнего загромождения кода. И все вписывается в концепцию – стек для промежуточных данных. Однако нужно учитывать несколько моментов:

Можно попробовать это сделать и через буфер, скажем, TIB. Но через стек получилось изящнее, избежал оперирования адресами, введением дополнительной структуры.

Еще один пример тспользование свободной области как буфера нашел у А. Черезова в fc\lib\win\winver.f

  HERE GetVersionExA 0<>
  HERE 4 CELLS + @ VER_PLATFORM_WIN32_NT = AND

Используется свободная область за указателем HERE Этот метод применим в случае больших возвращаемых блоков данных. В этом случае GetVersionExA возвращает блок данных размером более 200 байт. И второе его достоинтсво – не нужно чистить использованную память.

Улучшение справки

Т.к. постоянно приходится работать со справкой, пришлось ее несколько подправить. Что сделано:

Что получилость, можно взять отсюда

Вообще-то, использовать стандарт в качестве справки не очень практичная мысль. Команда должна быть описана кратким и приземленным языком, без лишнего онаучивания. И желательно с примерами.

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

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

Пример описания слова
: QUIT ( – ) ( R: i*x )
\ Сбросить стек возвратов, записать ноль в SOURCE-ID.
\ Установить стандартный входной поток и состояние интерпретации.
\ Не выводить сообщений. Повторять следующее:
\ - Принять строку из входного потока во входной буфер, обнулить >IN
\   и интепретировать.
\ - Вывести зависящее от реализации системное приглашение, если
\   система находится в состоянии интерпретации, все процессы завершены,
\   и нет неоднозначных ситуаций.

BEGIN CONSOLE-HANDLES 0 TO SOURCE-ID [COMPILE] [[ ['] MAIN1 CATCH ['] ERROR CATCH DROP AGAIN ;

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

<<< Предыдущий Начало  
Copyright © Alex Furashev 2004

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

Hosted by uCoz