Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Чт мар 28, 2024 15:03

...
Google Search
Forth-FAQ Spy Grafic

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




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: Снятие ограничений на использование управляющих констукций
СообщениеДобавлено: Пт сен 01, 2006 22:55 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
Автор: mOleg
дата первой публикации на forthwiki 01-03-2002

Снятие ограничений на использование управляющих констукций.


Preface.
Предназначено для снятия ограничений с операторов управления, как то: Begin While Repeat, If Else Then и прочих - на использование вне ':' ';', то есть в состоянии исполнения.

Абстракт.

Довольно часто бывает так, что нужно, например в цикле, провести какой-нибудь тест, предвычисление или сделать тот или иной выбор, заполнить массив осмысленными данными при его создании, создать за ряз ряд "похожих" Does> слов. Обычно такая необходимость предполагает порождение лишних определений, которые в последствии засоряют словарь и к тому же совсем не нужны в самой программе. Методы избавления от таких слов существуют, но они неудобны и занимают много времени. Например можно сделать так:
<pre>
: Test ( --> n ) Begin .... While .... Repeat
Abort" Unit not available!" ;
Test
Forget Test
</pre>
Возможен и вариант с Marker-ами или с Noname: - ами. И если вариант с маркерами просто дольше выполняется, то вариант с Noname: засоряет память а в некоторых системах и словарь, что в свою очередь вызывает замедление поиска слов в словаре и тоже сказывается на скорости работы системы в целом и ее размере. Кроме того, если после такого ненужного слова будет определено уже нужное, то ни один из перечисленных методов не пройдет.

Реализация.
Механизм работает следующим образом: при выполнении одного из слов, начинающих управляющую структуру, в режиме интерпретации система переводится в состояние компиляции до тех пор, пока не встретится закрывающая часть конструкции, после чего собранная конструкция исполняется.
Данная библиотека предополагает решение за счет введения системы в режим компиляции после встречи слов: If, IfNot, Begin, Do, ?Do, Case, Switch и перевода системы в режим интерпретации (точнее переводя систему в предыдущее состояние) после слов Then, Again, Until, While, Loop, +Loop,EndCase, EndSwitch, закрывающих первые.
Для того, чтобы не мешать выполнению полученного таким путем слова, сборка должна быть проведена не на here, куда в последствии могут попасть результаты работы этого слова, а во временном буфере, который может быть безболезненно удален по завершении исполнения полученного таким оборазом участка кода.

Реализация не предполагает сильного изменения самого интерпретатора и более того переписывания всех слов, завязанных на State, а так же создания более сложных правил поведения привычных слов: снаружи все должно выглядеть, как раньше.

Область применимости.
Не следует путать поведение слов IF и [IF] - первое вызывает компиляцию кода, вплоть до завершающего THEN, то есть автоматически переводит компилятор в режим компиляции, а по-завершении THEN возвращает систему в режим интерпретации и вызывает выполнение скомпилированного кода, в то время как [IF] управляет потоком трансляции. Таким образом следующий текст не вызовет ошибки трансляции:
0 [IF] простой пример многострочного коментария [THEN]
а следующий текст:
0 IF недопустимый текст внутри конструкции ветвления THEN
вызовет ошибку, на первом же неопознанном слове, то есть на слове: 'недопустимый'.

текст решения для СПФ.
Код:
содержимое файла devel\~moleg\lib\util\run.f
\ 02-06-2007 ~mOleg
\ Copyright [C] 2007 mOleg mininoleg@yahoo.com
\ поддержка временного буфера для создания безымянных временных слов

REQUIRE ADDR     devel\~moleg\lib\util\addr.f
REQUIRE ON-ERROR devel\~moleg\lib\util\on-error.f
REQUIRE IFNOT    devel\~moleg\lib\util\ifnot.f

        \ переменная для контроля парности открывающих и закрывающих слов
        USER controls ( --> addr )

        \ размер временного буфера для сборки слов мимо кодофайла
        0x4000 CONSTANT #compbuf ( --> const )

        \ адрес временного буфера
        USER-VALUE CompBuf ( --> addr )

        \ переменная для временного хранения адреса DP из CURRENT
        USER save-dp ( --> addr )

