Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
| '''IF''' (если) — стандартное слово [[Каллисто]]. Условный оператор. | | '''IF''' — стандартное слово [[Каллисто]]. |
| IF ( ф −− ) Если ф ложен (ф=0), перейти к парному THEN (или ELSE).
| |
| [[Файл:CallistoIf.png|thumb|right|264px|Пример работы слова IF]]
| |
| Ветвление "IF" выполняет действия только при выполнении определённого условия, но может включать в себя альтернативу:
| |
| * IF xxx [[THEN]] — фраза xxx выполняется тогда и только тогда, когда ф истинно (отлично от нуля)
| |
| * IF xxx [[ELSE]] yyy [[THEN]] — фраза xxx выполняется, когда ф истинно (отлично от нуля), а yyy тогда и только тогда, когда ф [[FALSE|ложно (равно нулю)]]
| |
| Любой IF, независимо от наличия части [[ELSE]], всегда должен завершаться словом [[THEN]]. Эти два каллистянских слова образуют операторные скобки IF-THEN.
| |
| | |
| == Ввод слова IF ==
| |
| В [[Режим ЛАТ|режиме ЛАТ]] последовательно нажмите две клавиши [[Клавиша 7|{{Серая клавиша|7}}]] [[Клавиша П|{{Чёрная клавиша|П}}]]
| |
| | |
| == IF в стандарте ANS Forth ==
| |
| <pre>
| |
| 6.1.1700 IF CORE
| |
| Интерпретация: Семантика интерпретации для этого слова не определена.
| |
| | |
| Компиляция: ( C: -- orig )
| |
| Помещает адрес ячейки новой неразрешенной ссылки вперед orig на
| |
| стек потока управления. Добавляет семантику времени-выполнения,
| |
| данную ниже к текущему определению. Семантика не завершена, пока
| |
| orig не разрешена, например THEN или ELSE.
| |
| | |
| Время-выполнения: ( x -- )
| |
| Если все биты x нулевые, продолжает выполнение с адреса ячейки
| |
| определенного ссылкой orig.
| |
| | |
| См.: 3.2.3.2 Стек потока-управления, 6.1.1310 ELSE, 6.1.2270 THEN.
| |
| | |
| A.6.1.1700 IF
| |
| Типичное использование:
| |
| : X ... test IF ... THEN ... ;
| |
| или
| |
| : X ... test IF ... ELSE ... THEN ... ;
| |
| </pre>
| |
| | |
| == История ==
| |
| «Разрушающий» (снимающий со стека верхнее значение) IF пришёл в Каллисто из Форта.
| |
| | |
| Условный оператор был изобретён [https://ru.wikipedia.org/wiki/Маккарти,_Джон Джоном Маккарти] для языка Лисп в 1957-58 годах ([http://www-formal.stanford.edu/jmc/history/lisp/node2.html англ.]) на основе условного перехода, существовавшего в то время в Фортране. Будучи в комитете по разработке Алгола, Маккарти также внёс условный оператор в Алгол, откуда он и вошёл в Форт и другие языки программирования.
| |
| | |
| В конце 1950-ых годов, когда Чак Мур программировал для [https://ru.wikipedia.org/wiki/%D0%A1%D0%BC%D0%B8%D1%82%D1%81%D0%BE%D0%BD%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%B0%D1%81%D1%82%D1%80%D0%BE%D1%84%D0%B8%D0%B7%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%BE%D0%B1%D1%81%D0%B5%D1%80%D0%B2%D0%B0%D1%82%D0%BE%D1%80%D0%B8%D1%8F САО] отслеживание советских спутников, фортрановский оператор IF … ELSE IF позволял выбирать команды интерпретатора по первому символу. Использование такого интерпретатора позволяло вводить (посредством [https://ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BA%D0%B0%D1%80%D1%82%D0%B0 перфокарт]) разные уравнения для нескольких спутников, без дорогостоящей компиляции основной программы.
| |
| | |
| Слово IF впервые появилось в программе CURVE, написанной Чак Муром на Алголе для Burroughs B5500 в 1964 году ([https://ru.wikipedia.org/wiki/%D0%9D%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%83%D1%81%D0%BA%D0%BE%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BB%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B8%D1%8F_SLAC Национальная ускорительная лаборатория SLAC], [https://ru.wikipedia.org/wiki/%D0%A1%D1%82%D1%8D%D0%BD%D1%84%D0%BE%D1%80%D0%B4%D1%81%D0%BA%D0%B8%D0%B9_%D1%83%D0%BD%D0%B8%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%82%D0%B5%D1%82 Стэнфордский университет]). Необычный постфиксный условный оператор является модификацией условного оператора, взятого из Алгола:
| |
| Алгол — IF выражение THEN истина ELSE ложь
| |
| CURVE — стек IF истина ELSE ложь THEN
| |
| | |
| «Истина» интерпретировалась, если на стеке был не-нуль. THEN предлагал уникальное завершение, отсутствие которого в Алголе всегда вводило в замешательство Чака Мура. Подобные выражения интерпретировались: IF сканировал вперёд до ELSE или THEN.
| |
| | |
| В 1970 году неразрушающий условный оператор IF ELSE THEN был реализован Чаком Муром для 2К×48бит версии Форта на Burroughs B-5500. Следущий код B-5500 FORTH проверял вершину стека на истинность и дублировал её, если она истина (аналог [[?DUP]]):
| |
| IF DUP THEN
| |
| | |
| В 1971-73 годах Чак Мур перенёс Форт на DEC PDP-11 в [https://en.wikipedia.org/wiki/National_Radio_Astronomy_Observatory National Radio Astronomy Observatory] (''англ.'', [https://ru.wikipedia.org/wiki/%D0%A8%D0%B0%D1%80%D0%BB%D0%BE%D1%82%D1%81%D0%B2%D0%B8%D0%BB%D0%BB_%28%D0%92%D0%B8%D1%80%D0%B3%D0%B8%D0%BD%D0%B8%D1%8F%29 Шарлотсвилл]). Появился ''косвенный шитый код'' (''англ.'' indirect-threaded code), который изменил структуры управления, включая IF … THEN. Они получили элегантную реализацию с адресами на [[Стек данных|стеке данных]] во время компиляции.
| |
| | |
| В {{colorForth}} Чак Мур вернулся к «неразрушающему» IF. Мотивацией послужило то, что лучше явно писать IF DROP где это необходимо, а последовательности DUP IF или ?DUP IF расходуют машинное время впустую.
| |
| | |
| === IF в предыдущем стандарте Forth-83 (англ.) ===
| |
| IF flag -- C,I,79
| |
| -- sys (compiling)
| |
| Used in the form:
| |
| flag IF ... ELSE ... THEN
| |
| or
| |
| flag IF ... THEN
| |
| If flag is true, the words following IF are executed and the
| |
| words following ELSE until just after THEN are skipped. The
| |
| ELSE part is optional.
| |
| | |
| If flag is false, the words from IF through ELSE , or from
| |
| IF through THEN (when no ELSE is used), are skipped. sys is
| |
| balanced with its corresponding ELSE or THEN . See: "9.9
| |
| Control Structures"
| |
| | |
| === IF в стандарте Forth-79 (англ.) ===
| |
| IF flag -- I,C,210
| |
| Used in a colon-definition in the form:
| |
| flag IF ... ELSE ... THEN or
| |
| flag IF ... THEN
| |
| If flag is true, the words following IF are executed and the
| |
| words following ELSE are skipped. The ELSE part is optional.
| |
| If flag is false, words between IF and ELSE, or between IF and
| |
| THEN (when no ELSE is used), are skipped. IF-ELSE-THEN
| |
| conditionals may be nested.
| |
| | |
| === IF в fig-FORTH Release 1 glossary, май 1979 (англ.) ===
| |
| IF f --- (run-time) -- addr n (compile) P,C2,L0
| |
| Occurs is a colon-definition in form:
| |
| IF (tp) ... ENDIF .
| |
| IF (tp) ... ELSE (fp) ... ENDIF
| |
| At run-time, IF selects execution based on a boolean flag. If f is
| |
| true (non-zero), execution continues ahead thru the true part. If f
| |
| is false (zero), execution skips till just after ELSE to execute
| |
| the false part. After either part, execution resumes after ENDIF.
| |
| ELSE and its false part are optional.; if missing, false execution
| |
| skips to just after ENDIF..
| |
| | |
| At compile-time IF compiles 0BRANCH and reserves space for an offset
| |
| at addr. addr and n are used later for resolution of the offset and
| |
| error testing.
| |
| | |
| == Реализация ==
| |
| В [[Каллисто]], как и в Форте, реализован «разрушающий IF»: слово IF всегда ''снимает'' со стека значение, в зависимости от которого выполняется одна или другая последовательность слов. Если вам важно ещё раз проверить это значение, необходимость его сохранения возложена на разработчика — обычно для этого используются слова [[Слово ↑|↑]] или [[?DUP]].
| |
| | |
| IF можно использовать только внутри [[Слово :|определений через двоеточие]]. Слово IF [[?COMP|проверяет состояние компиляции]], и если обнаруживает [[Слово [|состояние исполнения]], вызывает [[Авост приложения|авост]] с сообщением об ошибке № 17.
| |
| | |
| Слово IF компилирует в [[шитый код]] [[?BRANCH|оператор условного перехода]], который будет прилежно выполняться вне зависимости от [[STATE]].
| |
| <pre>
| |
| 3699 ;#IF
| |
| 3700 ; IF I ( ф −− ) Если ф ложен (ф=0), перейти к парному THEN (или ELSE).
| |
| 3701 LIF: .DB 82H
| |
| 3702 .TEXT "IF" ; ( флаг −− )
| |
| 3703 .DW LELSE
| |
| 3704 SIF: .DW CALL ; Начало ветвления "IF".
| |
| 3705 RIF: .DW QCOMP, COMP,ZBRAND, GMARK, TWO, EXIT
| |
| </pre>
| |
| | |
| Пример реализации IF из предыдущего стандарта Forth-83:
| |
| : IF COMPILE ?BRANCH >MARK ; IMMEDIATE
| |
| | |
| Реализация IF в СП-Форте 3.07:
| |
| <PRE>
| |
| : IF ?COMP HERE ?BRANCH, >MARK 1 ; IMMEDIATE
| |
| </PRE>
| |
| Реализации из SP-Forth 4.20:
| |
| <pre>
| |
| : IF \ 94
| |
| \ Интерпретация: семантика неопределена.
| |
| \ Компиляция: ( C: -- orig )
| |
| \ Положить на управляющий стек позицию новой неразрешенной ссылки вперед orig.
| |
| \ Добавить семантику времени выполнения, данную ниже, к текущему определению.
| |
| \ Семантика незавершена, пока orig не разрешится, например, по THEN или ELSE.
| |
| \ Время выполнения: ( x -- )
| |
| \ Если все биты x нулевые, продолжать выполнение с позиции, заданной
| |
| \ разрешением orig.
| |
| ?COMP 0 ?BRANCH, >MARK 1
| |
| ; IMMEDIATE
| |
| </pre>
| |
| <pre>
| |
| : IF \ 94
| |
| ?COMP 0 TC-?BRANCH, >MARK 1
| |
| ; IMMEDIATE
| |
| </pre>
| |
| | |
| === Советская реализация ===
| |
| Юрий Семёнов приводит следующее описание слова IF (стр. 59):
| |
| : IF COMPILE ?BRANCH HERE 0 , 2 ; IMMEDIATE
| |
| | |
| У Баранова-Ноздрунова определение слова IF выглядит так (стр. 58):
| |
| : IF ( ---> A,1 ) COMPILE ?BRANCH >MARK 1 ;
| |
| IMMEDIATE
| |
| | |
| Описание слова IF и определение IF…ELSE…THEN в ядре ФОРТ-ЕС:
| |
| <pre>
| |
| IF HК->А,2 /КОМПИЛЯЦИЯ/ НАЧАЛО ВЕТВЛЕНИЯ "IF" 47
| |
| F-> /ИСПОЛНЕНИЕ/
| |
| | |
| Экран номер 47
| |
| ( 31.03.86 СТАНДАРТНЫЕ СТРУКТУРЫ УПРАВЛЕНИЯ )
| |
| : IF ?COMP COMPILE ?BRANCH >MARK 2 ; IMMEDIATE
| |
| : THEN 2 ?PAIRS >RESOLVE ; IMMEDIATE
| |
| : ELSE 2 ?PAIRS COMPILE BRANCH >MARK
| |
| SWAP >RESOLVE 2 ; IMMEDIATE
| |
| </pre>
| |
| Определение слова IF в FORTH ИТЭФ:
| |
| <PRE>
| |
| HEAD 302Q,'I',306Q,$IF,$COL ; IF
| |
| DW COMP,ZBRAN,HERE,ZERO,COMMA,TWO,SEMI
| |
| </PRE>
| |
| | |
| == Ссылки ==
| |
| * {{Исходник|IF|IF}}
| |
| * См. слова [[ELSE]] и [[THEN]], а также [[TRUE]] и [[FALSE]]
| |
| * Слово [http://forth.sourceforge.net/standard/dpans/dpans6.htm#6.1.1700 IF] и [http://forth.sourceforge.net/standard/dpans/dpansa6.htm#A.6.1.1700 комментарий к нему] в стандарте ANS Forth ''(англ.)''
| |
| * Слово [http://forth-standard.org/standard/core/IF IF] и [http://forth-standard.org/standard/rationale#rat:core:IF комментарий к нему] в черновике Forth 200x ''(англ.)''
| |
| * Статья [http://www.compiler.su/uslovnye-operatory.php «Условные операторы»] на compiler.su
| |
| * [https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%D0%B2%D0%B5%D1%82%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F Оператор ветвления на Википедии]
| |
| * [http://gudleifr.h1.ru/cgi-bin/pilo.cgi?FL=../g9.txt&IS=\6.PERWOISTOTNIKI\LEO%20BRODIE%20STARTING%20FORTH\04.%20KOMPJUTER%20%22PRINIMAET%20RESENIA%22 КОМПЬЮТЕР "ПРИНИМАЕТ РЕШЕНИЯ"] в книге [http://gudleifr.h1.ru/cgi-bin/pilo.cgi?FL=../g9.txt&IS=\6.PERWOISTOTNIKI\LEO%20BRODIE%20STARTING%20FORTH Л.Броуди «Начальный курс программирования на языке Форт»]
| |
| * [http://www.forth.com/starting-forth/sf4/sf4.html Decisions, Decisions…] в книге [http://www.forth.com/starting-forth/ Leo Brodie Starting Forth] ''(англ.)''
| |
| | |
|
| |
|
| | {{нет иллюстраций}} |
| {{заготовка}} | | {{заготовка}} |
| [[Категория:Слова Каллисто]] | | [[Категория:Слова Каллисто]] |
| [[Категория:Слова высокого уровня]]
| |
| [[Категория:Слова с признаком IMMEDIATE]]
| |
| [[Категория:Структуры управления Каллисто]]
| |
| [[Категория:Слова, способные вызывать авост приложения]]
| |
| [[Категория:Компилирующие слова]]
| |
| [[Категория:Стандартные слова]]
| |
| [[Категория:1994 CORE]]
| |
| [[Категория:2012 CORE]]
| |