Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Чт окт 18, 2018 02:34

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
 Заголовок сообщения: [BF] структуры управления в старом ЦК
СообщениеДобавлено: Вс июн 03, 2007 10:38 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Код:
\ структуры управления

: {      THERE _entry cell! CREATE THERE , DOES> @ call ;
: }      ret ;

: if      -1 ?jmp THERE _cell - ;
: endif      THERE SWAP cell! ;
: else      -1 jmp THERE _cell - SWAP endif ;

: begin      THERE ;
: again      jmp ;
: until      ?jmp ;
: while      if ;
: repeat   SWAP jmp THERE SWAP cell! ;

: const  ( n )   CREATE ( n ) ,                      DOES> @ lit ;
: var    ( n )   CREATE THERE , ( n ) cell,          DOES> @ lit ;
: buffer ( n )   CREATE THERE , ( n ) 0 DO 0 b, LOOP DOES> @ lit ;

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: [BF] структуры управления в старом ЦК
СообщениеДобавлено: Вс июн 03, 2007 10:48 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
forth@km.ru писал(а):
Код:
: {      THERE _entry cell! CREATE THERE , DOES> @ call ;
: }      ret ;


Эти два слова используются для определения слов (процедур) в целевом коде (vs макросы определенные как обычно через : ; и компилирующиеся в целевой код inline).

Код:
THERE _entry cell!
берет текущее значение указателя ЦК, и патчит параметрт стартого jmpа в стартовом коде (см. самый конец исходника цк), устанавливая точку входа программы на определяемое через { } слово. Учтите что словарная структура в целевом коде не создается, так что это значение фактически является CFA нового слова. Если все же понадобится создание словарной структуры, слово HEADER, компилирующее заголовок словарной статьи, должно выполняться до этого кода.

Код:
CREATE THERE , DOES> @ call
в словаре инструментальной форт-системы (в нашем случае это SPF) создается CREATE-DOESнутое слово с именем слова, которое мы сейчас определяем через { }. Это слово при своем выполнении будет компилировать команду call на запомненное текущее значение THERE.