\ восстановить системные переменные
: rest ( --> )
       save-dp A@ DP A!
       0 controls !
       [COMPILE] [ ;

\ начать компиляцию во временный буфер
: init: ( --> )
        0 controls A!
        HERE save-dp A!
        CompBuf IFNOT #compbuf ALLOCATE THROW TO CompBuf THEN
    ['] rest ON-ERROR
        CompBuf DP A!
        ] ;

\ закончить компиляцию во временный буфер, выполнить его содержимое
\ восстановить состояние системных переменных
: ;stop ( --> )
        RET,
    EXIT-ERROR rest
        CompBuf EXECUTE ;

\ пока так
\ при входе в определение переменная controls увеличивается на 1
\ при выходе из определения - уменьшается на 1
: : 1 controls ! : ;
: ; controls @ 1 = IFNOT -22 THROW THEN  0 controls ! [COMPILE] ; ; IMMEDIATE

содержимое файла devel\~moleg\lib\util\control.f
\ 19-04-2007 ~mOleg
\ Copyright [C] 2007 mOleg mininoleg@yahoo.com
\ структуры управления: ветвления и циклы
\ можно использовать даже во время исполнения.

REQUIRE ?DEFINED devel\~moleg\lib\util\ifdef.f
REQUIRE IFNOT    devel\~moleg\lib\util\ifnot.f
REQUIRE ;stop    devel\~moleg\lib\util\run.f

\ Начало ветвления. Код за словом IF выполняется в случае, если flag <> 0
: IF ( flag --> )
     STATE @ IFNOT init: THEN
     2 controls +!
     HERE ?BRANCH, >MARK 1 ; IMMEDIATE

\ Альтернативное ветвление. Код за else выполняется в случае, если
\ пропущен код за основным: IF или IFNOT ветвлением.
: ELSE ( --> ) ?COMP HERE BRANCH, >RESOLVE  >MARK 2  ; IMMEDIATE

\ Описатель начала цикла. На код за словом BEGIN передается управление
\ в случае повторений цикла
: BEGIN ( --> )
        STATE @ IFNOT init: THEN
        2 controls +!
        <MARK 3 ; IMMEDIATE

\ возврат без условий на точку BEGIN. Отмечает конец кода бесконечного цикла.
: AGAIN ( --> )
        ?COMP -2 controls +!
        3 = IFNOT -2006 THROW THEN  BRANCH,
        controls @ IFNOT ;stop THEN ; IMMEDIATE

\ Возврат на точку после BEGIN если flag <> 0 (цикл с постусловием)
: UNTIL ( flag --> )
        ?COMP -2 controls +!
        3 = IFNOT -2004 THROW THEN ?BRANCH,
        controls @ IFNOT ;stop THEN ; IMMEDIATE

\ условный выход из цикла, если flag = 0
\ используется между BEGIN и REPEAT, отмечающими начало и конец цикла
: WHILE ( flag --> )
        ?COMP 2 controls +!
        HERE ?BRANCH, >MARK 1 2SWAP ; IMMEDIATE

\ условынй выход из цикла, если flag <> 0. Используется аналогично WHILE
: WHILENOT ( flag --> )
           ?COMP 2 controls +!
           HERE N?BRANCH, >MARK 1 2SWAP ; IMMEDIATE

\ безусловный возврат на BEGIN. Используется вместе с BEGIN и WHILE
: REPEAT ( --> )
         ?COMP -4 controls +!
         3 = IFNOT -2005 THROW THEN BRANCH, >RESOLVE
         controls @ IFNOT ;stop THEN ; IMMEDIATE

\ Начало ветвления. Промежуточное имя.
: ifnot ( flag --> )
        STATE @ IFNOT init: THEN
        2 controls +!
        HERE N?BRANCH, >MARK 1 ;

\ Конец ветвления. На точку за THEN переходит управление после выполнения
\ одной из альтернатив, то есть кода после IF IFNOT или ELSE
: THEN ( --> )
       ?COMP -2 controls +!
       >RESOLVE
       controls @ IFNOT ;stop THEN ; IMMEDIATE

\ Начало ветвления. Код за словом IFNOT выполняется в случае, если flag = 0
: IFNOT ifnot ; IMMEDIATE


Последний раз редактировалось mOleg Вс окт 05, 2008 05:24, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт сен 01, 2006 23:03 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
Вообще, здесь можно модифицировать сам цикл интерпретации. Допустим, строка сначала компилируется во временный буфер, а потом исполняется. Причем любая строка. Получится цикл REFILL COMPILE EXECUTE


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт сен 01, 2006 23:15 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
Хищник писал(а):
Вообще, здесь можно модифицировать сам цикл интерпретации. Допустим, строка сначала компилируется во временный буфер, а потом исполняется. Причем любая строка. Получится цикл REFILL COMPILE EXECUTE


я так и хотел, но не стал. Кстати это можно использовать для оптимизации кода 8)
Так вот, я хотел еще разрешить и >R R> во время интерпретации.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб сен 02, 2006 00:24 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
/me когда-то для этого сделал себе пару слов << и >> все, что внутри двойных угловых скобок сначала компилилось, затем исполнялось..
И все...

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб сен 02, 2006 08:04 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
WingLion писал(а):
/me когда-то для этого сделал себе пару слов << и >> все, что внутри двойных угловых скобок сначала компилилось, затем исполнялось..
И все...


да, можно и так.
По сути так и сделано, только потом добавлено к каждому из управляющих слов 8)


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

Зарегистрирован: Ср май 03, 2006 11:27
Сообщения: 1394
Откуда: St.Petersburg
Благодарил (а): 2 раз.
Поблагодарили: 11 раз.
oleg писал(а):
а это вариант от mak


В http://wiki.forth.org.ru/%CD%E5%20%FF%E ... F%F6%E8%FF
Куда-то пропали : . Не пойму я этот wiki.

Код:
\ Снятие ограничений на использование управляющих констукций
\ в рамках стандарта

VARIABLE SAVE_SP
VARIABLE SAVE_DP
VARIABLE SAVE_AL

: DO-MDSW:
STATE @ 0=
      IF  99999 ALLOCATE THROW SAVE_AL !
          HERE SAVE_DP !
          SAVE_AL @ DP ! :NONAME
          SP@  SAVE_SP !

      THEN ;

: MDSW:
  :  POSTPONE DO-MDSW:
     ' COMPILE,
   POSTPONE ; IMMEDIATE ;

: DO-MDSW;
  SP@  SAVE_SP @ =
  IF 0 SAVE_SP ! POSTPONE ;
       SAVE_DP @ DP !   EXECUTE
       SAVE_AL @ FREE DROP
  THEN   ;

: MDSW;
  :  ' COMPILE,
      POSTPONE DO-MDSW;
  POSTPONE ;  IMMEDIATE ;

  MDSW: DO  DO
  MDSW: ?DO ?DO
  MDSW; LOOP LOOP
  MDSW; +LOOP +LOOP

  MDSW: BEGIN BEGIN
  MDSW; UNTIL UNTIL
  MDSW; AGAIN AGAIN
  MDSW; REPEAT REPEAT

\  TEST

HERE

5 0 DO I VALUE LOOP A B C D E

10 0 DO  I . LOOP CR
10 BEGIN  1- DUP
    WHILE  DUP 0 DO I . LOOP CR
    REPEAT .

A . B . C . D . E .

HERE U. U.


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

Зарегистрирован: Ср май 03, 2006 11:27
Сообщения: 1394
Откуда: St.Petersburg
Благодарил (а): 2 раз.
Поблагодарили: 11 раз.
oleg писал(а):
Так вот, я хотел еще разрешить и >R R> во время интерпретации.


Вернее во время неявной компиляции. У меня слова определенные через
MDSW: запускают слово :NONAME , которое устанавливает режим компиляции.
Слова определенные через MDSW; совершают условное завершение
неявной компиляции. Условием является уровень стека данных сохраненный
в переменной SAVE_SP . >R R> стек данных не меняют.

Можно явно запустить компиляцию во временный буфер словом DO-MDSW:
Однако, завершающее слово DO-MDSW; не имеет признака немедленного
исполнения. Из-за этого определим:
Код:
: ;MDSW DO-MDSW; ; IMMEDIATE

Пример
Код:
DO-MDSW: 5 >R ." XXX=" R> . ;MDSW


Еще не плохо добавить:
Код:
..: DECODE-ERROR SAVE_SP 0! ;..


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср ноя 26, 2008 12:21 
Не в сети
Аватара пользователя

Зарегистрирован: Вт сен 11, 2007 11:07
Сообщения: 187
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
почитал я спор Chess и mOleg в http://fforum.winglion.ru/viewtopic.php?t=1686,
увидел отсылку на эту ветку..... во всех предложенных схемах не будут работать
определяющие слова. т.о. польза представляется весьма сомнительной.

более корректно было-бы завести отдельный словарь (скажем - TRANSIENT или MACRO)
компилировать туда всё то, что не хочется сохранять в финальном образе системы и
не допускать компиляции слов из этого словаря вне этого словаря (раз уж в форке
mOleg числа и так являются словарём, то не стоило бы плодить сущностей.....).

p.s. разумеется, сам словарь должен быть в отдельном участке памяти.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср ноя 26, 2008 17:21 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
garbler писал(а):
почитал я спор Chess и mOleg

Так спора-то и не было. Я о лексемах-генераторах говорил, как их использовать в режиме интерпретации.
Причем здесь определяющие слова. Вся информация о коде, который лексема генерит зашита в наборе символов
самой лексемы в нем же зашита и отсылка к соответствующему этой лексеме транслятору(конкретному NOTFOUND).
Сохранять эти NOTFOUND по SAVE необходимо.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Чт ноя 27, 2008 00:20 
Не в сети
Moderator
Moderator
Аватара пользователя

Зарегистрирован: Чт май 04, 2006 00:53
Сообщения: 5062
Откуда: был Крым, теперь Новосибирск
Благодарил (а): 23 раз.
Поблагодарили: 63 раз.
garbler писал(а):
почитал я спор Chess и mOleg в http://fforum.winglion.ru/viewtopic.php?t=1686,
увидел отсылку на эту ветку..... во всех предложенных схемах не будут работать
определяющие слова. т.о. польза представляется весьма сомнительной.

ух ты, а я и не заметил ;)
Вы попробуйте, а потом говорите.

_________________
Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur


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

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


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

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


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

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