РефалАБ. Руководство пользователя

4. Компиляция и исполнение РефалАБ-программ

Введение

Компиляция и компоновка РефалАБ-программ может производиться на ПК под управлением следующих операционных систем:

Для исполнения РефалАБ-программ не требуется ни LLVM MinGW-w64, ни clang.

РефалАБ-система представляет собой совокупность следующих файлов:

В комплект поставки исходников РефалАБ-системы входят:

4.1. Сборка РефалАБ-системы

4.1.1. Windows

Чтобы собрать РефалАБ-систему в Windows из исходников РефалАБ-системы, требуется LLVM Mingw-w64 (LLVM 18.1.8 или позже (POSIX threads) UCRT Runtime).

32-битная версия LLVM Mingw-w64 i686 позволяет собрать 32-битную РефалАБ-систему.

64-битная версия LLVM Mingw-w64 x86_64 позволяет собрать 64-битную РефалАБ-систему.

В процессе сборки РефалАБ-системы необходимо, чтобы папка {MinGW-w64}\bin ({MinGW-w64} - путь к папке, где находится LLVM MinGW-w64) была в переменной окружения PATH.

Распакуйте исходники РефалАБ-системы в любую директорию X. Перейдите в папку refalab:

cd X\refalab

Запустите процесс сборки:

mingw32-make

Чтобы посмотреть доступный список команд mingw32-make выполните:

mingw32-make help

Результатом сборки будут:

  1. РефалАБ-компиляторы bin\refalabc.exe и bin\refalabc_dbg.exe (режим отладки).
  2. интерпретаторы из промежуточного языка - ‘языка сборки’, выделенные как множества объектных модулей в библиотеках lib\librefalab.a и lib\librefalab_dbg.a (режим отладки).
  3. объектные файлы - lib\obj\refalab_initiator.o (для запуска РефалАБ-программы), lib\obj\refalab_initiator_dbg.o (для запуска РефалАБ-программы в режиме отладки), lib\obj\refalab_debugger.o (для запуска отладчика РефалАБ-программы) и lib\obj\refalab_debugger_dbg.o (для запуска отладчика РефалАБ-программы в режиме отладки).

Для проверки правильности сборки РефалАБ-системы необхоимо запустить тестовые примеры. Запустите, находясь в X\refalab, скрипт refalabclg.bat:

refalabclg tests\{name}

где

{name} := hello | fact | test0..test5

Для работы примера “fact” (факториал n) вы должны ввести целое число n.

Введите 0 или пустую строку для выхода.

Обратите внимание на то, что завершающие сообщения “Recognition impossible” для примеров test1, test4 и test5 являются правильными, поскольку в этих тестах имеются фрагменты на проверку неотождествления.

По необходимости, можно запустить тестовые примеры, используя refalabclg_dbg.bat для запуска в режиме отладки, refalabdclg.bat для запуска отладчика, refalabdclg_dbg.bat для запуска отладчика в режиме отладки.

4.1.2. POSIX

Чтобы собрать РефалАБ-систему в POSIX-совместимой ОС из исходников РефалАБ-системы, требуется clang 18.1.8 или позже.

32-битная версия clang позволяет собрать 32-битную РефалАБ-систему.

64-битная версия clang позволяет собрать 64-битную РефалАБ-систему.

Распакуйте исходники РефалАБ-системы в любую директорию X. Перейдите в папку refalab:

cd X/refalab

Запустите процесс сборки:

make

Чтобы посмотреть доступный список команд make выполните:

make help

Результатом сборки будут:

  1. РефалАБ-компиляторы bin/refalabc и bin/refalabc_dbg (режим отладки).
  2. интерпретаторы из промежуточного языка - ‘языка сборки’, выделенные как множества объектных модулей в библиотеках lib/librefalab.a и lib/librefalab_dbg.a (режим отладки).
  3. объектные файлы - lib/obj/refalab_initiator.o (для запуска РефалАБ-программы), lib/obj/refalab_initiator_dbg.o (для запуска РефалАБ-программы в режиме отладки), lib/obj/refalab_debugger.o (для запуска отладчика РефалАБ-программы) и lib/obj/refalab_debugger_dbg.o (для запуска отладчика РефалАБ-программы в режиме отладки).

