FOR

Материал из ПМК вики
Перейти к навигации Перейти к поиску

FOR (для, читается «фор») — усовершенствованное слово Каллисто. Начало цикла со счётчиком.

FOR            ( n −− )                             Повторить n раз цикл FOR NEXT. Если n<=0, цикл не исполнять.
Пример работы цикла FOR

Цикл FOR … NEXT исполнится ровно n раз, если n положительное число. Ситуация не определена, если n>65535.

Последовательность слов w1 w2… wk в цикле

n FOR w1 w2… wk NEXT

исполнится ровно n раз. Если n отрицательно или равно нулю, цикл не выполнится ни разу. Управление сразу передастся на слово, следующее за словом NEXT.

Внутри цикла слово I позволяет считать переменную цикла, меняющуюся от n при первом проходе до 1 при последнем. В случае вложенных циклов похожее слово J позволяет узнать значение переменной внешнего цикла. Если потребуется прервать цикл досрочно, можно воспользоваться словом LEAVE.

Ввод слова FOR[править]

В режиме ЛАТ последовательно нажмите три клавиши  П   5   × 

История цикла со счётчиком[править]

В 1968 году первая версия интерпретатора, получившая название FORTH, заработала на миникомпьютере IBM 1130 с графическим дисплеем IBM 2250 (16-битный процессор с ОЗУ 8К, дисководом, клавиатурой, принтером и ридером/панчером перфокарт).

Когда Чак Мур понял, что основанная на Форте среда для кросс-программирования терминала IBM 2250 на миникомпьютере IBM 1130 превосходит Фортрановскую среду разработки на IBM 1130, он превратил свою среду в компилятор для IBM 1130. Это добавило команды цикла, концепцию хранения исходного текста в 1024-байтных блоках, инструменты для управления ими и множество особенностей компилятора, вошедших в Форт надолго.

Первый FORTH для IBM 1130 знал цикл FOR…NEXT под именем DO … CONTINUE

Этот же заимствованный из Фортрана цикл DO CONTINUE Чак Мур использовал в версии Форта 1970 года размером 2К×48бит для компьютера Burroughs B-5500.

В 1971-73 годах Чак Мур перенёс Форт на DEC PDP-11 в National Radio Astronomy Observatory (англ., Шарлотсвилл). Появился косвенный шитый код, который изменил структуры управления, включая DO … LOOP. Они получили элегантную реализацию с адресами на стеке данных во время компиляции.

Позже мощный цикл DO … LOOP/+LOOP, позволяющий задавать границы и шаг цикла, вошёл во все стандарты Форта, но ещё в 1985 году он был отвергнут Чаком Муром из-за своей излишней сложности. Форт-процессор NC4000, на котором работал cmForth, поддерживал цикл со счётчиком аппаратно. В те годы цикл FOR…NEXT выполнялся на один («нулевой») раз больше, чем сейчас. eForth и некоторые диалекты Форта скопировали эту раннюю реализацию, позже для компенсации лишнего раза включив средства разной элегантности, например -ZERO в cmForth и AFT/THEN в eForth.

В предложенном виде цикл FOR используется в colorForth, откуда он и пришёл в Каллисто.

Цикл FOR…NEXT был взят в Форт из Бейсика. Интересно, что в Бейсик цикл FOR…NEXT пришёл также из Фортрана, как более удобный синтаксис того же самого DO…CONTINUE.

Цикл FOR…NEXT хорошо совместим с циклом FL0 советских ПМК и ЭКВМ, допуская при этом практически неограниченное число вложений. Важное развитие входного языка в том, что тело каллистянского цикла FOR…NEXT может не выполниться ни разу, если запрошенное число циклов отрицательно или равно нулю.

При переносе программ с Форта на Каллисто можно заранее вычислить количество повторений и использовать цикл FOR…NEXT. Это ускорит работу приложения. Значение фортовской переменной цикла можно получить, прибавив I к нижней границе цикла, или вычев её из верхней. Для буквальной, но медленной имитации цикла DO … LOOP/+LOOP, можно использовать цикл WHILE. Переменную цикла можно объявить с помощью слов VARIABLE, VALUE или держать на вершине стека возвратов.

Если в фортовской программе уже используется n FOR, при переносе на Каллисто надо перепроверить по документации использованного диалекта Форта, считает ли там цикл до 0 или 1.

Реализация[править]

На этапе компиляции FOR может вызывать авост с кодом ошибки 17. Авост вызывает слово ?COMP если обнаруживает, что текущее состояние не является компиляцией.

