A вот и получившийся "крокодил" с метками:
\
\
\ определения для работы с метками
\
\ описание слов
\ 1. NEW-LABEL - определяет имя для новой метки
\ USE: NEW-LABEL label-name
\ каждая новая метка получает уникальный идентификатор, и для нее заводится запись в таблице определенных меток
\ для слова label-name определяется действие, по которому на стек кладется идентфикатор метки
\ 2. COMPILE-LABEL ( id-label --> ) метка компилируется в целевую память и ссылка на место,
\ куда она компилируется, помещается в таблицу неопределенных меток
\ 3. SET-LABEL (id-label, addr --> ) в таблицу определенных меток для указанной метки записывается адрес
\ 4. RESOLVE-LABELS - производится разрешение всех меток -
\ по таблице неопределенных меток находятся адреса, куда надо размещать метки,
\ а сами метки берутся из таблицы определнных меток
\ если используемая метка оказалась неопределена - выдается *** ERROR ***
\ если же не используется некая объявленная метка, то
\ ( выдается только слабый --- warning --- ) не выдается!
\ в коде все метки оказываются неопределенными
\ к концу исходника программы всех их надо определить и вызвать RESOLVE-LABELS
\ настроечные константы
10 CONSTANT MAX-LABELS-NUM \ максимальное число использованных меток
100 CONSTANT MAX-LINK-NUM \ максимальное число ссылок на метки
\ размеры таблиц меток
\ MAX-LABELS-NUM CELLS CONSTANT DEF-TABLE-SIZE \ определенных
\ MAX-LINK-NUM CELLS CONSTANT UDEF-TABLE-SIZE \ неопределенных
\ создание таблиц
CREATE DEF-LABEL-TABLE MAX-LABELS-NUM CELLS ALLOT \ определенных меток
CREATE UDEF-LABEL-TABLE MAX-LINK-NUM CELLS ALLOT \ неопределенных меток
\ value переменные с числом использованных позиций в таблицах
VALUE UDEF-LABELS 0 TO UDEF-LABELS \ неопределенных ссылок
VALUE DEF-LABELS 0 TO DEF-LABELS \ определeнных меток
\ организация новой записи в таблице неопределенных меток
: NEXT-UDEF \ --> addr - на выходе адрес для записи данных в таблицу
UDEF-LABELS
DUP 1+ TO UDEF-LABELS
DUP MAX-LINK-NUM = IF ." --- ERROR! достигнут предел количества использованных ссылок на метки --- " CR THEN
CELLS UDEF-LABEL-TABLE + \ полученный адрес выдается наружу --> PLACE-IN-TABLE
;
\ организация записи в таблице определенных меток и выдача ее номера как id-label
: NEXT-ID \ -- id-label - на выходе номер новой определенной метки
DEF-LABEL-TABLE DEF-LABELS CELLS + \ место для размещения записи
-1 SWAP ! \ положить значение -1 в запись - означает, что метка не определена
DEF-LABELS \ id-label
DUP 1+ TO DEF-LABELS \ подготовка для следующей метки
DUP MAX-LABELS-NUM =
IF ." --- ERROR! достигнут предел количества используемых меток --- " CR THEN
;
\ объявление новой метки - создание константы со следующим номером id-label
: NEW-LABEL NEXT-ID CONSTANT ;
\ установить значение метки по id-label
: SET-LABEL \ data,id_label -->
CELLS DEF-LABEL-TABLE + \ адрес размещения метки в таблице
DUP @ -1 <> IF ." --- ERROR! метка уже была определена --- " CR THEN
SWAP 0FFFF AND SWAP ! \ установить!
;
\ компилировать метку в целевую память - компилируется id-label
\ а в таблицу неопределенных меток заносится адрес, куда надо вписывать метку и ее id
: COMPILE-LABEL \ id_label -->
THERE OVER T, \ компиляция метки в целевую память
10000 * + \ вычисляется значение для записи в таблицу - (id_label * 65536) + addr
NEXT-UDEF \ новый адрес в таблице неопределенных меток
! \ запись в таблицу неопределенных меток
;
\ разрешение всех меток
: RESOLVE-LABELS
UDEF-LABELS 0 DO \ цикл по всем записям ссылок на метки
I CELLS UDEF-LABEL-TABLE + @ 10000 / \ получить id_label для метки
\ получить запись определенной метки
CELLS DEF-LABEL-TABLE + @ DUP -1 =
IF ." --- ERROR! используемая метка не определена ---" THEN
0FFFF AND \ выделить значение метки
\ получить адрес для размещения метки
I CELLS UDEF-LABEL-TABLE + @ 0FFFF AND
2 * TW! \ поместить метку в целевую память
LOOP
;
Сначала объявляются все метки... Вернее, они объявляются в процессе их появления в исходнике.
В исходнике они используются независимо от того, где определены, в начале или в конце, перед реальным использованием или после.
Когда исходник завершен, вызывается слово, разрешающее сразу все метки.
Получается компиляция один проход, во время которого "собирается" таблица ссылок, по которой затем в скомпилированный код вписываются нужные адреса...
Установкой двух констант регулируется количество используемых меток и ссылок на них.
Формально, можно вписать в эти константы большие числа, но тогда... э... ну, почти ничего не произойдет, пока компилятор работает на компьютере "с бесконечной память", если компилятор потом на самой встроенной системе с EQUINOX запускать, то регулировка количества используемых меток очень даже нужна.
п.с. ...код отлажен лишь частично...