Для проверки правильности сборки РефалАБ-системы необхоимо запустить тестовые примеры. Запустите, находясь в X/refalab, скрипт refalabclg:

./refalabclg tests/{name}

где

{name} := hello | fact | test0..test5

Для работы примера “fact” (факториал n) вы должны ввести целое число n.

Введите 0 или пустую строку для выхода.

Обратите внимание на то, что завершающие сообщения “Recognition impossible” для примеров test1, test4 и test5 являются правильными, поскольку в этих тестах имеются фрагменты на проверку неотождествления.

По необходимости, можно запустить тестовые примеры, используя refalabclg_dbg для запуска в режиме отладки, refalabdclg для запуска отладчика, refalabdclg_dbg для запуска отладчика в режиме отладки.

4.2. РефалАБ-система на ПК

4.2.1. Windows

На ПК с Windows РефалАБ-система хранится в следующих файлах:

Для компиляции и компоновки РефалАБ-программ необходимо, чтобы папка {MinGW-w64}\bin ({MinGW-w64} - путь к папке, где находится LLVM MinGW-w64) была в переменной окружения PATH.

32-битная РефалАБ-система создает 32-битные исполняемые файлы РефалАБ-программ с расширением exe и требует 32-битной версии LLVM Mingw-w64 i686.

64-битная РефалАБ-система создает 64-битные исполняемые файлы РефалАБ-программ с расширением exe и требует 64-битной версии LLVM Mingw-w64 x86_64.

Находясь в refalab, запустив скрипт refalabco.bat, можно скомпилировать РефалАБ-модуль в объектный файл. Имя файла, содержащего РефалАБ-модуль (без указания расширения “.ref”), является параметром при вызове этого командного файла:

refalabco имя_файла

Находясь в refalab, запустив скрипт refalabco_dbg.bat, можно скомпилировать РефалАБ-модуль в объектный файл в режиме отладки. Имя файла, содержащего РефалАБ-модуль (без указания расширения “.ref”), является параметром при вызове этого командного файла:

refalabco_dbg имя_файла

Находясь в refalab, запустив скрипт refalabclg.bat, можно скомпилировать, скомпоновать и запустить РефалАБ-программу в обычном режиме. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

refalabclg имя_файла

Находясь в refalab, запустив скрипт refalabclg_dbg.bat, можно скомпилировать, скомпоновать и запустить РефалАБ-программу в режиме отладки. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

refalabclg_dbg имя_файла

Находясь в refalab, запустив скрипт refalabdclg.bat, можно скомпилировать, скомпоновать и запустить отладчик РефалАБ-программы. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

refalabdclg имя_файла

Находясь в refalab, запустив скрипт refalabdclg_dbg.bat, можно скомпилировать, скомпоновать и запустить отладчик РефалАБ-программы в режиме отладки. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

refalabdclg_dbg имя_файла

Необходимые изменения (например, если требуется задать другой список опций или компоновать программу из нескольких РефалАБ-модулей) можно внести в эти скрипты при помощи любого текстового редактора.

Можно запустить и проверить работу тестовых примеров. Запустите, находясь в refalab, скрипт refalabclg.bat:

refalabclg tests\{name}

где

{name} := hello | fact | test0..test5

Для работы примера “fact” (факториал n) вы должны ввести целое число n.

Введите 0 или пустую строку для выхода.

Обратите внимание на то, что завершающие сообщения “Recognition impossible” для примеров test1, test4 и test5 являются правильными, поскольку в этих тестах имеются фрагменты на проверку неотождествления.

По необходимости, можно запустить тестовые примеры, используя refalabclg_dbg.bat для запуска в режиме отладки, refalabdclg.bat для запуска отладчика, refalabdclg_dbg.bat для запуска отладчика в режиме отладки.

Можно установить переменные окружения РефалАБ для облегчения компиляции и компоновки РефалАБ-программ.

Для этого, находясь в refalab, запустите скрипт set_env.bat.

