?BRANCH

Материал из ПМК вики
Перейти к навигации Перейти к поиску
Версия для печати больше не поддерживается и может содержать ошибки обработки. Обновите закладки браузера и используйте вместо этого функцию печати браузера по умолчанию.

?BRANCH (условное ветвление) — фортовское слово Каллисто. Условный переход в шитом коде.

?BRANCH        ( ф -- )                        Условное ветвление. Переход в шитом коде, если ф=0.

Слово ?BRANCH снимает флаг ф со стека и анализирует его значение:

  • если это «ложь» (ф=0), то слово работает, как BRANCH — указатель интерпретации устанавливается по адресу, скомпилированному вслед за токеном ?BRANCH.
  • если это «истина» (ф≠0), то при интерпретации данной последовательности скомпилированный адрес перехода будет обойдён. Интерпретация продолжится с адреса, следующего за адресом перехода.

Обычно слово ?BRANCH компилируется в шитый код лишь стандартными словами вроде IF, WHILE и UNTIL. В приложениях необходимость использования слова ?BRANCH возникает лишь в случае разработки новых структур управления — например, оператора CASE, отсутствующего в Каллисто.

Ввод слова ?BRANCH

В режиме NUM последовательно нажмите клавиши  K     Р-ГРД-Г   В/О   ×   ШГ←   4   С/П   ПП 

Для возврата в режим NUM нажмите синюю клавишу  P .

История

Любопытно, что ?BRANCH продолжает традицию советских ПМК: переход выполняется, если проверяемое условие ложно (ф=0 представляет логическое значение «ложь»).

Некоторые альтернативные названия этого слова отражают тот факт, что переход происходит при нуле на вершине стека: 0BRANCH ZBRANCH

?BRANCH в предыдущем стандарте Forth-83 (англ.)

     ?BRANCH      flag --                       C,83 "question-branch"
          When used in the form:  COMPILE ?BRANCH  a conditional
          branch operation is compiled.  See BRANCH for further
          details.  When executed, if flag is false the branch is
          performed as with BRANCH .  When flag is true execution
          continues at the compilation address immediately following
          the branch address.

0BRANCH в fig-FORTH Release 1 glossary, май 1979 (англ.)

0BRANCH       f  ---                            C2
       The run-time proceedure to conditionally branch. If f is false
       (zero), the following in-line parameter is added to the interpretive
       pointer to branch ahead or back. Compiled by IF, UNTIL, and WHILE.

Реализация

В Каллисто 1.0 словарная статья ?BRANCH содержит два токена, осуществляющие условные переходы как в области данных, так и в памяти программ:

 647 ;#qBRANCH
 648 ; ?BRANCH          ( ф −− )                             Условное ветвление. Переход в шитом коде, если ф=0.
 649 ; Служебное слово для реализации структур управления −− таких, как IF WHILE
 650 LZBRAN:         .DB     7
 651                 .TEXT   "?BRANCH"               ; ( f −− )
 652                 .DW     LTYPE1
 653 ZBRAND:         .DW     JZBRAND                 ; ?BRANCH в памяти данных
 654 JZBRAND:        RM3 M8  1 + M3  KRM8            ; POP RX
 655                 PX!=0 CNTD
 656                 KRM6 KRM6  KGOTO9               ; RI := RI+2, NEXT
 657 
 658 ZBRAN:          .DW     JZBRAN                  ; ?BRANCH в памяти программ
 659 JZBRAN:         RM3 M8  1 + M3  KRM8            ; POP RX
 660                 PX!=0 CNT                       ; если RX==0, переход
 661                 PPRM9044 PPRM9044               ; RI := RI+2, пропустить ячейку
 662                 KGOTO9                          ; NEXT
…
 672 CNTD:           KRM6 RME ∗ KRM6 + M6  KGOTO9
…
 676 CNT:
 677                 Cx PPM9210                      ; Прочесть двухбайтовое значение по номеру X=0
 678                 PPM9042                         ; RI := MEMW[RI]
 679                 KGOTO9                          ; NEXT

Реализации в SP-Forth 4.20

: TC-?BRANCH,
  ?SET
  084 TO J_COD
  ???BR-OPT
  SetJP  SetOP
  J_COD    \  JX без 0x0F
  0x0F     \  кусок от JX
  C, C,
  DUP IF DP @ CELL+ - THEN , DP @ TO LAST-HERE
;
: ?BRANCH, ( ADDR -> ) \ скомпилировать инструкцию ADDR ?BRANCH
  ?SET
  084 TO J_COD
  ???BR-OPT
  SetJP  SetOP
  J_COD    \  JX без 0x0F
  0x0F     \  кусок от JX
  C, C,
  DUP IF DP @ CELL+ - THEN , DP @ TO LAST-HERE
;

Советская реализация

У Баранова-Ноздрунова приводится следующее высокоуровневое определение слова ?BRANCH (стр. 54):

 : ?BRANCH   ( A ---> )    R> ↔ IF 2+ ELSE @ THEN  >R  ;

Для повышения скорости исполнения в Каллисто BRANCH реализован, как примитив.

В ФОРТ-ЕС слово ?BRANCH также было примитивом, который опирался на код BRANCH

Вот описание слова ?BRANCH и их определения:

?BRANCH К F-> ЕСЛИ F "ЛОЖЬ", ТО КАК "BRANCH", ИНАЧЕ             5
          ПРОДОЛЖИТЬ ИНТЕРПРЕТАЦИЮ ОТ АДРЕСА,
          СЛЕДУЮЩЕГО ЗА АДРЕСОМ ПЕРЕХОДА

                      Экран номер 5
( 09.09.86  BRANCH  ?BRANCH  (LOOP/  (+LOOP/ )

CODE  BRANCH  M: ВRANСН#
 RI 0 (, RI RFORTH LH,    RI RMASK  NR,      RNEXT BR,

СОDE ?BRANCH  RW1 POP,   RW1 RW1  LTR,   ВRANСН# BZ,
   RI RTWO AR,  RNEXT BR,

В FORTH ИТЭФ слово ?BRANCH тоже было примитивом и зависело от кода BRANCH:

             HEAD    207Q,'?BRANC',310Q,ZBRAN             ; ?BRANCH
   ; Ветвление при нуле в стеке (FALSE)
             POP   AX
             CMP   AX, 0
             JE    CNT
             ADD   SI, 2
             NEXT

             HEAD    206Q,'BRANC',310Q,BRAN               ; BRANCH
   CNT:      ADD   SI,  [SI]
             NEXT

Ссылки


  У этой статьи нет иллюстраций. Вы можете помочь проекту, добавив их.


  Это заготовка статьи. Вы можете помочь проекту, дополнив её.