KRIEGSSPIELE!
Вы хотите отреагировать на этот пост ? Создайте аккаунт всего в несколько кликов или войдите на форум.

Компилирующие слова

Перейти вниз

Компилирующие слова Empty Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:46 pm

Кроме того, машина, о которой говорится в статье, до такой степени неэффективна, что каждая реализация фактического алгоритмического языка, вероятно, может рассматриваться как ее оптимизация, возможная благодаря некоторым ограничениям языка. /Э.В.Дейкстра/

Что можно сказать о шитом коде FORTH "в общем"? В первую очередь, существует четкое разделение слов на категории: слова, создающие другие слова; слова, создающие структуры управления в других словах; и слова, обеспечивающие доступ к различным частям откомпилированных слов. (Что будет, если смешать все категории в одну кучу, об этом позже).
Во вторую очередь - то, что шитый код реализован простейшим способом. Ни о какой тщательно выверенной и единственно верной схеме речь не идет.
***

Общепризнанных способов, создающих другие слова очень немного:
1. : ... ; - способ создавать "обычные слова" - как комбинации из других слов;
2. VARIABLE, VALUE, CONSTANT... - способы создавать "переменные" обычного для других языков программирования вида;
3. CREATE - обобщенный способ создавать не только "переменные", но и "массивы".
4. CREATE ... DOES> - обобщение способа (3). Позволяет создавать слова "по образцу": имеющие одинаковый функционал, но разные хранимые данные. Правда к хранимым данным относится и шитый код, что позволяет иметь не "неодинаковый" функционал.
Если в (3) речь идет чаще о непосредственном создании "массивов", то здесь - о создании слов "создающих "массивы".

На первый взгляд, жуткая бесконечная рекурсия: создание слов; создание слов, создающих слова; создание слов, создающих слова, создающие слова...
Броуди, скорее запутывает дело, чем проясняет. Его примеры (ограничивающиеся созданием слов, создающих слова - конструкция : ... CTEATE ... DOES> ... ; ) изящны, но недостаточно глубоки...

По Баранову и Нозрунову: Компилирующие слова Leaf10ТЕМА #120, АБЗАЦ #2032Компилирующие слова Leaf10.
***

"CREATE ... DOES> ... Создает новый уровень выразительности".
Еще одна цитата из цикла: "Я не соласен, что FORTH это язык тупого программиста и умного пользователя, т.к. сам - программист".
Я, к ужасу своему, заметил, что совсем забыл уделить внимания связке CREATE ... DOES> .., понадеявшись на Броуди. Придется наверстывать.

Допустим, есть функция f(a, b). И мы считаем, что множество значений первого параметра (a) порождает достаточно важные частные случаи. Не долго думая мы заменяем f(x,b) на fx(b), f(у,b) - на fy(b), f(z,b) - на fz(b)...
Конечно, в терминах ООП это записывается красивее: класс f с двумя методами: конструктор f::f(а) и исполнятор f::operator()(b). Но, ведь, в ООП никто не заставляет ограничиваться только двумя методами...
И где тут "новый уровень выразительности"? Просто удобный способ сокращенной записи важных частных случаев путем придумывания им отдельных имен, основанный на том, что парадигмы програмирования по одиночке не ходят... Введешь, например, понятие переменная, и пользуешь в свое удовольствие... Или константа, или массив, или структура памяти, или ... Очень мало что "или". Эта конструкция очень хорошо подходит для создания хитрых данных "со встроеным обработчиком", но совершенно не обязательно стараться свести все сущее именно к ней одной.
***

И еще... Пусть, например, нам надо реализовать в виде шитого кода следующий фрагмент: "A; if B then C else D; E;". (Понятно, речь идет о второй категории компилирующих слов - создающих структуры управления).

1. Мы привыкли видеть в шитом коде цепочку A-E, прореженную кодами [?]BRANCH и адресами перехода.
2. Второй вариант - слово CD, имеющее два варианта исполнения - C или D - в зависимости от внешнего условия. Или слово, состоящее из пар "слово-условие - слово-действие", работающих подобно конструкциям if-fi (do-od) Дейкстры. В отличие от (1) такой шитый код не требует прошивки пар [?]BRANCH-адрес.
3. Третий - слово CD, переопределяемое словом В в виде C или D.
4. Можно еще хитрее - слово В, изменяющее следующий за ним адрес на C или D. Как и в (3), это позволяет управлять ветвлением "очень издалека".

А как быть с циклами, как сделать их без прыжков-адресов?

5. Можно, как в (2) - слово, повторяемое определенное число раз (или пока выполняется условие).
6. Использование в конце шитого кода специального слова "вернуться к началу" или "вызвать с начала рекурсивно". Можно по условию (2) или перезаписывать/переопределять (3 или 4).

Т.о. мы видим огромный спектр возможностей, из которых "классический FORTH" использует только самую простую. Даже в FORTH-процессорах.
Однако, время от времени отголоски этих решений всплывают. Например, в виде конфликта между DOER и DEFER. Что лучше: иметь в переопределяемых словах ссылку на слово, или на кусок шитого кода?


Последний раз редактировалось: Gudleifr (Вт Мар 23, 2021 9:44 am), всего редактировалось 2 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:48 pm

ЗАБАВНЫЙ ПРИМЕР ИЗ ОДНОЙ FORTH-ПРЕЗЕНТАЦИИ

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

: launch \ ЗАПУСК ШАТТЛА
BEGIN
00 00 06 60 T- is-time? IF start-main-engine-3 THEN
00 00 06 48 T- is-time? IF start-main-engine-2 THEN
00 00 06 36 T- is-time? IF start-main-engine-1 THEN
00 00 00 00 T+ is-time? IF ignite-SRBS release-SRBS THEN
00 00 00 01 T+ is-time?
UNTIL ;

Все более или меннее понятно (слова T+ и T-, очевидно, переводят время из человеческого в миллисекунды с указанием знака - "до" и "после"). Автор презентации предлагает следующее "улучшение":

: launch
BEGIN
00 00 06 60 T- at start-main-engine-3
00 00 06 48 T- at start-main-engine-2
00 00 06 36 T- at start-main-engine-1
00 00 00 00 T+ at ignite-SRBS release-SRBS
00 00 00 01 T+ is-time? UNTIL ;

где слово at определяется следующим образом:

: at
POSTPONE is-time? POSTPONE IF BEGIN
BL WORD DUP COUNT NIP WHILE
FIND IF
POSTPONE LITERAL POSTPONE EXECUTE ELSE
DROP THEN
REPEAT DROP POSTPONE THEN ; IMMEDIATE

Немножко облегчить читабельность одного блока за счет другого - полностью нечитаемого?
***

ЛИРИЧЕСКОЕ ОТСТУПЛЕНИЕ.
Слово POSTPONE узаконено стандартом ANSI-94. Оно дополняет старое доброе слово [COMPILE] способностью "компилировать и так компилируемые слова", пытаясь придать смысл выражению "отложить компиляцию следующего слова до времени исполнения определения". Т.е. при исполнии слова at слово is-time? будет нормально скомпилировано в launch, а IF создаст в launch начало условной конструкции. Ранее было бы "COMPILE is-time? [COMPILE] IF".
КОНЕЦ ЛИРИЧЕСКОГО ОТСТУПЛЕНИЯ.
***

Дело даже не в том, что основные пороки читабельности остались как были: избыточные данные ("00 00 06 60 T-" вполне можно заменить на "-06.60") и большое количество практически одинаковых строк (надо либо заменять таблицей, либо продолжать упрятывать структуры в слова). Раз уж мы упрятали в слова IF-ы, то почему не упрятать туда время и действие? Причем, это будет даже проще.
И - даже не в том, что в слове at спрятана возможность ошибки - нет реакции на неправильно введенную команду.
Основной недостаток данного фрагмента другой - мы практически имеем систему, которая большую часть времени ничего не делает, занимая при этом вычислительные ресурсы. Тупо крутится в бесконечном цикле. Причем, остается опасность того, что увлекшись обработкой одной команды, программа не успеет вовремя запустить следующую. Сам бог велел повесить это все на прерывание таймера.
Но тут - облом. Хоть FORTH и пишется прямо на железе (и даже на специальном железе для него созданном), его всеми силами пытаются обстрагировать от особенностей этого самого железа. По Стандарту, прерывания - лишь дополнительный структурный выход из программного блока по ошибке.
***

Так что, лучше, смотрите примеры у Броуди.
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:48 pm

ЗАМЕЧАНИЯ О DOES>

С точки зрения объектно-ориентированного программирования DOES> - это, ведь, тоже ссылка (вида is_a - т.е. указывающая на "род"). И ее даже можно использовать! Например, Таунсенд и Фохт так определяют тип слова:

: ПЕРСП ( -- PFA+2 ) CREATE HERE 2+ , 0 , DOES> 2+ ;
ПЕРСП FOO ' FOO @ FORGET FOO
: ПЕР? ( С -- F ) DUP @ 0= SWAP 4 - @ [ DUP ] LITERAL = AND ;
DROP

Т.е. "типом слов" (созданных ПЕРСП) будет адрес их шитого кода (лежащего в ПЕРСП за DOES>).
***

Мало кто пользуется тем, что кроме параметров-данных между CREATE и DOES> можно вставлять и параметры-код.

CREATE данные ] DOES> код >R

Например, в игре, которую я сейчас переписываю для своей странички, есть, как и положено, жуткий набор правил: "если выполняются такие-то условия, то можно сыграть так-то". Причем два "условия" - "для данной версии правил" и "в этой фазе хода" повторяются постоянно. Что может быть проще, чем придумать особый вид слов - ПРАВИЛА?

VARIABLE ФАЗА
VARIABLE ВЕРСИЯ
: ПРАВИЛО ( <ИМЯ> ФАЗА, ВЕРСИЯ -- ...) CREATE , , ] DOES>
DUP @ ВЕРСИЯ @ AND IF CELL+ DUP @ ФАЗА @ = IF CELL+ >R
ELSE DROP THEN ELSE DROP THEN ;

Использование:

фаза версия ПРАВИЛО имя-правила код -правила ;

5 ФАЗА !
7 ВЕРСИЯ !

5 1 ПРАВИЛО EX1 55 . ;
6 1 ПРАВИЛО EX2 66 . ;
5 3 ПРАВИЛО EX3 77 . ;

EX1 EX2 EX3 ___55_77_Ok

P.S. В этом смысле >R очень часто удобнее EXECUTE , т.к. позволяет выполнить не одно слово, а целое предложение.
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:49 pm

НЕНОРМАЛЬНЫЕ КОМПИЛИРУЮЩИЕ СЛОВА

Пишу этот огрызок с чувством глубокой обреченности. Никакого красивого решения или полезной морали здесь не предвидится. Да и что может получиться из помещения в раздел "Алгоритмы" вещей, для которых мы эти самые алгоритмы даже не умеем толком записать?
Более того, предложенный способ изложения может всерьез разозлить пару категорий фортеров. Для удобства спора обозначу их как:
- МИКРО-ФОРТЕР - фортер, считающий что FORTH существует только в тех узких рамках, в которых он его понимает (обычно - в рамках стековой машины с шитым кодом). Следовательно, можно создать некое FORTH-ядро (виртуальную FORTH-машину), которую можно будет продавать любым FORTH-программистам даже без объяснения внутреннего устройства.
- СТРУКТУРНЫЙ ФОРТЕР. Тоже верит в незыблемость понятия виртуальной FORTH-машины. Однако, считает, что FORTH есть нечто большее - а именно, структурное расширение этого "ядра" до размеров "обычного" языка программирования высокого уровня.

Может, конечно, эти зловредные типы лишь мне мерещатся, но до чего же удобно с ними, безответными, спорить!
***

"Нормальные" слова FORTH честно собираются из других слов, как ожерелье из бусин. Во всех FORTH-учебниках этот процесс многократно воспет и превознесен до небес.
Микро-фортеры даже считают, что ничего другого пользователю и не надо - нанизывай бусину за бусиной, изредка вставляя специальные - условия, циклы и прочие "структурности".
***

Однако, если FORTH позволяет полностью сам себя переписывать, почему этим не воспользоваться и не насоздавать своих "специальных" слов?
Первое, что обычно приходит в голову, создание своих компилирующих слов (в "обычных" языках их бы назвали операторами управления). Это не трудно, хотя и вызывает забавный философский вопрос: что является "блоком" (в понимании структурных языков программирования) языка FORTH - целое слово или кусок шитого кода? (Назовем это ВОПРОСОМ КВАНТОВАНИЯ).
***

