Всвязи с тем, что тема уже не однократно поднималась, и мне уже не одному пришлось лично объяснять, как можно более удобно работать со словарями, решил завести отдельную тему.
Для начала небольшой экскурс.
Словари в Форте удобны тем, что можно в них упрятывать имена, удобным образом их группировать. При этом работа со словарями достаточно громоздка:
VOCABULARY SAMPLE
ALSO SAMPLE DEFINITIONS
....
PREVIOUS DEFINITIONS
так выглядит классический метод использования словарей. То есть создается словарь (в текущем словаре), он кладется на вершину контекста, делается текущим, после чего добавляются необходимые определения, и словарь "закрывается" то есть удаляется из контекста, и текущим делается предыдущий словарь.
Понятно, что в случае необходимости использования слов из какого-либо словаря его необходимо положить в контекст, что иногда в коде выливается в следующую последовательность:
... [ ALSO VocName ] ImportName [ PREVIOUS ] ...
что встречается может и не часто, но достаточно неудобно.
Для решения этой проблемы существует несколько решений, к примеру в СПФ есть библиотека spf_modules.f (есть и другие).
Проблема как всегда в том, чтобы не усложняя сильно реализацию, предоставить удобный и полезный интерфейс, который бы однозначно работал и следовал духу Форта.
Далее предлагается следующий синтаксис:
Unit: VocName \ создать словарь с именем VocName сделать его текущим и контекстным,
\ то есть все слова после его определения пойдут уже в словарь VocName
Sub Unit: NestedVoc \ создать вложенный словарь с именем NestedVoc
: simple ." простое имя не влияющее на контекст" ;
F: recoil ." имя со сложным поведением, влияющее контекст" ;F
EndUnit
EndUnit
итак, далее вне зависимости от состояние переменной STATE поведение слов будет одинаковым. Последовательность:
... VocName NestedVoc simple recoil ...
приведет к вызову(либо компиляции в зависимости от STATE) слов simple recoil из вложенного словаря, при этом, контекст на выходе окажется неизменным. Иными словами словари становятся словами немедленного исполнения и откаты [ PREVIOUS ] происходят автоматически при использовании слов, определенных через F: ... ;F , причем глубина отката определяется тем, было ли перед Unit: указано Sub.
\ 21.02.2009 ~mOleg (уже не помню какая редакция - много их было!)
\ Сopyright [C] 2009 mOleg mininoleg@yahoo.com
\ работа с вложенными словарями
math/ useful.fts
branch/ handlers.fts
ALSO HIDDEN DEFINITIONS
VOCABULARY UNITS
UNITS DEFINITIONS
USER chain
\ в зависимости от состояния системы либо исполнить указанное слово,
\ либо добавить его в текущее определение
\ удалить верхний словарь из контекста
: using ( xt --> ) PREVIOUS
state IF COMPILE, ELSE EXECUTE THEN ;
\ начать создание метода с указанным именем asc #
: (F) ( asc # --> ) S: [COMPILE] <: ;
\ создать словарь-контейнер с указанным именем
: container ( asc # --> vid )
DDUP <| [CHAR] ( KEEP KEEPS [CHAR] ) KEEP |> SVOCAB
ALSO LATEST LINK>C EXECUTE CONTEXT A@ PREVIOUS A>L
CREATED 0 chain CHANGE , AL@ A, IMMEDIATE
['] L> >R
DOES> DUP @ IFNOT ALSO THEN
CELL + A@ WITH ;
ALSO FORTH THIS
\ сообщает о логической вложенности контейнера
: Sub ( --> ) chain ON ;
\ создать контейнер, перенаправить компиляцию в него
: Unit: ( / name --> )
NEXT-WORD container
ALSO WITH DEFINITIONS ;
\ завершить работу с контейнером, откатить контекст на предыдущее состояние,
\ вернуть текущий словарь
: EndUnit ( --> ) RECENT ;
\ начать описание метода
: F: ( / name --> ) NEXT-WORD (F) ;
\ завершить описание метода
: ;F ( --> )
[COMPILE] ;> COMPILE using
[COMPILE] ; IMMEDIATE
; IMMEDIATE
RECENT