Таким образом, когда при работе ЦК мы выполняем (в режиме интерпретации) слово { NEWWORD. оно добавляет в ЦК слово NEWWORD, которое уже в свою очередь будет компилировать call на текущий адрес.

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 10:50 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
совсем по-простому: словом { NEWWORD мы добавляем в ЦК слово NEWWORD компилирующее call на значение THERE в момент своего создания,
} вообще тупо компилирует ret.

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 10:57 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
С реализацией конструкций типа if/else/endif все очень запутанно. Если кратко, то используется принцип -- в местах где нам нужно скомпилировать безусловный или условный переход, компилируем фиктивный (?)jmp 0xFFFF(FFFF) , запоминая в стеке данных адрес параметра этого (?)jmpа. Далее в процессе работы ЦК мы выясняем необходимые реальные значения этого параметра, и патчим параметры ранее скомпилированных jmpов (так называемая методика backpatching, используется практически во всех однопроходных компиляторах).

_________________
http://akps.ssau.ru/forth/


Последний раз редактировалось forth@km.ru Вс июн 03, 2007 11:03, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 10:59 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
чтобы врубиться в работу слов типа if else begin while ... имхо лучше всего посмотреть в какой код компилируются эти конструкции, и попытаться реализовать их самостоятельно (в итоге получится практически тот же самый код что и у меня 8-)

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:02 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
код
Код:
... z1 ( n1 n2 n3 flag ) if z2 endif z3 ...

скомпилируется в байт-код
Код:
     ...
     z1 ( n1 n2 n3 flag )
@IF: ?jmp 0xFFFF --patched--> label@ENDIF \ здесь работало слово if компилируя фиктивный jmp
     z2
label@ENDIF: \ здесь работало слово endif которое взяло THERE=label@ENDIF и пропатчило фиктивный jmp
     z3
     ...

_________________
http://akps.ssau.ru/forth/


Последний раз редактировалось forth@km.ru Вс июн 03, 2007 11:10, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:09 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
код
Код:
... z1 if z2 else z3 endif z4 ...

компилится более сложно:
Код:
     ...
     z1
@IF: ?jmp 0xFFFF --patched--> @ELSE \ скомпилилось ifом
     z2
     jmp 0xFFFF --patched--> @ENDIF \ это
@ELSE:  \ и это скомпилилось elseом, на стеке данных была подмена адресов для endifа
     z3
@ENDIF: \ отработал endif но пропатчил не ifный ?jmp а elseный jmp (адреса параметров на стеке были подменены elseом)
     z4
     ...

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:14 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Код:
.... z1 begin z2 again z3 ...
проще всего:
Код:
     ...
     z1
@BEGIN:
     z2
@AGAIN: jmp @BEGIN
     z3
     ...

никакого геморроя -- тупо взяли адрес, положенный begin, и скомпилили на него jmp

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:16 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
совсем просто реализуются циклы do/loop:

Код:
.... z1 ( n1 n2 ) do z2 i z3 loop z4 ...


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

Код:
     ...
     z1
( n1 n2 ) do
     z2
     i
     z3
loop
     z4
     ...

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:19 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Код:
... z1 begin z2 ( flag ) while z3 repeat z4 ...
компилится в
Код:
     ...
     z1
@BEGIN: \ begin положил адрес
     z2
( flag )
@WHILE: ?jmp 0xFFFF --patched--> @REPEAT \ while положил адрес и скомпилил фиктивный ?jmp
     z3
jmp @WHILE \ это
@REPEAT: \ и это скомпилил repeat используя со стека адреса положенные begin и while
     z4
     ...

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:24 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
и наконец аналогично
Код:
.... z1 begin z2 ( flag ) until z3 ...
компилится в
Код:
     ...
     z1
@BEGIN:
     z2
( flag )
@UNTIL: ?jmp @BEGIN
     z3
     ...

как и с begin/again никаких фиктивных jmpов, компилим
Код:
?jmp @BEGIN
и все

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:27 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
ну и структуры управления.
если словарную структуру не создаем, то делаем просто:
константы реализуем как CREATE-DOES слова, в целевой код компилируем литералом inline:
Код:
: const  ( n )   CREATE ( n ) ,                      DOES> @ lit ;

код
Код:
0x1234 const KDSKSDKJ

.... z1 ... KDSKSDKJ ... z2 ...
компилится
Код:
....
z1
....
lit 0x1234
...
z2
...

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:31 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
переменные -- компилируем в байт-код начальное значение, его адрес запоминаем через CREATE-DOES,
Код:
: var    ( n )   CREATE THERE , ( n ) cell,          DOES> @ lit ;
при упоминании имени переменной в коде
Код:
0x1234 var SDKJSDJ

.... z1 ... SDKJSDJ @ ... z2 ...

компилируем запомненный адрес переменной литералом:
Код:
...
@SDKJSDJ: dcell 0x1234
...
z1
...
lit @SDKJSDJ
@
...
z2
...

_________________
http://akps.ssau.ru/forth/


Последний раз редактировалось forth@km.ru Вс июн 03, 2007 11:38, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:36 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
буфер
Код:
: buffer ( n )   CREATE THERE , ( n ) 0 DO 0 b, LOOP DOES> @ lit ;
запоминаем адрес (текущее значение THERE), компилим n нулевых байт, при упоминании имени буфера компилим литерал адрес буфера
Код:
512 buffer FLOPPY_SECTOR
... z1 ... FLOPPY_SECTOR ... z2 ...
компилится в
Код:
...
@FLOPPY_SECTOR: db 0 times 512
...
z1
...
lit @FLOPPY_SECTOR
...
z2
...

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июн 03, 2007 11:48 
Не в сети

Зарегистрирован: Сб май 06, 2006 18:43
Сообщения: 400
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Ну все, получили самый маленький язык программирования, теперь можно на этом рисовать программки.
Для удобства надо еще добавить многозадачность (хотя бы параллельное выполенние нескольких нитей -- адресное пространство кода и данных одно и то же, но для каждой нити отдельные стеки).
Так вот при запуске таких нитей нам нужно будет для команды ( cfa-addr ) thread ( pid ) указывать адрес слова, с которого будет стартовать потом нить командой ( pid ) start ( -- ) .
Для этого нам в ЦК нужно слово ['] которое будет каким-то образом лезть внутрь CREATE-DOES {слова} и вытаскивать из него адрес, который это {слово} использует при компиляции call {слово-addr}.
Самым простым мне показалось сначала дать этому {слову} отработать, то есть скомпилить call, а потом пропатчить этот call заменив на lit. Чтобы сохранить традиционный префиксный синтаксис ['] , используется поиск имени {слова} по словарю и запуск еще через EXECUTE, хотя более красивым и простым было бы использование постфиксной формы.
Код:
: [']      
     BL WORD FIND IF EXECUTE ELSE ABORT THEN \ лезем в поток SOURCE выцепляя имя, делаем поиск и запуск (или аборт)
     0x05 ( lit-op) THERE _cell - ( call-op-addr ) b! \ патчим опкод call на опкод lit
;

_________________
http://akps.ssau.ru/forth/


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB