Forth
http://www.fforum.winglion.ru/

"атомарные" конструкции управления
http://www.fforum.winglion.ru/viewtopic.php?f=25&t=2100
Страница 1 из 3

Автор:  mOleg [ Пн май 04, 2009 22:06 ]
Заголовок сообщения:  "атомарные" конструкции управления

"атомарные" конструкции управления (или как их поправильнее назвать?)
для начала код:
\ 03.05.2009 ~mOleg
\ Сopyright [C] 2009 mOleg mininoleg@yahoo.com
\ "атомарные" ветвления и циклы

branch/ handlers.fts

\ Внимание! Все следующие слова не компилируют следующий токен самостоятельно,
\ поэтому не желательно использовать после него слова немедленного исполнения.
\ то есть те же ограничения использования, что и у слова COMPILE !!!

\ если flag отлично от нуля, выполнить следующий токен, находящийся в коде
\ за ift , иначе пропустить токен (смещает указатель интерпретации дальше)
: ift ( flag --> ) ?COMP <: IFNOT TOKEN R+ THEN ;> COMPILE, ; IMMEDIATE

\ если flag равно нулю, выполнить следующий токен, находящийся в коде за iff
\ иначе следующий токен не исполнять.
: iff ( flag --> ) ?COMP <: IF TOKEN R+ THEN ;> COMPILE, ; IMMEDIATE

\ если flag меньше нуля, выполнить следующий токен, иначе пропустить его
: ifn ( flag --> ) ?COMP <: -IF DROP ;THEN DROP TOKEN R+ ;> COMPILE, ; IMMEDIATE

\ если flag положительное число(или 0) выполнить следующий токен, скомпилированный
\ в коде за ifp, иначе токен обойти.
: ifp ( flag --> ) ?COMP <: -IF DROP TOKEN R+ ;THEN DROP ;> COMPILE, ; IMMEDIATE

\ выполнять следующий скомпилированный в коде токен до тех пор, пока число n
\ находящееся на вершине стека данных отлично от нуля. n снимается со стека только
\ в случае равенства нулю!
: whilet ( n --> ) ?COMP
<: *IF AR@ TOKEN@ EXECUTE [ TOKEN NEGATE ] LITERAL R+ ;THEN
DROP TOKEN R+
;> COMPILE, ; IMMEDIATE

\ выполнять следующий скомпилированный в коде токен до тех пор, пока n = 0
\ в случае значения отличного от нуля удаляется значение с вершины стека данных
\ и управление передается на следующий токен (то есть 3 по счету,
\ если считать от токена, компилируемого словом whilef
: whilef ( n --> ) ?COMP
<: *IF DROP TOKEN R+ ;THEN
AR@ TOKEN@ EXECUTE [ TOKEN NEGATE ] LITERAL R+
;> COMPILE, ; IMMEDIATE

\ выполнять в цикле следующий скомпилированный токен, находящийся в коде за
\ whilen до тех пор, пока значение n на вершине стека данных отрицательно
\ в случае невыполнения условия управление передается на следующий
\ за "зацикленным" токен
: whilen ( n --> ) ?COMP
<: -IF AR@ TOKEN@ EXECUTE [ TOKEN NEGATE ] LITERAL R+ ;THEN
DROP TOKEN R+
;> COMPILE, ; IMMEDIATE

\ выполнять в цикле следующий скомпилированный токен до тех пор, пока значение
\ n положительно (либо = 0), в случае невыполнения условия управление передается
\ дальше
: whilep ( n --> ) ?COMP
<: -IF DROP TOKEN R+ ;THEN
AR@ TOKEN@ EXECUTE [ TOKEN NEGATE ] LITERAL R+
;> COMPILE, ; IMMEDIATE

?ABSENT test{ \EOF -- тестовая секция ---------------------------------------
test{

: aaaa 938470 ;
: bbbb 670284 ;
: cccc DUP 1 - ;
: dddd DUP 1 + ;
: eeee DROP 1 - DUP DUP 0 = ;

: test-a DUP ift aaaa bbbb ;
0 test-a bbbb <> THROW THROW
234 test-a bbbb <> THROW aaaa <> THROW 234 <> THROW
: test-b DUP iff aaaa bbbb ;
0 test-b bbbb <> THROW aaaa <> THROW THROW
323 test-b bbbb <> THROW 323 <> THROW
: test-c DUP ifn aaaa bbbb ;
-2442 test-c bbbb <> THROW aaaa <> THROW -2442 <> THROW
123 test-c bbbb <> THROW 123 <> THROW
0 test-c bbbb <> THROW THROW
: test-d DUP ifp aaaa bbbb ;
-1543 test-d bbbb <> THROW -1543 <> THROW
233 test-d bbbb <> THROW aaaa <> THROW 233 <> THROW
0 test-d bbbb <> THROW aaaa <> THROW THROW
: test-e whilet cccc bbbb ;
3 test-e bbbb <> THROW 1 <> THROW 2 <> THROW 3 <> THROW
: test-f whilep cccc bbbb ;
3 test-f bbbb <> THROW THROW 1 <> THROW 2 <> THROW 3 <> THROW
: test-g whilen dddd bbbb ;
-3 test-g bbbb <> THROW -1 <> THROW -2 <> THROW -3 <> THROW
: test-h whilef eeee bbbb ;
3 0 test-h bbbb <> THROW THROW THROW 1 <> THROW 2 <> THROW
}test

Автор:  mOleg [ Пн май 04, 2009 22:16 ]
Заголовок сообщения: 

итак, используется это очень просто:

: hello ." test " ;
: sample DUP . ift hello ." passed" ;
0 sample
12 sample

в слове sample ift является конструкцией выбора, причем, никаких меток по типу классических IF ELSE THEN и подобных веще в этих конструкциях не используется (в чем их преимущество: проще реализовать для микроконтроллера, к примеру) а значит никаких MARK> RESOLVE> не надо.

то же самое с циклами:
: test ." count: " DUP . 1 - ;
: sample whilet test ." pased" ;
10 sample

особенность использования состоит в том, что данные конструкции не выгребают за собой следующее слово, а компилируются как обычное(сравнительно обычное. Можно убрать ?COMP <: ;> COMPILE, IMMEDIATE , которые нужны только для контроля времени использования)
слово, но это значит, что после данных ift iff .. нельзя использовать компилирующие слова (точнее надо очень осмотрительно их использовать,
так как подобный код: ift [COMPILE] [ будет состоять из двух токенов, и ветвление будет касаться не слова [COMPILE] а слова [

Автор:  _Harry [ Вт май 05, 2009 02:39 ]
Заголовок сообщения: 

Да интересно :roll:
Только не понятно что здесь атомарное?

Автор:  VoidVolker [ Вт май 05, 2009 09:09 ]
Заголовок сообщения: 

_Harry писал(а):
Только не понятно что здесь атомарное?

Видимо то, что они работают с одним токеном и они проще, чем более привычные IF/ELSE/THEN.

Автор:  _Harry [ Вт май 05, 2009 09:34 ]
Заголовок сообщения: 

Хм привычное значение для слова атомарный - неделимый.
Это опереации которые нельзя прерывать. Лучше все таки по другому обозвать, только как не придумывается :shuffle;

Автор:  Гость [ Вт май 05, 2009 09:48 ]
Заголовок сообщения: 

В DSSP это же было?

Для spf4: devel\~day\common\dssp.f

Автор:  WingLion [ Вт май 05, 2009 18:16 ]
Заголовок сообщения: 

кажется в контроллерах бывают команды условного исполнения,
которые по некоему условию исполняют или неисполняют следующую команду в программе...

А тут то же самое только для FVM получается... если, конечно, я правильно понял

Автор:  garbler [ Вт май 05, 2009 19:59 ]
Заголовок сообщения: 

в dssp это действительно было, равно как и принцип "одно слово исходника = одно слово целевого кода". что касается пропуска следующей команды в ассемблере микропроцессора по какому-то условию, то это не является чем-то уникальным, подобная команда есть в массе различных микропроцессоров.

да, и ещё, подобные формы условных конструкций, как описано у mOleg, широко применяются в 4P (единственно, реализованы по другому).

p.s. да, в 4P есть ещё команды or: and: while: и т.д. они действуют до конца слова, тоже удобно (особенно в совокупности с множественными точками входа и хвостовой рекурсией).

p.p.s. если будешь смотреть - обрати ещё внимание на then> later> и др. (приём широко используется).

Автор:  mOleg [ Вт май 05, 2009 22:48 ]
Заголовок сообщения: 

garbler писал(а):
p.s. да, в 4P есть ещё команды or: and: while: и т.д. они действуют до конца слова, тоже удобно (особенно в совокупности с множественными точками входа и хвостовой рекурсией).

рекурсия - это первое, что я получил при отладке :) в смысле в виде побочного эффекта (перемудрил со стеком возвратов, получил трассу откатов)
а ссылочки можно на описание?

garbler писал(а):
да, и ещё, подобные формы условных конструкций, как описано у mOleg, широко применяются в 4P (единственно, реализованы по другому).

если честно, думал, что из Постскрипта команды реализую. Потом, когда уже сделал, посмотрел в Постскрипт - там иначе оно (тоже надо будет сделать).

garbler писал(а):
p.p.s. если будешь смотреть - обрати ещё внимание на then> later> и др. (приём широко используется).

ссылочки, ссылочки :) потому как гугл выдаст тучу мусора, попробуй разгреби ее 8((

Автор:  mOleg [ Вт май 05, 2009 22:53 ]
Заголовок сообщения: 

Гость писал(а):
В DSSP это же было?
Для spf4: devel\~day\common\dssp.f

там не так сделано :)

_Harry писал(а):
Хм привычное значение для слова атомарный - неделимый.
Это опереации которые нельзя прерывать. Лучше все таки по другому обозвать, только как не придумывается

то-то и оно. Но в данном случае "атомарный" - в противоположность "составному"

WingLion писал(а):
кажется в контроллерах бывают команды условного исполнения,
которые по некоему условию исполняют или неисполняют следующую команду в программе...
А тут то же самое только для FVM получается... если, конечно, я правильно понял_________________

вобщем да, почти правильно :) для скорости и экономии места эти операции имеет смысл загнать внутрь ФВМ, только надо будет пересмотреть весь код, чтобы убрать классические if-ы. Тут, как оказалось, техника использования нетривиальная (или скорее непривычная). Получается множество мелких слов, которые сложно как-то осмысленно обозвать...

Автор:  WingLion [ Ср май 06, 2009 00:50 ]
Заголовок сообщения: 

а чем не устраивает название команды условного исполнения?

кстати, классический if незачем убирать. Он есть всего лишь условным исполнением команды jmp addr

Автор:  Wlad [ Ср май 06, 2009 01:50 ]
Заголовок сообщения: 

А что назвать "классикой"?

Общий вид оператора условия:

IF THEN
ELSIF THEN
ELSIF THEN
...
ELSE
END

тут просто переходом и не пахнет...

Автор:  WingLion [ Ср май 06, 2009 09:17 ]
Заголовок сообщения: 

Wlad писал(а):
IF THEN
ELSIF THEN
ELSIF THEN
...
ELSE
END

хм... иноязычная класика нам совсем и не класика...

для форта класика -
IF / компилируется условный переход за ELSE
..
ELSE // компилируется переход за THEN
..
THEN // ничего не компилируется, просто метка (происходит разрешение адресов переходов)

Так что, переходами пахнет, и даже двумя...

Автор:  garbler [ Ср май 06, 2009 10:18 ]
Заголовок сообщения: 

mOleg писал(а):
а ссылочки можно на описание?

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

я на рапиду положил предыдущую, в ней начни с файла help4p

mOleg писал(а):
если честно, думал, что из Постскрипта команды реализую

неа, там все команды работают с XT на стеке, выполняемый код представлен блоками {...} (с поддержкой вложенности) и реализован "total rpn" (за исключением лексического представления типов данных: ключ в словарь, число, слово, блок кода, строка и т.д.). учитывая, что у тебя есть box[ и ]box, лобовая реализация будет тривиальной (с оптимальной же придётся повозиться).

garbler писал(а):
p.p.s. если будешь смотреть - обрати ещё внимание на then> later> и др. (приём широко используется).

и ещё на ;then

mOleg писал(а):
ссылочки, ссылочки :) потому как гугл выдаст тучу мусора, попробуй разгреби ее 8((

мне с гуглом везёт больше :-) внутри архива с исходниками многое можно найти поиском, в частности, определения later> лежат в tool4p (а слой ansi совместимости в dxt.fs). и ещё: символ ` управляет флагами компиляции, type` эквивалентно (если посмотреть на вещи грубо) postpone type, а `type соответствует ['] type

собственно говоря, у каждого слова в 4P как минимум по 2 поля кода (одно называется "классом слова" и определяет действия по компиляции), это упрощает многие вещи, и даже внутренний интерпретатор :-)

p.s. можно ещё поискать мессаги от Helmar Wodtke в comp.lang.forth, из них будет понятнее почему были приняты те или иные проектные решения.

Автор:  Wlad [ Ср май 06, 2009 10:37 ]
Заголовок сообщения: 

Хорошо, но может стоит как-то попробовать сделать так, что бы уменьшить вложенность условных операторов, ежели автора понесёт на глубину вложенности > 3 ?
Тут надо учесть, что то, что я привёл - НЕ есть аналог SWITCH/CASE...

Страница 1 из 3 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/