Вторая область приложения усилий любителей создания "ненормальных" слов - слова, изменяющие свое поведение по ходу программы.
Простейший случай выглядит так: надо ввести некое слово-1, которое используется в слове-2, но слово-2 само используется в слове-1 (РЕКУРСИЯ). Другие примеры - оставление пользователю возможности переопределить системное слово позднее (ДООПРЕДЕЛЕНИЕ) или создание слова, которое будет работать то так, то этак (КОСВЕННОСТЬ)... Микро-фортеры обычно признают только косвенность, т.к. рекурсию не понимают, а доопределение считают частным случаем косвенности. Структурные фортеры (действуя полностью аналогично) при этом еще и путано рассуждают о необходимости отделить объявления функций от определений (как в "приличных" языках).
С точки же зрения FORTH, все очень просто - надо оставить где-то в шитом коде дырку (поименованую, чтобы потом ее можно было найти). И придумать способ заполнения этой дырки позднее нужным кодом.
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:50 pm

ПРОСТЕЙШИЙ СПОСОБ ПЕРЕОПРЕДЕЛЕНИЯ СЛОВА

Он не требует введения никаких необычных слов:

VARIABLE 'СЛОВО-1
<...>
: СЛОВО-2 <...> 'СЛОВО-1 @ EXECUTE <...> ;
<...>
: СЛОВО-1 <...> ;
<...>
' СЛОВО-1 'СЛОВО-1 !
<...>
СЛОВО-2 \ будет выполнено то, что в переменной 'слово

Т.е. СЛОВО-1 вызывается через промежуточную переменную 'СЛОВО-1 , содержащую его адрес. Значение переменной, понятное дело, можно изменить в любое время. "Дыркой" в данном случае является просто (неразрешенный по-началу) "указатель на функцию".
***

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

