Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Язык программирования (и ОС) ФОРТ (FORTH) 0004: целевой компилятор


Информационный Канал Subscribe.Ru

0004: целевой компилятор

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

Целевой комилятор (ЦК) -- расширение форт-системы, превращающее ее в
ассемблер и кросс-компилятор.

Основной принцип -- создается буфер

0x10000 CONSTANT Msz          \ максимальный размер программы
CREATE M Msz CELLS ALLOT      \ буфер
0 VALUE THERE                 \ указатель компиляции (на свободный элемент)

Слово
: CELLS ( n -- n*cell)   CELL * ;
берет со стека число элементов и умножает на размер элемента в байтах.

В таком виде и при использовании 32-битной форт-системы типа
SP-FORTH http://spf.sf.net будет генерироваться 32-битный байт-код.
Если вы хотите переключить ЦК в 16-битный режим, перед загрузкой ЦК или
перед переопределением CELLS нужно задать строку

2 CONSTANT CELL

Для сохранения байт-кода в файл определяем слово

: save" \ program"
\ сохранить байт-код в файл program и выйти из форт-системы
     [CHAR] " WORD COUNT W/O CREATE-FILE DROP ( fh )
     M THERE CELLS ROT ( M THERE*CELL fh ) WRITE-FILE DROP BYE
;

Для чтения и записи чисел в буфер ЦК определяем слова

: cell! ( n addr -- ) CELLS M + CELL 2 = IF W! ELSE ! THEN ;
: cell@ ( addr -- n ) CELLS M + CELL 2 = IF W@ ELSE @ THEN ;

которые записывают и читают n по смещению addr от начала M. При этом
проверяется значение CELL и выбирается соответствующий вариант чтения/записи
памяти форт-системы (чтение/запись 32- или 16-битного слова).

Осталось определить слово

: cell, ( n -- )  THERE cell! THERE 1+ TO THERE ;

компилирующее n в конец уже скомпилированного байт-кода.

В таком варианте уже можно использовать ЦК:

test.4th
=================================
\ 2 CONSTANT CELL \ раскомментировать для генерации 16-битного байт-кода
S" tc.spf" INCLUDED
0x1234 cell, 0x5678 cell,
save" test.bc"
=================================

и должен получиться файл test.bc
=================================
34 12 00 00 78 56 00 00
=================================

Теперь нам нужно определить набор слов, компилирущих управляющие конструкции.
Для этого сначала нужно определеить несколько команд.

Сначала используя CREATE DOES> определим слова

: 0op          CREATE , DOES> @ cell, ;           \ команда 
: 1op ( n )    CREATE , DOES> @ cell, cell, ;     \ команда  

затем определяем несколько команд (описание см. выпуск [0003])

0x00 0op nop
0x01 1op jmp        0x02 1op ?jmp       0x03 1op call       0x04 0op ret
0x05 1op lit
0x06 0op exec

0x08 0op do         0x09 0op loop
0x0A 0op i          0x0B 0op j          0x0C 0op k

и управляющие структуры (подробное описание по запросу)

1 CONSTANT _entry   \ см. стартовый код далее

: {            CREATE THERE , THERE _entry cell! DOES> @ call ;
: }            ret ;
: const        CREATE ( n ) , DOES> @ lit ;
: var          CREATE THERE , ( n ) cell, DOES> @ lit ;
: begin        THERE ;
: again        jmp ;
: until        ?jmp ;
: while        -1 ?jmp THERE 1- ;
: repeat       SWAP jmp THERE SWAP cell! ;
: if           -1 ?jmp THERE 1- ;
: then         THERE SWAP cell! ;
: else         -1 jmp THERE 1- SWAP then ;

остальные команды (полную версию см. http://akps.ssau.ru/forth/tiny/tc.spf)

0x10 0op dup        0x11 0op drop       0x12 0op swap       0x13 0op over

0x20 0op fetch      0x21 0op store

0x30 0op add        0x31 0op sub        0x32 0op mul        0x33 0op div

0x40 0op less       0x41 0op great      0x42 0op eq         0x43 0op noteq

0x60 0op key        0x61 0op emit       0x62 0op print      0x63 0op dot

0x70 0op sdot
                                                            0x7F 0op bye

Слово { при своем выполнении переопределяет точку запуска программы на
последнее определенное через { } слово, модифицируя стартовый код:

\ start-up код
-1 jmp    \ jmp entry

Константа _entry задает адрес параметра команды jmp

Все, это весь компилятор (ассемблер) для tinyVM 8-)

Основную сложность в понимании того, как работает этот ЦК, имеют слова
управляющих конструкций -- советую переписать их самостоятельно, чтобы понять
как они работают.

код1 begin код2 again код3

должен компилироваться в

               код1
begin-addr:
               код2
               jmp begin-addr
               код3

(для сохранения адресов типа begin-addr используйте стек)

код1 begin код2 until код3

               код1
begin-addr:
               код2
               ?jmp begin-addr
               код3

код1 if код2 else код2 then код4

               код1
if-addr:
               ?jmp else-addr
               код 2
               jmp then-addr
else-addr:
               код3
then-addr:
               код4

(компилировать ?jmp и jmp с фиктивным адресом типа -1, запомнив адрес
параметра команд (?)jmp на стеке, а в словах else и then использовать
сохраненные адреса параметров для их изменения на реальные адреса)

код1 begin код2 while код3 repeat код4

               код1
begin-addr:
               код2
               ?jmp repeat-addr
               код3
               jmp begin-addr
repeat-addr:
               код4

{ someword код }

{ создает в словаре форт-системы слово

: someword <значение THERE при исполнении {> call ;

которое при своем выполнении компилирует команду call 

Фактически { запоминает текущую позицию компиляции, создав слово, которое
скомпилирует CALL на эту позицию.

К сожалению написать create does> для целевого компилятора мне не удалось 8-(,
но пока в этом нет необходимости.

При использовании ЦК можно пользоваться двумя вариантами определения новых
слов:

: macroword    код1 ;
{ tcword       macroword код2 macroword }

Слово macroword при этом определяется как макрос, и компилируется в целевой
код inline, а слово tcword компилируется как процедура:

tcword:
               код1
               код2
               код1
               ret

Теперь если вы хотите полностью понять, как это работает, и научиться
пользоваться tiny, советую скачать SP-FORTH или другую форт-систему
соответствующую стандарту ANS FORTH '94, полную версию движка, целевого
компилятора и примеров с http://akps.ssau.ru/forth/tiny/ и полностью
переписать движок (лучше на любом другом языке или ассемблере) и ЦК так, чтобы
примеры работали.

Если возникают какие-то вопросы, или что-то не получается, обязательно
свяжитесь со мной, и в следующих выпусках рассылки ваши вопросы будут
расжеваны более подробно и с примерами.

PS: для работы ЦК необходима регистро-зависимая форт-система,
считающая слова SOMEWORD и someword разными словами

================
http://akps.ssau.ru
forth@km.ru
FidoNet SU.FORTH 2:5057/18.29
tel.: +7 8462 28 9910 (work), 15 4313 (home)

Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.forth
Отписаться
Вспомнить пароль

В избранное