День шестой.

День шестой.

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

topic

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

help слово

Порадовало нечуствительность к регистру. Удобно.

Текст справки переформатирован фактически из тексат стандарта DPANS'94 В тексте справки оставлено много лишнего, то что имеет определенный смысл в стандарте, но абсолютно лишено такового в справке: как произносятся слова, ссылки на разделы стандарта, форматирование стандарта. Еще один досадный момент – несмотря на то что есть перевод этого самого стандарта, текст справки дан в англоязычном варианте. Может автор считал, что первоисточник приводить лучше, так как он понятнее. Но как по мне – лучше уж русскоязычная справка. Еще замеченная шероховатость – при некоторых вызовах справки происходит подторможивание, видимо SP-Forth какие-то разделы подгружает...

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

: man
 ." ---  Разделы справки  --- " CR
 ." core       - базовые слова" CR
 ." сore-ext   - расширения" CR
 ."      Использование: man слово" CR
;

Нашел форум Авиабазы Много чего интересного можно на нем найти. Он не может похвастаться активностью, но ответы там толковые.

Наткнулся на такой пример

WINAPI: MessageBoxA user32

: Test 0 S" Test" DROP S" Hello!" DROP 0 MessageBoxA DROP BYE ;

' NOOP MAINX ! ' Test TO

TRUE TO ?GUI FALSE TO ?CONSOLE

S" gui.exe" SAVE BYE

Генерит exe-шник, который выдает всего лишь окошко приветствие. Файл получился 88кБ. Правда, я в spf.ini все поотключал. Наверное это много. Но уже интересенее стало :)

С того форума: SP-Forth, слово S" всегда в конце строки добавляет замыкающий ноль. Т.е. стока на один байт длиннее положенного, зато сразу ASCIIZ. Достаточно сбросить со стека длину - и получим строку в готовом для WinAPI-функций виде.

 0
 S" Test" DROP \ если не перепутал их (title и text) порядок - должны быть
 S" Title" DROP \ в обратном сишному.
 0
 MessageBoxA

да, а про это я и не знал... Все таки в справку нужно вставлять не стандарт, а то что есть действительно. В справке про это ни гу-гу!

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

Глава 11 – создание новых слов, оказалась гораздо поинтереснее. Forth предоставляет механизм описывать свои слова. Мощный инструмент.

: ax+b
 CREATE  ( a b – )  \ стадия создания нового слова
 SWAP , ,          \ помещаем данные со стека в тело создваемого слова
 DOES> ( x – y )    \ стадия работы нового слова
         ( x adr )   \ на вершине стека - адрес поля данных этого слова
 DUP @ ( x adr a )
 ROT   ( adr a x )
   *     ( adr a*x)
 SWAP  ( a*x adr )
 CELL+ @ ( x*a b )
   +       ( x*a+b )
;
    \ ----- Пример использования ----
2 3 ax+b 2x+3   \ создали новое слово 2х+3

5 2x+3 . \ применение вновь созданного слова

От приведенного в книге это определение слова отличается тем что не использует стек возвратов.

Да, при написании много времени занимает отслеживание расположение данных на стеке, запсиь стековой нотации. Да и становится листинг так понятней.

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

Принципы игры "Жизнь" очень простые: перед началом игры с помощью простого редактора на экране дисплея изображаются колонии "клеточных бактерий" (представленные простыми графическими образами или буквами). После того как введена картина их исходного расположения, начинается жизнь первого "поколения". У каждой клетки имеется восемь соседних позиций <по числу основных направлений стрелки компаса), в которых могут находиться или не находиться другие клетки. Течение "эволюции" расположения клеток зависит от числа соседей, которое имеет каждая клетка: если их у нее меньше двух, то говорят, что она "умирает" от "одиночества", если больше четырех - то от "тесноты". Однако клетка, имеющая двух или трех соседей выживает до следующего поколения. Кроме того, если вокруг какой-либо незанятой позиции образуется точно три соседние клетки, то в этом месте спонтанно возникает новая клетка нового поколения. При выполнении таких простых правил исходное поколение клеток может прийти к гибели, к конечному устойчивому состоянию или изменяться в течение нескольких, сотен и даже тысяч поколений. Ход игры всегда интересен, удивительно непредсказуем и приводит к очень любопытным конфигурациям клеток.

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

Начал писать и застопорился на отладке слова РасставитьКлетки

\  Life game
\ -------- Данные --------------
16 CONSTANT ВысотаПоля
16 CONSTANT ШиринаПоля

: Массив CREATE \ Резервирую место под массив ВысотаПоля ШиринаПоля * ALLOT

DOES> \ ( x y -- adr )Выдаю просто адрес ( x y addr ) ROT ROT ( addr y x ) * 1- \ получили индекс одномерного массива CELL * \ отмасштабировали адрес + \ адрес элемента ;

\ -- Сделали поле Массив ЧислоСоседейКлетки Массив КлеткиНаЭкране

: РасставитьКлетки ВысотаПоля 1 DO ШиринаПоля 1 DO I J * 2 MOD \ генерим "случайно" 1 или 0 бактерии I J КлеткиНаЭкране ! \ и расставляю их по всему полю LOOP LOOP ;

РасставитьКлетки

\ 20 0 DO \ ПоказатьКолонию \ ОпределитьКоличествоСоседей \ УдалитьМертвыеКлетки \ ДобавитьНовыеКлетки \ LOOP \ 1 1 16 КлеткиНаЭкране ! \ 4 4 КлеткиНаЭкране @ .

Вот это слово РасставитьКлетки вылетает с ошибкой, генерит исключение и SP-Forth выдает дамп памяти, который мне абсолютно пока ни о чем не говорит.

Цикл отрабатывает нормально, значения счетчиков цикла пробегают от 1 до 15 как и положено, КлеткиНаЭкране ! нормально запоминает числа для любых координат от 1 до 16. Это проверял в диалоговом режиме.

1  1  16 КлеткиНаЭкране  !
1  1  1  КлеткиНаЭкране  !
1  16 16 КлеткиНаЭкране  !
1  4  4  КлеткиНаЭкране  !
 Ok

В таком варианте, тоже работает

: РасставитьКлетки
   ВысотаПоля 1 DO
      ШиринаПоля 1 DO
       I J * 2 MOD             \ генерим "случайно" 1 или 0  бактерии
          15 15 КлеткиНаЭкране ! \ и расставляю их по всему полю
 LOOP
 LOOP
;

А как только координаты задаю счетчиками, все начинает сбоить... Потратил полтора часа, а ничего так и не нашел...

Отложил задачу. Через некоторе время пришла здравая мысль – массив расположил в области кода, который по определению не модифицируемый. Решил изменить тактику – данные размещать в динамической области, а в переменных хранить только адрес начала выделенной памяти. Второе, к чему пришел – отказ от использования специализированных слов, сделанных через связку : CREATE ... DOES> ... ; По крайней мере в этом проекте.

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

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

Мне эта эпопея с изучением Forth напоминает установку и настройку ранних дистрибутивов Linux. Интересно, есть энтузиазм, а информации нет, то что находишь – скудное, противоречивое, и топаешь методом проб и ошибок...

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

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

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

Hosted by uCoz