3721 ;#FOR
3722 ; FOR            I ( n −− )                             Повторить n раз цикл FOR NEXT. Если n<=0, цикл не исполнять.
3723 ; Начало цикла со счётчиком. Цикл исполнится ровно n раз, если n положительное число.
3724 ; Ситуация не определена, если n>65535.
3725 LFOR:           .DB     83H
3726                 .TEXT   "FOR"                   ; ( сколько −− )
3727                 .DW     LREPEAT
3728 FOR:            .DW CALL, QCOMP, COMP,XFORD, GMARK, LMARK, PI, EXIT

Реализация цикла DO…LOOP в SP-Forth 4.20[править]

( inline'ы для компиляции циклов )

CODE C-DO
      LEA EBP, 8 [EBP]
      A;  BA C, 0000 W, 8000 W,   \   MOV     EDX , # 80000000
      SUB  EDX, -8 [EBP]
      LEA  EBX,  [EDX] [EAX]
      MOV  EAX, -4 [EBP]
      MOV  EDX, EDX  \ FOR OPT
\      PUSH EDX
\      PUSH EBX
      RET
END-CODE

CODE C-?DO
      CMP  EAX, -8 [EBP]
      JNZ  SHORT @@1
\      SIF  0=
        MOV  EAX, -4 [EBP]
        JMP  EBX
\      STHEN
@@1:  PUSH EBX
      A; BB C, 0000 W, 8000 W,   \   MOV     EBX , # 80000000
      SUB  EBX, -8 [EBP]
      PUSH EBX  \ 80000000h-to
      ADD  EBX, EAX
      PUSH EBX  \ 80000000H-to+from
      MOV  EAX, -4 [EBP]
      RET
END-CODE
…
: DO   \ 94
  ?COMP
  S" C-DO" TC-FINDOUT INLINE,
  SetOP  0x68 C, DP @ 4 ALLOT  \ PUSH #
  SetOP  0x52 C,               \ PUSH EDX
  SetOP  0x53 C,               \ PUSH EBX
  4 ALIGN-NOP
  DP @ DUP TO :-SET
; IMMEDIATE

: ?DO   \ 94 CORE EXT
  ?COMP
  OP0 @ :-SET  UMAX TO :-SET
  S" NIP" TC-FINDOUT DUP INLINE, INLINE,
  0xBB C, DP @ 4 ALLOT
  S" C-?DO" TC-FINDOUT INLINE,
  DP @ DUP TO :-SET
; IMMEDIATE

: LOOP   \ 94
  ?COMP
  24 04FF W, C, \ inc dword [esp]
  HERE 2+ - DUP SHORT?   SetOP SetJP
  IF
    71 C, C, \ jno short 
  ELSE
    4 - 0F C, 81 C, , \ jno near
  THEN    SetOP
  0C24648D , \ lea esp, 0c [esp]
  *DP@ SWAP !
; IMMEDIATE

: +LOOP    \ 94
  ?COMP
    0x810FFC45
    0x8B240401
\ ADD     [ESP] , EAX
\ MOV     EAX , FC [EBP]
\ JNO 
  OP0 @ :-SET  UMAX TO :-SET
  POSTPONE [ S" ' NIP" EVALUATE ]  INLINE, SetOP , , 
  -5 ALLOT SetOP 
   3 ALLOT SetOP
   2 ALLOT
  DP @ CELL+ -  ,
  SetOP 0x0C24648D , \ lea esp, 0xC [esp]
  *DP@ SWAP !
; IMMEDIATE

Советская реализация цикла со счётчиком[править]

Описание слова DO и определение DO…LOOP в ядре ФОРТ-ЕС:

DO     HK ->А1,А2,3 /КОМПИЛЯЦИЯ/ НАЧАЛО ЦИКЛА "DO" CO           47
          N1,N2-> /ИСПОЛНЕНИЕ/ СЧЕТЧИКОМ ОТ N2 ДО N1

                      Экран номер 47
 ( 31.03.86   СТАНДАРТНЫЕ СТРУКТУРЫ УПРАВЛЕНИЯ )
 : DO      ?COMP  COMPILE (DO) >MARK <MARK 3 ; IMMEDIATE
 : LOOP    3 ?PAIRS COMPILE (LOOP) <RESOLVE >RESOLVE ; IMMEDIATE
 : +LOOP   3 7PAIRS COMPILE (+LOOP) <RESOLVE >RESOLVE ; IMMEDIATE

Цикл DO…LOOP/+LOOP в FORTH ИТЭФ тоже определён через (DO) и (LOOP)/(+LOOP):

             HEAD    302Q,'D',317Q,$DO,$COL               ; DO
             DW  COMP,XDO,HERE,THREE,SEMI

             HEAD    304Q,'LOO',320Q,LOOP,$COL            ; LOOP
             DW  THREE,QPAIR,COMP,XLOOP,BACK,SEMI

             HEAD    305Q,'+LOO',320Q,PLOOP,$COL          ; +LOOP
             DW  THREE,QPAIR,COMP,XPLOO,BACK,SEMI

Ссылки[править]


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