После этого будут созданны следующие переменные окружения ({refalab} - путь к папке refalab без пробелов):

  1. %REFALABBIN%={refalab}\bin
  2. %REFALABLIB%={refalab}\lib
  3. %REFALABINCLUDE%={refalab}\include
  4. %REFALABLLFLAGS%=”-O2 -Wno-override-module”
  5. %REFALABLLFLAGS_DBG%=”-O0 -g -Wno-override-module”
  6. %REFALABCFLAGS%=”-pipe -Wall -O2”
  7. %REFALABCFLAGS_DBG%=”-pipe -Wall -O0 -g -Dmdebug”
  8. %REFALABLFLAGS%=”{refalab}\lib\obj\refalab_initiator.o -L{refalab}\lib -lrefalab -pthread”
  9. %REFALABLFLAGS_DBG%=”{refalab}\lib\obj\refalab_initiator_dbg.o -L{refalab}\lib -lrefalab_dbg -pthread”
  10. %REFALABLFLAGS_DEBUGGER%=”{refalab}\lib\obj\refalab_debugger.o -L{refalab}\lib -lrefalab -pthread”
  11. %REFALABLFLAGS_DEBUGGER_DBG%=”{refalab}\lib\obj\refalab_debugger_dbg.o -L{refalab}\lib -lrefalab_dbg -pthread”

По необходимости, можно добавить папку {refalab}\bin в переменную окружения PATH.

В случае необходимости удаления переменных окружения РефалАБ, необходимо, находясь в refalab, запустить скрипт del_env.bat.

4.2.2. POSIX

На ПК с POSIX-совместимой ОС РефалАБ-система хранится в следующих файлах:

32-битная РефалАБ-система создает 32-битные исполняемые файлы РефалАБ-программ и требует 32-битной версии clang.

64-битная РефалАБ-система создает 64-битные исполняемые файлы РефалАБ-программ и требует 64-битной версии clang.

Находясь в refalab, запустив скрипт refalabco, можно скомпилировать РефалАБ-модуль в объектный файл. Имя файла, содержащего РефалАБ-модуль (без указания расширения “.ref”), является параметром при вызове этого командного файла:

./refalabco имя_файла

Находясь в refalab, запустив скрипт refalabco_dbg, можно скомпилировать РефалАБ-модуль в объектный файл в режиме отладки. Имя файла, содержащего РефалАБ-модуль (без указания расширения “.ref”), является параметром при вызове этого командного файла:

./refalabco_dbg имя_файла

Находясь в refalab, запустив скрипт refalabclg, можно скомпилировать, скомпоновать и запустить РефалАБ-программу в обычном режиме. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

./refalabclg имя_файла

Находясь в refalab, запустив скрипт refalabclg_dbg, можно скомпилировать, скомпоновать и запустить РефалАБ-программу в режиме отладки. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

./refalabclg_dbg имя_файла

Находясь в refalab, запустив скрипт refalabdclg, можно скомпилировать, скомпоновать и запустить отладчик РефалАБ-программы. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

./refalabdclg имя_файла

Находясь в refalab, запустив скрипт refalabdclg_dbg, можно скомпилировать, скомпоновать и запустить отладчик РефалАБ-программы в режиме отладки. Имя файла, содержащего РефалАБ-программу с одним модулем (без указания расширения “.ref”), является параметром при вызове этого командного файла:

./refalabdclg_dbg имя_файла

Необходимые изменения (например, если требуется задать другой список опций или компоновать программу из нескольких РефалАБ-модулей) можно внести в эти скрипты при помощи любого текстового редактора.

Можно запустить и проверить работу тестовых примеров. Запустите, находясь в refalab, скрипт refalabclg:

./refalabclg tests/{name}

где

{name} := hello | fact | test0..test5

Для работы примера “fact” (факториал n) вы должны ввести целое число n.

Введите 0 или пустую строку для выхода.

Обратите внимание на то, что завершающие сообщения “Recognition impossible” для примеров test1, test4 и test5 являются правильными, поскольку в этих тестах имеются фрагменты на проверку неотождествления.

По необходимости, можно запустить тестовые примеры, используя refalabclg_dbg для запуска в режиме отладки, refalabdclg для запуска отладчика, refalabdclg_dbg для запуска отладчика в режиме отладки.

Можно установить переменные окружения РефалАБ для облегчения компиляции и компоновки РефалАБ-программ.

Для этого, находясь в refalab, запустите скрипт set_env.

source ./set_env

После этого будут созданны следующие переменные окружения ({refalab} - путь к папке refalab без пробелов):

  1. $REFALABBIN={refalab}/bin
  2. $REFALABLIB={refalab}/lib
  3. $REFALABINCLUDE={refalab}/include
  4. $REFALABLLFLAGS=”-O2 -Wno-override-module”
  5. $REFALABLLFLAGS_DBG=”-O0 -g -Wno-override-module”
  6. $REFALABCFLAGS=”-pipe -Wall -O2 -DPOSIX”
  7. $REFALABCFLAGS_DBG=”-pipe -Wall -O0 -g -Dmdebug -DPOSIX”
  8. $REFALABLFLAGS=”{refalab}/lib/obj/refalab_initiator.o -L{refalab}/lib -lrefalab”
  9. $REFALABLFLAGS_DBG=”{refalab}/lib/obj/refalab_initiator_dbg.o -L{refalab}/lib -lrefalab_dbg”
  10. $REFALABLFLAGS_DEBUGGER=”{refalab}/lib/obj/refalab_debugger.o -L{refalab}/lib -lrefalab”
  11. $REFALABLFLAGS_DEBUGGER_DBG=”{refalab}/lib/obj/refalab_debugger_dbg.o -L{refalab}/lib -lrefalab_dbg”

Эти переменные можно использовать в текущей оболочке и во всех процессах, запускаемых из текущей оболочки.

Чтобы сделать их постоянными, необходимо добавить в файл .bashrc (или аналог) директории $HOME строки:

export REFALABBIN={refalab}/bin
export REFALABLIB={refalab}/lib
export REFALABINCLUDE={refalab}/include
export REFALABLLFLAGS="-O2 -Wno-override-module"
export REFALABLLFLAGS_DBG="-O0 -g -Wno-override-module"
export REFALABCFLAGS="-pipe -Wall -O2 -DPOSIX"
export REFALABCFLAGS_DBG="-pipe -Wall -O0 -g -Dmdebug -DPOSIX"
export REFALABLFLAGS="{refalab}/lib/obj/refalab_initiator.o -L{refalab}/lib -lrefalab"
export REFALABLFLAGS_DBG="{refalab}/lib/obj/refalab_initiator_dbg.o -L{refalab}/lib -lrefalab_dbg"
export REFALABLFLAGS_DEBUGGER="{refalab}/lib/obj/refalab_debugger.o -L{refalab}/lib -lrefalab"
export REFALABLFLAGS_DEBUGGER_DBG="{refalab}/lib/obj/refalab_debugger_dbg.o -L{refalab}/lib -lrefalab_dbg"

По необходимости, можно добавить папку {refalab}/bin в переменную окружения PATH.

export PATH="{refalab}/bin:$PATH"

В случае необходимости удаления постоянных переменных окружения РефалАБ, необходимо, удалить строки из файла .bashrc (или аналог) директории $HOME, которые добавлялись, чтобы сделать их постоянными.

4.3. Подготовка исходных текстов РефалАБ-программ

Любая РефалАБ-программа состоит хотя бы из одного РефалАБ-модуля, в котором определена функция GO, которая должна быть объявлена входной точкой данного модуля с помощью директивы ENTRY. В РефалАБ-программе могут быть еще РефалАБ-модули.

Исходные тексты РефалАБ-программ можно подготавливать с помощью любого редактора текстов. Тип файла (расширение у имени файла) должен быть ref.

РефалАБ-программа состоит из одного или нескольких таких файлов.

В каждом таком файле есть один РефалАБ-модуль.

Пример. Сохранить текст в файл hello.ref:

HELLO +
    START

    ENTRY Go
    EXTRN Print

    IMPL

Go      = <Print 'Hello World!'>

    END

4.4. Компиляция РефалАБ-модулей

Компиляция РефалАБ-модулей производится РефалАБ-компилятором и происходит в объектные файлы, используя компилятор clang.

За один запуск РефалАБ-компилятора обрабатывается один файл. Для компиляции необходимо выдать следующую команду:

Возможна компиляция в режиме отладки с помощью команды:

Имя_файла (возможно с указанием пути) без указания расширения “.ref”.

Список_опций либо пуст, либо имеет следующий вид:

опция_1 опция_2 ... опция_k

где опция_i - имя опции, представляющее собой цепочку литер, не содержащую пробелов. Имена опций отделяются друг от друга пробелами.

Список_опций служит для установки режимов работы компилятора. Допускаются следующие имена опций:

Вначале РефалАБ-компилятор генерирует .ll-файл в коде LLVM с именем имя_файла.ll. Потом компилятор запускает clang для компиляции .ll-файла в объектный файл:

clang -c имя_файла.ll [options]

При компиляции clang .ll-файла в объектный файл будет возникать предупреждение:

warning: overriding the module target triple with <target name> [-Woverride-module]
1 warning generated.

Чтобы подавить это предупреждение необходимо в options добавить -Wno-override-module:

-l,"-Wno-override-module"

Пример 1

$REFALABBIN/refalabc test1 -l,"-o test1.o"

Компилируется модуль из файла test1.ref. Исходный текст модуля с диагностикой выдается в файл test1.lst. Результат работы компилятора - файл test1.o.

Пример 2

$REFALABBIN/refalabc test2 -ns

Компилируется модуль из файла test2.ref. Листинг не выводится. Результат работы компилятора - файл test2.o или test2.obj.

Пример 3

$REFALABBIN/refalabc test3 -ll

Компилируется модуль из файла test3.ref. Исходный текст модуля с диагностикой выдается в файл test3.lst. Результат работы компилятора - файл test3.ll.

На терминал выводится протокол работы компилятора, который содержит имя компилируемого модуля, его длину, длину файла-результата или сообщения об ошибках, если таковые обнаруживаются в процессе компиляции, время компиляции.

Для компиляции РефалАБ-модуля в объектный модуль необходимо выполнить команду:

Для компиляции РефалАБ-модуля в объектный модуль в режиме отладки необходимо выполнить команду:

ЗАМЕЧАНИЯ:

4.5. Компиляция модулей первичных функций на Си

РефалАБ-программа может использовать не только библиотечные первичные функции, но и собственные. Такие функции находятся в модулях первичных функций. Они написаны на языке Си, поэтому имеют расширение “.c”.

В начале модуля находится директива

#include "refalab.h"

“refalab.h” - это файл заголовков для разработчиков из папки include, который содержит объявления структур, макросов, переменных и функций, необходимых для написания собственных первичных функций и программ на Си.

Потом идут описания собственных первичных функций.

Для компиляции модуля первичных функций в объектный модуль необходимо выполнить команду:

Для компиляции модуля первичных функций в объектный модуль в режиме отладки необходимо выполнить команду:

4.6. Исполнение РефалАБ-программ

Создание исполняемого файла РефалАБ-программы производится компоновкой объектных модулей, полученных компиляцией РефалАБ-модулей и модулей первичных функций, с помощью редактора связей (компоновщика) через запуск компилятора языка Си clang.

Для создания исполняемого файла РефалАБ-программы, который запускает РефалАБ-программу, необходимо скомпоновать необходимые объектные модули с объектным файлом refalab_initiator.o и библиотекой librefalab.a, скомпилированными из программы и модулей на Си и РефалАБ-модулей, причем РефалАБ-программа вызывается из refalab_initiator.o по имени GO. Данная компоновка производится следующей командой:

где имя_файла1 … имя_файлаn - имена объектных модулей, полученных компиляцией РефалАБ-модулей и модулей первичных функций.

Если вызвать исполняемый файл имя_файла, то начнет работать программа refalab_initiator, которая формирует начальное поле зрения вида <GO> и запускает РефалАБ-машину.

Допустим, что требуется запустить РефалАБ-машину, начиная с функции JOB. Тогда в РефалАБ-программе должно быть предложение вида

GO = <JOB>

Если РефалАБ-машина останавливается не по причине нормального останова, то перед завершением работы выводится сообщение о причине останова, количество шагов, поле зрения, копилка, размер списковой памяти в звеньях и байтах, время работы интерпретатора языка сборки.

Команды компиляции, компоновки и запуска можно собрать вместе:

Для создания исполняемого файла РефалАБ-программы, который запускает РефалАБ-программу в режиме отладки, необходимо при компоновке заменить библиотеку librefalab.a на библиотеку librefalab_dbg.a, а объектный файл refalab_initiator.o на refalab_initiator_dbg.o:

где имя_файла1_dbg … имя_файлаn_dbg - имена объектных модулей, полученных компиляцией РефалАБ-модулей в режиме отладки и модулей первичных функций в режиме отладки.

Отличие режима отладки от обычного режима в том, что в режиме отладки выводится отладочная информация. И, если РефалАБ-машина останавливается по причине нормального останова, то перед завершением работы выводится сообщение “Concretization is executed”, количество шагов, поле зрения, копилка, размер списковой памяти в звеньях и байтах, время работы интерпретатора языка сборки.

4.7. Средства отладчика

4.7.1. Вызов отладчика

Для отладки РефалАБ-программы используется отладчик РефалАБ-программы.

Для создания исполняемого файла отладчика РефалАБ-программы, который запускает отладчик РефалАБ-программы, необходимо скомпоновать необходимые объектные модули с объектным файлом refalab_debugger.o и библиотекой librefalab.a, скомпилированными из программы и модулей на Си и РефалАБ-модулей, причем отладчик вызывается из refalab_debugger.o, а отладчик вызывает РефалАБ-программу по имени GO. Данная компоновка производится следующей командой:

где имя_файла1 … имя_файлаn - имена объектных модулей, полученных компиляцией РефалАБ-модулей и модулей первичных функций.

Для создания исполняемого файла отладчика РефалАБ-программы, который запускает отладчик РефалАБ-программы в режиме отладки, необходимо при компоновке заменить библиотеку librefalab.a на библиотеку librefalab_dbg.a, а объектный файл refalab_debugger.o на refalab_debugger_dbg.o:

где имя_файла1_dbg … имя_файлаn_dbg - имена объектных модулей, полученных компиляцией РефалАБ-модулей в режиме отладки и модулей первичных функций в режиме отладки.

Отличие режима отладки от обычного режима в том, что в режиме отладки выводится отладочная информация.

После вызова исполняемого файла начинает работать программа refalab_debugger. Она выдает приглашения, в ответ на которые пользователь должен задать управляющую информацию. Затем refalab_debugger анализирует полученную информацию. Если при этом обнаруживаются ошибки, работа refalab_debugger заканчивается. Если же ошибок нет, начинается исполнение РефалАБ-программы.

Выдается 11 приглашений:

> (function list):
>= (function list):
= (function list):
!= (function list):
< (function list):
<= (function list):
TRAP (function list):
STOP (step number):
FROM (step number):
TO (step number):
E._= (y/n):

Управляющая информация, задаваемая в ответ на эти приглашения, делится на две группы:

Вся она имеет один из двух форматов:

Обратите внимание, что список имен функций задается через пробел и через запятую.

В качестве имени рефал-функции можно употреблять также литеру “%”. Такое имя изображает множество всех имен символов-ссылок. Таким образом, все символы-ссылки с точки зрения управления прокруткой являются как бы одной функцией.

4.7.2. Управление остановом

В отладчике РефалАБ-программы имеются средства управления остановом двух типов: STOP-условия, которые позволяют задавать останов по номеру шага, и TRAP-условия, которые позволяют задавать останов по имени функции.

Если в ответ на приглашение:

STOP (step number):

ввести целое число N, то работа РефалАБ-программы прекратится, как только будет выполнено N шагов. Например, если задано

STOP (step number): 30000

то РефалАБ-программа остановится перед началом выполнения шага 30001. Эта возможность полезна в тех случаях, когда отлаживаемая программа зацикливается.

Если STOP не задан, то STOP = 2147483647.

Если в ответ на приглашение

TRAP (function list):

ввести список имен функций

F1 F2 ... Fn

то это будет означать, что когда ведущим станет функциональный терм вида <F1 E.e> или <F2 E.e> и т.д., РефалАБ-программа остановится, не приступая к выполнению очередного шага (здесь F1, F2 … Fn - функции, объявленные ловушками, а Ee - объектное выражение).

Эта возможность полезна в тех случаях, когда требуется выдать состояние поля зрения, копилки и ящиков в момент обращения к одной из функций-ловушек.

Если TRAP-условие задано вместе со STOP-условием, останов произойдет как только будет удовлетворено хотя бы одно из условий.

4.7.3. Управление прокруткой

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

При выдаче информации об отдельном шаге указываются:

При выдаче информации об обращениях к заданным функциям указывается:

Задание на прокрутку может быть двух видов:

Диапазон прокрутки задается с помощью приглашений

FROM (step number):
TO (step number):

в ответ на которые нужно ввести целые числа Nf и Nt.

Задание диапазона означает, что следует выдавать информацию только о тех шагах, номера которых лежат в интервале от Nf до Nt. Выдача информации о тех шагах, номера которых меньше Nf или больше Nt - запрещена. В частности, если Nf>Nt, то никакая информация выдаваться не будет.

Если Nf не задавать, но задать Nt, или хотя бы одно условие прокрутки, то считается, что Nf=1.

Если же задание “TO” не установлено, но определено задание “FROM” или хотя бы одно условие прокрутки, то считается, что Nt=2147483647, т.е. практически “бесконечность”.

Таким образом, если диапазон прокрутки не задан, но задано хотя бы одно условие прокрутки, то Nf=1 и Nt=2147483647.

Если диапазон прокрутки не пуст, и не задано ни одного условия прокрутки, то считается, что следует выдавать информацию обо всех шагах, лежащих в этом диапазоне.

Приведем примеры заданий на прокрутку, состоящих только из указания диапазона.

Пример 1

FROM (step number): 1

Печатается информация обо всех шагах.

Пример 2

FROM (step number): 1000

Печатается информация обо всех шагах, начиная с шага 1000.

Пример 3

TO (step number): 5000

Печатается информация обо всех шагах, начиная с шага 1 до шага 5000 включительно.

Пример 4

FROM (step number): 500
TO (step number): 600

Печатается информация обо всех шагах, начиная с шага 500 до шага 600 включительно.

Теперь рассмотрим, как задаются условия прокрутки.

В то время как диапазон прокрутки накладывает ограничения на номера шагов, для которых должна выдаваться информация, условия прокрутки указывают, какую именно информацию и о каких функциях следует выдавать.

Условия прокрутки задаются в ответ на приглашения:

> (function list):
>= (function list):
= (function list):
!= (function list):
< (function list):
<= (function list):

в виде списка функций F1 F2 … Fn.

Список функций, в частности, может быть пустым. Под именем функции подразумевается то имя, которое она имеет внутри того модуля, в котором она описана, имена функций в списке функций разделяются пробелом или запятой.

Смысл управляющей информации:

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

Например:

> (function list): FUNC1 FUNC2
>= (function list): FUNC
= (function list): PSI FI
!= (function list): FI EPS
< (function list): XXX
<= (function list): YYY

Если в приведенном примере FUNC1 вызывает XXX и YYY, то будет выдаваться информация о работе FUNC1 и обо всех вызываемых ею функцций, исключая XXX и YYY, причем об XXX информации не будет никакой, а для YYY будет выдан шаг обращения к ней и сформированное ею поле зрения.

В общем случае условия прокрутки следующим образом истолковываются в процессе исполнения РефалАБ-программы.

Управление прокруткой может находиться в одном из трех состояний: S1, S2 или S3. Оно может переходить из состояния S1 в состояние S2 и обратно, а также из состояния S2 в состояние S3 и обратно. Непосредственный переход из S1 в S3 или из S3 в S1 - невозможен.

Переходами между состояниями S1 и S2 управляют условия “>” и “>=”. Переходами между состояниями S2 и S3 управляют условия “<” и “<=”. Условия “=” и “!=” управляют выдачей информации в состоянии S2. Таким образом, получается следующая схема переходов:

                    =,!=
------   >,>=      ------   <,<=     ------
|    |  ------>    |    |  ------>   |    |
| S1 |             | S2 |            | S3 |
|    |  <------    |    |  <------   |    |
------             ------            ------

В начале работы прокрутка находится в состоянии S1.

Находясь в состоянии S1, прокрутка выполняет РефалАБ-программу до тех пор, пока не встретится обращение к функции, для которой было задано одно из условий “>” или “>=”. Тогда прокрутка переходит в состояние S2, причем, если задано “>=”, но не задано “>”, то выдается обращение к этой функции.

Возврат в состояние S1 происходит только после того, как полностью закончится вычисление обращения к функции, по которому произошел переход из S1 в S2. При этом, если для этой функции было задано “>=”, но не задано “>”, то при возврате в S1 выдается окончательный результат замены, т.е. то выражение, которое возникло в результате полного вычисления обращения к функции.

Находясь в состоянии S2, прокрутка выполняет РефалАБ-программу до тех пор, пока не встретится обращение к функции, для которой было задано условие “<” или “<=”. Тогда прокрутка переходит в состояние S3, причем, если задано “<=”, то выдается обращение к этой функции.

Возврат в состояние S2 из состояния S3 происходит только после того, как полностью закончится вычисление обращения к функции, по которому произошел переход в S3 из S2. При этом, если для этой функции было задано “<=”, но не задано “<”, то при возврате в S2 выдается окончательный результат замены, т.е. то выражение, которое возникло в результате полного вычисления обращения к функции.

Если прокрутка находится в состоянии S2, и для текущей функции не задано ни “<”, ни “<=”, то прокрутка выполняет один шаг и остается в состоянии S2. При этом, если для текущей функции задано условие “=”, то выдается обращение к функции и результат непосредственной замены (результат выполнения шага).

Например, если заданы условия

>= X
= Y1 Y2 Y3
<= Z1 Z2

то выдача будет начинаться при каждом обращении к функции X. Будет выдаваться обращение к X и результат ее полного вычисления. В процессе вычисления X будут выдаваться обращения к Y1, Y2, Y3 и непосредственно результаты замены, а также обращения к Z1 и Z2 и результат полного вычисления этих обращений.

Иногда требуется, чтобы выдавались только обращения к указанным функциям и окончательные результаты замены. Этого можно добиться, задав для них условия “=” и “<=”.

Если задать только условие “<=”, то будет выдаваться информация о всей программе, а о заданных функциях - только обращение к ним и результат их работы.

И, наконец, в тех случаях, когда требуется запустить прокрутку по всем функциям, с первого шага до последнего, можно задать условие “!=” для несуществующей функции.

4.7.4. Перехват останова по неотождествлению

Легкость отладки РефалАБ-программ в значительной степени обусловлена тем, что различные нарушения в структуре обрабатываемых объектов, как правило, довольно быстро приводят к авосту “Отождествление невозможно”. Однако это приятное свойство утрачивается, если какие-либо функции, написанные на Си, не проверяют правильность аргумента. Поэтому при отладке функций, написанных на Си, необходимо тщательно тестировать как те случаи, когда обращение к функции имеет допустимый вид, так и те случаи, когда аргумент функции задан неверно. Всегда, когда аргумент не принадлежит к области определения функции, эта функция должна вырабатывать авост “Отождествление невозможно”.

Таким образом, всякий тест, предназначенный для проверки функций, написанных на Си, должен включать как правильные, так и заведомо неправильные обращения к этим функциям.

Для прогона таких тестов предусмотрен особый режим “E._=”. Если РефалАБ-программа исполняется в этом режиме, то при возникновении состояния “Отождествление невозможно” выполнение РефалАБ-программы не прекращается. Вместо этого выдается номер текущего шага, предупреждающее сообщение и ведущий функциональный терм. Затем ведущий терм заменяется на пустое выражение, и работа РефалАБ-программы продолжается.

Таким образом, РефалАБ-программа исполняется так, словно в конце каждой функции добавлено предложение

E._ =

Этому обстоятельству режим “E._=” и обязан своим названием.

Для того, чтобы РефалАБ-программа исполнялась в режиме “E._=”, необходимо в ответ на приглашение

E._= (y/n):

ответить “y”.