DEFER СЛОВО-1 ( -- ) заменяет VARIABLE. СЛОВО-1 теперь не просто переменая, а слово, исполняющее код, указуемый "указателем";
DEFER@ ( cfa -- cfa' ) и DEFER! ( cfa', cfa -- ) дают доступ к "указателю" как к обычной переменой;
IS СЛОВО-1 ( cfa' --) заменяет "!", присваивающее "указателю" новое значение, примерно то же, что и " ' СЛОВО-1 DEFER! ";
ACTION-OF СЛОВО-1 ( -- cfa' ) на случай, если захочется получить значение "указателя", примерно то же, что и " ' СЛОВО-1 DEFER@ ".

Здесь cfa - адрес кода слово-указателя, cfa' - значение "указателя".
***

Первые выводы:
- Решая проблему квантования в пользу "блок == слово", мы очень сильно упрощаем себе жизнь. "Ненормальные" слова становятся не такими уж и нужными. Плата - некоторые затраты на лишние имена и косвенные вызовы.
- На примере слова, введенного через DEFER, мы видим, что каждой разновидности "ненормальных" слов сопутствуют еще более "ненормальные": я их назову ПРИЧАСТИЯМИ, чтобы подчеркнуть то, что они создают ОБОРОТЫ - куски входного потока, которые вводятся в обход INTERPRET - первым словом оборота (обычно такие слова называются словами с предвыборкой). С "ненормальными" словами обычно связано два вида оборотов: создающий (здесь, DЕFER <имя>) и доступа (IS <имя> и ACTION-OF <имя>). Называется вид "ненормальных" слов обычно по имени создающему причастию.
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:50 pm

БЕЗ ЛИШНИХ СЛОВ

Какие очевидные улучшения предложенного выше метода можно предложить?
Хочется избежать создания лишних имен. У нас их было два: имя "указателя" и имя слова, на которое "указатель" будет указывать. Первое лучше оставить - надо же как-то адресовать "дырку". А вот второе можно ликвидировать: затыкать "дырку" безымянным куском шитого кода.
Подобный механизм - с использьзований причастий DOER и MAKE прекрасно описан у Броуди - с примерами и исходниками.
***

Если, все-таки отказаться и от первого имени, то можно получить такую схему (в наших первоначальных обозначениях):

: СЛОВО-2 <...> ... <...> ;
<...>
..: СЛОВО-2 <...> ;..

Слово "..." служит для обозначения дырки в "слове-2", блок, ограниченный " ..: слово-2" и ";.." - "вставляется" в эту дырку. Однако, "дырка" остается и может быть "заполнена" еще несколько раз (новыми " ..: слово-2 <...> ;.. ").
Во что обойдется такая "экономия"? Адрес "дырки" становится "составным": имя слова, в котором она находится и... в общем случае - надо искать в шитом коде сигнатуру "дырки". Идея постепеного заполнения "дырки" тоже вызывает сомнения...
На глаз же видно, что, используя вместо "..." DOER-имя, мы получаем гораздо более удобное средство.
***

- Начав изобретать подобные механизмы, мы все глубже и глубже погружаемся в устройство шитого кода. Так, например, рассматривая одну из реализаций причастия "..:" я пришел к выводу, что либо я не понимаю шитого кода данной системы, либо авторы немного намухлевали...
- Алгоритм действия "ненормальных" слов невозможно описать ни на каком языке. Т.к., если такое описание было бы возможно, можно было бы придумать еще более "ненормальные" слова, нарушающие правила и такого языка.
- Переходя к более сложным "ненормальным" словам, мы видим, что одними оборотами уже не обойтись, нужны целые предложения, подобные " : имя <...> ; " (выводящие FORTH из равновесия на время исполнения некоторых действий). Например, здесь: " ..: имя <...> ;.. ".
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:51 pm

ПРЕДОПРЕДЕЛЕННЫЕ РАЗНОЧТЕНИЯ

Есть такая разновидность "ненормальных" слов (еще их называют векторными, причем, чаще - неправильно), которые изначально прописываются в нескольких вариантах.
В простейшем случае такое поведение можно получить, используя условные выражения, или хитрую систему словарей, но можно применить и "ненормальные" слова.
Все, как выше - одно причастие для создания, несколько - для доступа к вариантам.
Например, VALUE - переменная, понимающая, что от нее требуется: выдача значения (вызов без причастия) или запоминание значения (с причастием TO). (Баранов и Ноздрунов подробно рассмотрели векторные слова - Компилирующие слова Leaf10ТЕМА #120, АБЗАЦ #2048Компилирующие слова Leaf10).
***

Возможны и другие варианты. Я уже приводил пример слова (WIN-CONST), которое при первом исполнении рассчитывало и выдавало константу, а при последующих - только выдавало. Т.к. Windows такие "константы" встречаются сплошь и рядом, то слово оказалось очень удобным.
***

С некоторой натяжкой к этому виду слов можно отнести и "обычные" DOES-слова. (Т.е. созданные выражением " CREATE имя <...> DOES> <...> ; "). Ведь их действие определяется не только их шитым кодом, но и состоянием их встроенных переменных. Или даже можно хранить в этих переменных "указатели", получая семейство слов, имеющих схожее, но не идентичное поведение. Хотя, обычно о DOES-словах говорят, не как о словах с разным поведением, но, наоборот, как о группе слов с одинаковым поведением.
***

- Имеем слова CREATE и DOES>, позволяющие создавать CREATE-слова, позволяющие, в свою очередь, создавать DOES-слова, изменяющие свое состояние в процессе исполнения... А если учесть, что многие из этих слов имеют различное поведение при компиляции и исполнении...
Попахивает бесконечной рекурсией. Чем раньше вы сможете разорвать этот порочный круг (Компилирующие слова Leaf10ТЕМА #129, АБЗАЦ #2248Компилирующие слова Leaf10), приняв некий все объясняющий компромисс, тем лучше...
- Ну, вот, к алгоритмическим проблемам добавились философские... Как их победить? Решение очень простое, однако, противоречащее убеждениям наших воображаемых оппонентов - не создавать заранее набор всех необходимых "ненормальных" слов, но открыть пользователю доступ к внутренним механизмам FORTH, позволяющим создавать любые виды слов самому.


Последний раз редактировалось: Gudleifr (Сб Май 29, 2021 12:56 am), всего редактировалось 2 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:52 pm

ПАРДОН, ПОГОРЯЧИЛСЯ

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

Код:
: <vector>   { name | xt -- }
   here  ['] xxx ,  to xt
   c" is-" name  get-current :2name   \ runtime: xt --
      xt lit, !, ;,
   name get-current :name   \ runtime: --   \runtime runtime: i*x -- j*x
      state@, if,   xt lit,  postpone lit,  postpone @,  postpone execute,
      else,         xt lit,  @,  execute,                                    then,  ;,
      immediate
 ;

 : vector ( -- )
   bl word hstr  dup >r  <vector>  r> dealloc ;

Что мы тут видим? (Не пугайтесь, это тот же DEFER, а xxx - слово затычка). Во-первых, уже в первой строчке вместо круглых скобок мы видим фигурные - т.е. используется механизм локальных переменных. Во-вторых, имеем механизм создания слов "на лету" (:name и :2name). В-третьих, видим, что компиляция компиляторов превращена в фетиш - наличие для всех нормальных слов дубликатов, заканчивающихся на "запятую" (т.е. компилирующих их). В-четвертых, имеем отсыл к интеллектуальному менеджменту памяти под строки (hstr). В-пятых, имеем тот же самый DEFER и обычное для его реализации "в лоб" и без всяких "структурностей" количество lit, и postpone.
Автор, заявляет, что это "более эффективно", чем "обычный DEFER. В чем? Только в экономии слов: вместо "IS СЛОВО-1" можно использовать "IS-СЛОВО-1", что будет немного быстрее интерпретироваться - одно слово вместо двух. Но, честно говоря, в замене вызова нескольких слов одним в FORTH никого не удивишь, это делает просто слово ":". Более того, слово DOER позволяет вместо указателей на слова использовать указатели на код (экономя словарные статьи). И, наконец, если потребуется "быстро переключаться с одного слова на другое", то, скорее всего, нужно будет воспользоваться обычными (C-подобными) средствами адресной арифметики...
Неразрешима только одна проблема: почему автор назвал это не "DEFER-ЧЕРЕЗ-ЗАД-СТРУКТУРНО", а "вектор"?


Последний раз редактировалось: Gudleifr (Пн Дек 05, 2022 3:34 pm), всего редактировалось 1 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:53 pm

И, ВСЕ-ТАКИ, ФОРМАЛИЗМЫ

В учебниках пишут: каждая словарная статья состоит из четырех полей
- nfa - поле [имени], по значению которого слово ищется в словаре;
- lfa - поле [связи], нужное для увязывания слов в единую связную структуру данных - словарь;
- cfa - поле [кода], определяющее способ запуска слова;
- pfa - поле [параметров], для всего остального.

Но...

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

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

- FORTH-ОБРАЗУЮЩИЕ - те, которые используют слова "как надо": интерпретируют, выполняют, компилируют. Некоторые из них являются "псевдо-словами", т.е. не имеющими имени (FORTH и так "знает", где они находятся, а вам не скажет).
- ОТ-ПОЛЯ-К-ПОЛЮ-ПЕРЕХОДЯЩИЕ - слова, получающие адрес одного из полей (или имя слова) и выдающие адрес другого. Микро-фортеры очень любят заявлять, что наличие в их продукте подобных слов, позволяет пользователю создавать любые "неправильные" слова, даже не имея документации. Это неверно: подобные слова не только по-разному работают в разных версиях FORTH (как и все слова, работающие с полями), но часто не могут быть применены к словам некоторых видов.
- ХАКИНГА-ДАННЫХ - обычные слова обращения к памяти. Это, как раз, путь, "рекламируемый" микро-фортерами: получаем адрес нужного поля и при помощи обычных слов обращения к памяти производим все нужные манипуляции.
- ХАКИНГА-КОДА - это наши "создаватели неправильных слов". При помощи встроенного ассемблера, способные вставить в нужные слова свой код.
Куча подводных камней. Место кода иногда трудно доступно: поле часто содержит лишь ссылку на него, а сам код - в специальном сегменте памяти, недоступном обычным словам работы с памятью. Или, наоборот, код прямо забит в поле, и вписать туда "еще что-нибудь" невозможно - нет места...

Ввести какие-то общие правила для всех этих слов невозможно. В каждой FORTH-системе все по-своему. Но это не значит, что в них не надо разбираться. Наоборот!
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Компилирующие слова Empty Re: Компилирующие слова

Сообщение автор Gudleifr Чт Окт 26, 2017 3:54 pm

ПРИМЕР ПЕРЕХОДА ОТ ПОЛЯ К ПОЛЮ

Маленькая хитрость. Рано или поздно начинается геморрой с организацией своей собственной строковой памяти. Вспомните того же Rodriquez. Но, ведь в FORTH такая память есть по умолчанию - это его словарь! Конечно, он хранит только константы без пробелов, но для подавляющего количества программ работы с данными этого вполне достаточно. Слово создания таких строковых констант выглядит очень просто (в Win32Forth):

: SD ( <NAME> -- A) HERE CREATE >NAME DUP , DOES< ( -- A) @ ;

Дополнительный вывод адреса при создании константы сделал для того, чтобы сразу вставить строку в структуры данных.
Т.е. создаются слова, возвращающие свое собственное имя.
Более того, если вы сами пишете свой FORTH, то написать CREATE" для создания слов с пробелами, переназначить ввод для изготовления слов-строк на лету и/или организовать через FORGET очистку строковой памяти - пара пустяков.
Gudleifr
Gudleifr
Admin

Сообщения : 3245
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения