В новом билде кварка (build 32) в экспериментальных целях реализован новый механизм локальных объявлений. Механизм реализуется некоторой модификацией слов : ; и добавлением слов LOC[ ]LOC (обрамляющих область локальных объявлений). Дополнительно введен стек, названный пока за отсутствием мыслей о более точном термине стеком контекста компиляции. Как это работает: при начале определения нового слова состояние словаря CURRENT запоминается на вот этом самом стеке.
Слово LOC[ выполняет следующее:
- устанавливает ссылку вперед (запоминая адрес опять же на стеке контекста компиляции);
- переключает Форт в режим исполнения.
Слово ]LOC:
- разрешает ссылку вперед;
- устанавливает режим компиляции.
Слово ; дополнительно восстанавливает словарь CURRENT в состояние, забираемое со стека контекста компиляции.
Все. Если теперь работать с обычным определением, то пара : ; просто лишний раз забросит [CURRENT] на стек и снимет его оттуда. Никаких изменений в словаре при этом не происходит. Зато если внутри блока LOC[ ]LOC (напоминаю, внутри действует режим исполнения) определить дополнительные слова, то они добавляются в словарь (и вообще компилируются со всеми вытекающими последствиями), но слово ; ...
исключит их из поиска, вернув состояние, в котором начиналась компиляция "объемлющего" слова! Иными словами, все, что определено в блоке LOC[ ]LOC, доступно только для слова, в котором этот блок определен, т.е. представляет собой локальные объекты.
Код:
VARIABLE X
1 X !
: TEST
LOC[
VARIABLE X
: R 2 2 + . ;
]LOC
5 X !
X @ .
R
;
TEST
X @ .
Вывод этого кода: 5 4 1.
Особенностью (не пишу "недостатком") такого механизма является невозможность использования рекурсии: локальные переменные вовсе не создаются каждый раз при входе в слово. Просто для них выбираются фиксированные адреса, которые имелись в распоряжении компилятора в момент создания "объемлющего" определения. Там эти объекты и оказываются. Плюсом является возможность компиляции внутри слова чего угодно - обращаю внимание на наличие в примере локального определения R, которое при выходе оказывается недоступным (оно существует в словаре, но его Link не включен в цепочку поиска).
Build 32 пока не выложен, поскольку не все желаемое еще добавлено.