Язык процедур 2-REXX для OS-2

Инструкции

Инструкция приказывает системе выполнить какое-либо действие. Инструкции могут содержать одно или несколько присваиваний, меток или команд и, как правило, начинаются с новой строки. Далее приводятся краткие описания и примеры общеупотребительных инструкций.
Инструкция SAY - Формат инструкции SAY следующий:
SAY выражение
Выражение представляет собой какое-либо сообщение, которое Вы хотите вывести на экран, либо арифметическое выражение, которое должно быть вычислено, как, например, в следующем уравнении:
SAY 5 + 6 "= одиннадцать"
На экран будет выведено
11 = одиннадцать
Все символы в инструкции SAY, не заключенные в кавычки, преобразуются в прописные буквы или обрабатываются. Поэтому, если нужно вывести сообщение именно так, как оно набрано, то заключите его в кавычки.
Инструкции PULL и PARSE PULL - Обычная последовательность инструкций в процедуре - SAY для задания вопроса, а затем PULL для получения ответа. Ответ, введенный пользователем, помещается в память системы. Процедура, текст которой приведен ниже, выполнится некорректно, если инструкция PULL будет предшествовать инструкции SAY.
Вопрос: Что произойдет, если выполнится процедура NAME.CMD, текст которой приведен ниже?
/* Использование инструкции PULL */ SAY "Введите Ваше имя" PULL name /* Помещает ответ пользователя в память */ SAY "Привет" name EXIT
Ответ: NAME.CMD помещает введенное имя в память, а затем выводит это имя без кавычек в любом месте файла, где появится слово name.
Если Вы выполните процедуру NAME, то, возможно, заметите, что все буквы имени преобразуются в прописные. Чтобы сохранить символы в том виде, в каком они были набраны, используйте инструкцию PARSE PULL. Ниже приведен пример процедуры CHITCHAT.CMD, которая использует эту инструкцию:
/* Использование инструкции PARSE PULL */ SAY "Привет! Вы все еще там?" SAY "Я забыл Ваше имя. Как Вас зовут?" PARSE PULL name SAY name "Вы собираетесь на семинар к Ричарду?" PULL answer IF answer = "YES" THEN SAY "Хорошо. Увидимся там!" IF answer = "NO" THEN SAY "Как жаль, мы пропустим Ваше сообщение." EXIT
Инструкция PARSE PULL считывает все символы, введенные с клавиатуры так, как они были набраны, строчными или прописными. В приведенной процедуре имя выводится так, как Вы его ввели. Однако символы, помещенные в поле answer, преобразуются в прописные, поскольку при этом используется инструкция PULL. Это гарантирует, что какой бы Вы ответ ни ввели, yes, Yes или YES, будет выполнено одно и то же действие.
Инструкция EXIT - Инструкция EXIT прекращает выполнение процедуры. Эта инструкция должна использоваться в процедурах, содержащих подпрограммы. Несмотря на то, что инструкция EXIT необязательна для некоторых процедур, использование ее в конце каждой процедуры - признак хорошего стиля программирования.


Использование основных элементов языка REXX

В этом разделе пользователю предоставляется возможность ознакомиться с некоторыми элементами, используемыми при написании процедур REXX. Не беспокойтесь том, что при программировании могут быть ошибки, так как в этом разделе информация излагается последовательно по шагам.
Прим. При написании процедур REXX рекомендуется для каждого элемента использовать отдельную строку. Если Вы хотите расположить элемент в нескольких строках, то поставьте запятую (,) в конце строки. Это обозначает, что элемент продолжается на следующей строке. Если же нужно поместить несколько элементов в одной строке, то разделите их точкой с запятой (;).

В процедурах REXX могут быть любые или все перечисленные ниже элементы:



  • в дальнейшем REXX) разработан как

    Язык процедур 2/REXX для OS/2* (именуемый в дальнейшем REXX) разработан как язык процедур Systems Application Architecture* для семейства продуктов типа Office Vision и операционной системы OS/2. Он предназначен для того, чтобы облегчить программирование в стадии кодирования и отладки. Высокое качество программирования может быть достигнуто при использовании общепринятых слов английского языка в синтаксисе языка процедур, что одинаково понятно как начинающему, так и опытному программисту.

    REXX использует ряд мощных программных функций общего назначения и стандартные арифметические возможности наряду с командами OS/2 в простой конструкции. Существующие пакетные файлы могут быть преобразованы в процедуры REXX, обладающие большими функциональными возможностями.

    Процедуры REXX выполняются только в сеансах OS/2, они должны иметь расширение файла .CMD и начинаться со строки комментария (/*....*/). Также, как и для пакетных файлов, чтобы выполнить процедуру REXX, необязательно указывать расширение .CMD.

    Приведенная информация:

    Настоящая оперативная информация по REXX предназначена для ознакомления с языком, получения сведений об его основных особенностях и возможностях, а также для формирования представления о базовых принципах его работы. Разделы от "Приступая к работе .." до "PMREXX" представляют собой краткий обзор, основанный на информации об общих концепциях REXX, в то время как разделы "Инструкции" и "Функции" содержат конкретные сведения обо всех инструкциях и функциях, которые являются частью языка. Для получения более детальной информации по языку REXX обращайтесь к документу Язык процедур 2/REXX. Справочник или Руководство пользователя.



    это слово, фраза или аббревиатура,

    Команда - это слово, фраза или аббревиатура, которые приказывают системе выполнить определенные действия. В языке REXX все, что не является инструкцией REXX, оператором присваивания или меткой, рассматривается как команда. Например, в процедурах REXX можно использовать такие команды OS/2, как COPY, BACKUP, PRINT, TYPE и т.д.

    Ниже приводится пример использования команды OS/2 TYPE в процедуре REXX:

    /* Использование команд в процедуре REXX */ TYPE hello.cmd EXIT

    Это означает, что REXX инициирует выполнение команды TYPE.



    Все процедуры REXX должны начинаться

    Все процедуры REXX должны начинаться комментарием, расположенным с первой позиции первой строки файла. Комментарий указывает процессору команд, что программа, которую нужно прочитать и выполнить, - это процедура REXX. Для обозначения комментария используются следующие символы:
    /* Отмечает начало комментария
    */ Отмечает конец комментария
    Когда интерпретатор команд находит символ /*, он прекращает интерпретацию; если же он встречает символ */, интерпретация начинается с информации, следующей за этим символом. Комментарий может содержать несколько слов, несколько строк или вообще не содержать информации, т.е. состоять из пустого элемента, как показано на следующих примерах:
    /* Это комментарий. */ или
    SAY "'Будьте готовы!'" /* Этот комментарий расположен в той же строке, что и инструкция, и продолжается на следующей строке */
    В начале процедуры REXX можно использовать комментарий типа /* */, однако гораздо предпочтительнее помещать в качестве комментария краткое описание процедуры.
    Комментарий может отражать назначение данной процедуры, способ ввода информации, вывода результатов работы и т.д. Комментарии помогают быстрее разобраться в процедуре, когда Вы будете читать ее спустя некоторое время. Комментарии можно добавлять, улучшать или использовать в разных частях этой или другой процедуры.
    При написании процедуры не забывайте, что кто-то будет ее использовать и, возможно, ее потребуется модифицировать. Поэтому добавление комментариев к инструкциям помогает понять каждый шаг процедуры. Если к тому же процедура используется достаточно редко, то комментарии позволяют самому разработчику быстро освежить в памяти ее назначение. Вообще говоря, процедура должна быть прокомментирована достаточно хорошо, чтобы быть понятной всем, кто будет ею пользоваться.


    Метки

    В качестве метки может выступать любое слово, за которым следует двоеточие (между словом и двоеточием не должно быть пробелов) и которое не заключено в кавычки. Например:
    MYNAME:
    Метка отмечает начало подпрограммы. Ниже приведен пример использования метки error внутри процедуры:
    . . . IF problem = 'yes' then SIGNAL error . . . error: SAY 'Ошибка в данных' EXIT





    Написание процедур

    Напишем следующую процедуру REXX с помощью текстового редактора. Чтобы написать процедуру REXX с именем HELLO.CMD, выполните следующие инструкции:
    1. Создайте текстовый файл с именем HELLO.CMD.
    2. Наберите текст процедуры HELLO.CMD, приведенной ниже:
    /* Введение в REXX */ SAY "Привет! Я - REXX" SAY "Как Вас зовут?" PULL who IF who = "" THEN SAY "Привет, Незнакомец" ELSE SAY "Привет," who EXIT
    3. Сохраните файл и выйдите из текстового редактора.
    Теперь все готово для того, чтобы выполнить эту процедуру REXX. Наберите имя процедуры в командном режиме OS/2 и нажмите клавишу ENTER.
    hello
    Когда процедура сделает паузу, Вы можете либо ввести свое имя, либо просто нажать клавишу ENTER, чтобы увидеть второй вариант ответа.
    Далее приведено краткое описание каждой части процедуры HELLO.CMD :
    /* Введение в REXX */ В этом комментарии указывается, что данная процедура выполняет. Строка комментария начинается с символа /* и заканчивается символом */. Все процедуры REXX должны начинаться с комментария в первой позиции первой строки файла. Строка комментария указывает процессору команд, что процедура, которую нужно выполнить, - это процедура REXX. По этому признаку процессор команд отличает ее от обычных пакетных файлов.
    SAY "Привет! Я - REXX." SAY "Как Вас зовут?" С помощью этих инструкций слова, заключенные в двойные кавычки, выводятся на экран.
    PULL who С помощью инструкции PULL читается ответ, введенный с клавиатуры, и помещается в память операционной системы. Who - это имя, присвоенное области памяти, куда помещается введенный пользователем ответ. В инструкции PULL можно использовать любое имя.
    IF who = " " Инструкция IF проверяет условие. В этом примере проверяется, пусто ли поле who. Оно будет пустым, если пользователь набрал пробел, а затем нажал клавишу ENTER, либо просто нажал клавишу ENTER.
    THEN Определяет, что в случае истинности проверяемого условия, должна выполняться инструкция, следующая за данной.
    SAY "Привет, Незнакомец" Выводит на экран слова Привет, Незнакомец.
    ELSE Определяет, что в случае ложности проверяемого условия должна выполняться инструкция, следующая за данной.
    SAY "Привет," who Выводит на экран слово Привет с последующим отображением содержимого поля who.
    EXIT Эта инструкция прекращает выполнение процедуры.
    Если пользователь с именем Сергей выполнит процедуру HELLO, то протокол его работы будет иметь следующий вид:
    [C:\]hello Привет! Я - REXX. Как Вас зовут?
    Сергей
    Привет, Сергей
    [C:\]
    Если Сергей не введет свое имя, а наберет пробел, то протокол работы будет следующим:
    [C:\]hello Привет! Я - REXX. Как Вас зовут?
    Привет, Незнакомец
    [C:\]


    Операторы присваивания

    Оператор присваивания сообщает системе, что цепочку символов нужно поместить в определенное поле в памяти операционной системы. Например:
    Work = "Здание 021" строка Здание 021 запоминается как значение поля Work в памяти операционной системы. Так как поле Work может принимать различные значения (переопределяться по ходу выполнения) в различных частях процедуры, то его можно назвать переменной.


    Приступая к работе с REXX

    Процедура REXX представляет собой программу, состоящую из набора заданий, заключенных в один обрабатывающий или пакетный файл.
    Для написания программ могут быть использованы многие языки программирования. BASIC, который широко используется для базовых вычислений, имеет очень ограниченный набор правил, однако при написании сложных программ требует многих строк кода. Такие языки, как PL/1, COBOL, C, APL и PASCAL имеют более обширный набор правил, но при этом позволяют в нескольких строках закодировать большее число функций.
    REXX сочетает простоту такого языка программирования, как BASIC, с возможностями более мощных языков, перечисленных выше. REXX легок в изучении, так как использует знакомые слова и понятия. При этом REXX позволяет решать как простые задачи, так и более сложные комплексные проблемы.
    Чтобы начать работу с языком REXX, необходимо иметь:
  • Персональный компьютер с инсталлированной на нем операционной системой OS/2 версии 2.0. Процедуры REXX выполняются только в сеансах OS/2.
  • Сведения об использовании текстового редактора.
    Многие изучают язык программирования, просматривая примеры, поэтому настоящий обзор сопровождается примерами процедур REXX. Сначала просмотрите процедуру, затем изучите разъяснение к примерам, чтобы понять, что содержится в процедуре. При желании можно выполнить процедуру, чтобы увидеть, как она работает.

    Строки

    Строка представляет собой цепочку символов, заключенных в апострофы или кавычки. Можно использовать любые из этих символов, но только парами. Когда интерпретатор команд встречает один из этих символов, он прекращает интерпретацию и последующие символы оставляет в таком виде, в каком они были набраны, включая строчные и прописные буквы. Когда интерпретатор команд опять встречает такой же символ, он возобновляет интерпретацию. Например:
    'Грандиознейшее Шоу на Планете' "Президент правит своей страной"
    Оба сообщения - строки.
    Чтобы использовать апостроф или кавычки внутри строки, для обрамления полной строки выберите другой символ. Например:
    "Don't count your chickens before they hatch." или
    'Do not count your "chickens" before they hatch.'
    Внутри строки можно также использовать удвоенный символ (такого же типа, как и для обрамления полной строки). Например:
    SAY "Mary said ""He's here."""
    Эту инструкцию REXX интерпретирует следующим образом:
    Mary said "He's here."


    Написание арифметических процедур REXX

    Ниже дано упражнение, позволяющее повторить некоторые правила, используемые в предыдущих примерах. Вам нужно написать процедуру, выполняющую операцию сложения двух чисел. Имя процедуры - ADD.CMD.
    В своей процедуре Вам придется выполнить следующие действия:
  • Идентифицировать и описать процедуру REXX.
  • Предложить пользователю ввести числа.
  • Прочитать введенные числа и поместить их в память системы.
  • Сложить два числа и вывести результат на экран.
  • Завершить выполнение процедуры. Существует множество способов, позволяющих выполнить поставленную задачу. Чтобы облегчить ее выполнение в данной процедуре, предложим пользователю ввести каждое число отдельно, а затем сложим эти числа. Далее приведены размышления, которые помогут Вам при написании процедуры ADD.CMD.
  • Первым делом, что идентифицирует процедуру REXX? Если Вы считаете, что это комментарий, то Вы правы.
  • Далее, нужно предложить пользователю ввести число. С помощью инструкции SAY можно вывести это предложение на экран.
  • Когда число введено, его нужно поместить в память компьютера. Инструкция PULL получает ответ и помещает его в память.
  • Инструкция, которая запрашивает ввод второго числа, может выглядеть подобно первой; второе число также должно быть помещено в память.
  • Следующая инструкция похожа на инструкцию в процедуре MATH. В одном операторе языка REXX можно приказать интерпретатору сложить два значения в памяти и вывести результат на экран. Для этого используйте одну инструкцию, которая содержит строку и операцию сложения.
  • В заключение, для завершения выполнения процедуры используйте инструкцию EXIT.
  • Если Вы хотите проверить работу этой процедуры, то наберите и сохраните текст, приведенный ниже.
    /* Эта процедура складывает два числа */ SAY "Введите первое число." PULL num1 SAY "Введите второе число." PULL num2 SAY "Сумма двух чисел равна" num1 + num2 EXIT
    Чтобы выполнить процедуру ADD.CMD, введите ADD в командном режиме OS/2, а затем введите два любых числа. Ниже приведен протокол работы этой процедуры, если Вы ввели числа 3 и 12.
    [C:\]ADD Введите первое число. 3 Введите второе число. 12 Сумма двух чисел равна 15 [C:\]





    Переменные

    Переменная представляет собой часть данных с изменяющимся значением. Каждой переменной внутри процедуры присваивается уникальное имя, по которому на нее ссылаются в дальнейшем.
    При выборе имени переменной имейте в виду, что первым символом может быть один из следующих:
    A B C...Z ! ? _
    Первым символом имени может быть и строчная буква. Интерпретатор перекодирует ее в прописную.
    Остальными символами могут быть все перечисленные символы, а также цифры от 0 до 9.


    Работа с переменными и арифметическими выражениями

    В этом разделе рассказывается о том, как использовать переменные и производить арифметические вычисления, а также как писать комментарии, поясняющие работу процедуры. Этот раздел содержит информацию по следующим темам:
    Часть данных, которой присвоено уникальное имя
    Содержание переменной
    Символы, используемые для арифметических функций
    + оператор
    - оператор
    * оператор
    /, //, % операторы



    Выполнение арифметических вычислений

    Может возникнуть необходимость включить в процедуры REXX арифметические операции сложения, вычитания, умножения и деления. Например, Вам потребуется присвоить числовые значения двум переменным и затем сложить их.
    Арифметические операции выполняются обычным образом. Вы можете использовать целые числа и десятичные дроби. Целое число - это любое натуральное число, положительное, отрицательное или ноль, которое не содержит десятичной части (например, 1, 25 или 50). Десятичная дробь содержит десятичную точку (например, 1.45 или 0.6).
    Прежде чем продемонстрировать использование этих четырех операций в процедурах, мы приведем примеры написания арифметических выражений и символов, предназначенных для каждой операции. Это будут просто некоторые арифметические операции, используемые в REXX.
    Прим. Приведенные примеры содержат пробелы между числами и операторами для того, чтобы выражение смотрелось нагляднее, однако эти пробелы необязательны.

    Операторы - Символы, используемые для арифметических операций (+, -, *, /), называются операторами. Они производят действия над соседними элементами. В следующем примере операторы производят действия над числами (элементами) 4 и 2:
    SAY 4 + 2 /* выводит "6" */ SAY 4 * 2 /* выводит "8" */ SAY 4 / 2 /* выводит "2" */

    Сложение - Оператор сложения - это знак плюс (+). Инструкция сложения двух чисел выглядит следующим образом:
    SAY 4 + 2
    Результат выполнения инструкции Вы увидите на экране, это будет число 6.

    Вычитание - Оператором вычитания - это знак минус (-). Инструкция вычитания двух чисел выглядит следующим образом:
    SAY 8 - 3
    Результатом выполнения инструкции будет число 5, которое выводится на экран.

    Умножение - Оператор умножения - это звездочка (*). Инструкция умножения двух чисел выглядит следующим образом:
    SAY 2 * 2
    Результатом выполнения инструкции будет число 4, которое выводится на экран.

    Деление - Для операции деления можно использовать несколько операторов в зависимости от того, каким Вы хотите видеть результат: в виде полного числа, либо в виде какой-то его части.
    Например, для обычной операции деления используется символ наклонной черты (/). Инструкция деления двух чисел выглядит следующим образом:

    SAY 7 / 2

    Результатом выполнения инструкции будет число 3.5, которое выводится на экран.

    Для того, чтобы получить только остаток от деления, в качестве оператора деления используйте символ, состоящий из двух наклонных черт (//). Чтобы получить только целую часть без остатка, используйте знак процента (%).



    Для просмотра примеров, демонстрирующих выполнение описанных выше арифметических действий, выберите => .

    Вычисляемые выражения - Обычно выражения вычисляются слева направо. Выражение, приведенное ниже, иллюстрирует это правило. До сих пор Вы имели дело с выражениями, содержащими один оператор и два элемента, например, 4 + 2. Предположим, что имеется следующее выражение:

    9 - 5 + 4 =

    Сначала вычисляется выражение 9 - 5. К значению выражения 4 добавляется 4 и в конечном итоге получится 8.

    Однако некоторые операции имеют приоритет перед другими. В общем случае к выражениям применимы правила алгебры. Например, в выражении, приведенном ниже, операция деления выполняется раньше операции сложения:

    10 + 8 / 2 =

    Результатом этого выражения будет число 14.

    Если в выражении Вы используете скобки, то интерпретатор сначала вычислит значение выражения в скобках. Например:

    (10 + 8) / 2 =

    Результатом данного выражения будет число 9.



    Значение

    Значение переменной, в отличие от имени, может изменяться. Когда Вы именуете переменную (придаете ей некоторое значение), то тем самым выполняете присваивание. Например, любой оператор типа
    symbol = выражение является оператором присваивания. Таким образом, Вы приказываете интерпретатору вычислить значение выражения и поместить результат в поле переменной symbol. Это эквивалентно следующему: "Присвоить переменной symbol значение результата выражения" или каждый раз, когда переменная symbol появляется в тексте строки инструкции SAY без кавычек, выводить на ее месте значение выражения. Взаимосвязь между переменной и ее значением такая же, как и между почтовым ящиком и его содержимым. Номер почтового ящика всегда один и тот же, а его содержимое может поменяться в любое время. Ниже приведен пример еще одного оператора присваивания:
    num1 = 10
    Здесь num1 имеет то же смысловое значение, что и слово symbol в предыдущем примере, а значение 10 соответствует слову выражение.
    Один из способов изменения значения переменной num1 - добавление некоторого числа или выражения к старому значению с помощью следующего оператора присваивания:
    num1 = num1 + 3
    Значение num1 теперь изменилось с 10 на 13.
    Специальным соглашением в REXX является то, что в качестве первоначального значения переменной, которой не было присвоено значение, является ее имя, выводимое прописными буквами. Например, если Вы напишете в процедуре
    list = 2 20 40 SAY list то на экран выведется следующая информация:
    2 20 40
    Таким образом, переменная list принимает значения, которые были ей присвоены. Однако, если Вы не присвоите переменной list никакого значения и просто напишете:
    SAY list то на экран выведется:
    LIST
    Ниже приведен пример простой процедуры VARIABLE.CMD, которая присваивает значения переменным:
    /* Присваивание значений переменным */ a = 'abc' SAY a b = 'def' SAY a b EXIT
    Если Вы выполните процедуру VARIABLE, то протокол работы будет выглядеть следующим образом:
    [C:\]VARIABLE abc abc def
    [C:\]
    Процесс присваивания значений прост, однако убедитесь в том, что имя, выбранное для переменной, не будет использовано непредумышленно, как показано на примере процедуры MEETING.CMD:
    /* Непреднамеренная интерпретация переменной */ the='no' SAY Here is the person I want to meet EXIT
    Протокол выполнения процедуры:
    [C:\]MEETING HERE IS no PERSON I WANT TO MEET
    [C:\]
    Чтобы предотвратить непреднамеренное замещение слова переменной, заключите предложение в кавычки, как это сделано в процедуре MEETING.CMD, которая теперь уже правильно присваивает значение переменной:
    /* Правильная интерпретация переменной the*/ the= 'no' SAY "Here is the person I want to meet" EXIT



    Инструкции SELECT, AND, WHEN, OTHERWISE и NOP

    SELECT приказывает интерпретатору выбрать одну инструкцию из перечня возможных. Она используется только вместе с WHEN, THEN, END и иногда с OTHERWISE. Инструкция END отмечает конец каждой группы SELECT. Инструкция SELECT выглядит следующим образом:
    SELECT WHEN выражение1 THEN инструкция1 WHEN выражение2 THEN инструкция2 WHEN выражение3 THEN инструкция3 ... OTHERWISE инструкция инструкция инструкция END
    Прим. Инструкцию IF-THEN нельзя использовать с инструкцией SELECT, за исключением случаев, когда она следует за инструкциями WHEN или OTHERWISE. Формат инструкции SELECT, приведенный выше, можно интерпретировать следующим образом:
  • Если выражение1 истинно, то выполняется инструкция1. После этого обработка продолжается с инструкции, следующей за END. Инструкция END отмечает конец инструкции SELECT.
  • Если выражение1 ложно, проверяется выражение2. Если выражение2 истинно, то выполняется инструкция2 и обработка продолжается с инструкции, следующей за END.
  • Тогда и только тогда, когда все указанные выражения ложны, обработка продолжается с инструкции, следующей за OTHERWISE.

  • На диаграмме, приведенной ниже, представлена наглядная структура инструкции SELECT:
    Инструкции SELECT, AND, WHEN, OTHERWISE и NOP
    Инструкцию DO-END можно включить в инструкцию SELECT следующим образом:
    SELECT WHEN выражение1 THEN DO инструкция1 инструкция2 инструкция3 END . . .
    Инструкцию SELECT применяйте для использования одной переменной, которая может принимать несколько различных значений. С каждым из этих значений можно связать выполнение различных действий.
    Допустим, Вы хотите составить памятку основных дел на неделю. Переменная day может принимать значения Понедельник - Пятница. В зависимости от дня недели (значение переменной), Вы можете вывести список дел на соответствующий день (с помощью инструкции). Процедура SELECT.CMD, приведенная ниже, решает поставленную задачу.
    Прим. Инструкция THEN или ELSE должна предшествовать инструкции, непосредственно выполняющей выбранное действие.

    /* Выбор дел на каждый день недели */ SAY 'Какой сегодня день?' Pull day SELECT WHEN day = 'ПОНЕДЕЛЬНИК' THEN SAY ' Знакомство с доской объявлений' WHEN day = 'ВТОРНИК' THEN SAY "Встреча с моей командой" WHEN day = 'СРЕДА' THEN NOP /* Нет операции */ WHEN day = 'ЧЕТВЕРГ' THEN SAY "Мой семинар" WHEN day = 'ПЯТНИЦА' THEN SAY "Рецензирование книги" OTHERWISE SAY "Выходной день, все может случиться!" END EXIT
    Инструкция NOP: Если Вы не хотите предпринимать никаких действий для определенного выражения, то используйте инструкцию NOP (No Operation), как показано в предыдущем примере для значения СРЕДА.

    Инструкция ELSE

    ELSE определяет инструкцию, которая должна быть выполнена в случае, если выражение ложно. Чтобы приказать интерпретатору выбрать одну из двух возможных инструкций, используйте следующую конструкцию: IF выражение THEN инструкция1 ELSE инструкция2
    Формат IF-THEN-ELSE можно включить и в следующую процедуру:
    IF answer = 'ДА' THEN SAY 'ХОРОШО!' ELSE SAY 'почему нет?'
    Выполните процедуру GOING.CMD, чтобы посмотреть, как на практике осуществляется выбор между двумя инструкциями:
    /* Использование IF-THEN-ELSE */ SAY "Ты собираешься на заседание?" PULL answer IF answer = "ДА" THEN SAY "Я буду тебя ждать." ELSE SAY "Я сделаю для тебя заметки." EXIT
    Ниже приведен протокол работы этой процедуры:
    [C:\]GOING Ты собираешься на заседание?
    да
    Я буду тебя ждать.
    [C:\]


    Логические операторы NOT, AND, OR

    Логические операторы могут возвращать только значения 1 или 0. Оператор NOT (¬ или \), указанный перед элементом, изменяет его значение либо с истинного на ложное, либо с ложного на истинное.
    SAY \ 0 /* выведет '1' */ SAY \ 1 /* выведет '0' */ SAY \ (4 = 4) /* выведет '0' */ SAY \ 2 /* выведет ошибку синтаксиса */ Оператор AND (&), указанный между двумя элементами, принимает значение истина только в том случае, когда оба элемента истинны.
    SAY ( 3 = 3 ) & ( 5 = 5 ) /* выведет '1' */ SAY ( 3 = 4 ) & ( 5 = 5 ) /* выведет '0' */ SAY ( 3 = 3 ) & ( 4 = 5 ) /* выведет '0' */ SAY ( 3 = 4 ) & ( 4 = 5 ) /* выведет '0' */ Оператор OR ( | ), указанный между двумя элементами, принимает значение истина, если хотя бы один элемент имеет значение истина.
    Прим. В зависимости от клавиатуры персонального компьютера и используемой кодовой страницы, Вы можете не найти сплошную вертикальную черту для оператора OR. Поэтому в качестве оператора OR REXX также распознает прерывистую вертикальную черту. Некоторые клавиатуры содержат оба этих символа. В этом случае для логического оператора OR будет использоваться только тот, который в коде ASCII имеет значение 124. Подобное несоответствие может быть причиной того, что символы на Вашей клавиатуре не идентичны символам, выводимым на экран.

    SAY ( 3 = 3 ) | ( 5 = 5 ) /* выведет '1' */ SAY ( 3 = 4 ) | ( 5 = 5 ) /* выведет '1' */ SAY ( 3 = 3 ) | ( 4 = 5 ) /* выведет '1' */ SAY ( 3 = 4 ) | ( 4 = 5 ) /* выведет '0' */

    Если Вы хотите просмотреть еще некоторые примеры по использованию логических операторов, =>.




    Операторы истинности и ложности

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

    Операторы сравнения - Перечисленные далее операторы можно использовать для сравнений:
    > Больше чем
    < Меньше чем
    = Равно

    Сравнивать можно как числовые, так и символьные величины. Ниже приведены примеры сравнения чисел:
    Значение выражения 5 > 3 равно 1. Результат - истина.

    Значение выражения 2.0 = 002 равно 1. Результат - истина.

    Значение выражения 332 < 299 равно 0. Результат - ложь.

    Если элементы, которые нужно сравнить, не числа, то интерпретатор сравнивает символы. Например, при сравнении двух слов (строк) airmail и airplane, символ за символом, три первых буквы у них совпадут. Далее, так как m < p, то и airmail < airplane.
    Равенство - В языке REXX знак равенства (=) может иметь два значения в зависимости от его местоположения. Например,
    amount = 5 /* Это оператор присваивания */ присваивает переменной amount значение 5. Если же знак равенства используется не в операторе присваивания, то в этом случае будет выполняться сравнение. Например,
    SAY amount = 5 /* Это оператор сравнения */ сравнивает значение переменной amount с числом 5. Если они совпадают, то на экран выводится число 1, в противном случае - 0.

    Если Вы хотите просмотреть еще некоторые примеры сравнений => .


    Принятие решений (IF THEN)

    В процедурах, примеры которых были приведены ранее, инструкции выполнялись последовательно одна за другой. В этом разделе описывается, как управлять порядком выполнения инструкций. В зависимости от диалога, который пользователь ведет с процедурой, некоторые строки ее кода могут быть опущены.
    Существует две инструкции, IF и SELECT, которые позволяют принимать решения о порядке выполнения прочих инструкций в процедуре. Инструкция IF подобна команде OS/2 IF. Она определяет, выполнять ли следующую инструкцию или пропустить ее. Инструкция SELECT позволяет выбрать для выполнения одну инструкцию из группы.
    Для принятия решения инструкция IF должна использоваться вместе с инструкцией THEN. Интерпретатор выполняет следующую за IF инструкцию в том случае, если выражение истинно, например:
    IF answer = "ДА" THEN SAY "ХОРОШО!"
    В предыдущем примере инструкция SAY выполняется только в том случае, если переменная answer имеет значение ДА.
    Объединение инструкций с помощью DO и END - Для того, чтобы приказать интерпретатору выполнить некоторый перечень инструкций, следующих за инструкцией THEN, используйте конструкцию типа:
    DO Инструкция1 Инструкция2 Инструкция3 END
    Инструкция DO и завершающая ее инструкция END указывают интерпретатору рассматривать все инструкции, расположенные между ними, как одну инструкцию.


    Средства языка REXX

    В этом разделе описываются средства языка REXX, которые можно использовать для написания более сложных процедур. Вы увидите, как в процедуре можно сделать выбор, проверяя значение переменной с помощью инструкции IF. Вы также узнаете, как сравнивать величины и определять, является выражение истинным либо ложным. Ниже приведено краткое описание элементов, обсуждаемых в этом разделе.
    Используется вместе с THEN. Проверяет истинность выражения. Принимает решение на основании одной инструкции.
    Определяет инструкцию, которая должна быть выполнена, если выражение истинно.
    Определяет инструкцию, которая должна быть выполнена, если выражение ложно.
    Приказывает интерпретатору выбрать из нескольких инструкций одну.
    Используется вместе с SELECT. Определяет выражение, которое должно проверяться.
    Используется вместе с SELECT. Определяет инструкцию, которая должна быть выполнена, если проверяемое выражение ложно.
    Указывает, что должна быть выполнена некоторая группа инструкций.
    Указывает, что с данным выражением ничего не нужно делать.
    > < =Определяют, больше ли, меньше либо равно чему-либо данное выражение.
    ¬ или \Изменяет значение элемента с истинного на ложное, либо с ложного на истинное.
    &Присваивает значение истина, если оба элемента являются истинными.
    |Присваивает значение истина, если хотя бы один элемент является истинным.



    Автоматизация повторяющихся задач - использование циклов

    Если Вы хотите повторить выполнение нескольких инструкций в процедуре, можете использовать цикл. Циклы часто используются в программировании, так как они группируют некоторое множество инструкций, выполняемых несколько раз. Циклы делают Вашу процедуру более краткой, а также позволяют опрашивать пользователя до тех пор, пока он не введет правильный ответ.
    С помощью циклов можно складывать или вычитать числа до тех пор, пока Вы не захотите остановиться. Вы можете определить, сколько раз процедура должна выполнить указанные инструкции. В этом разделе Вы познакомитесь с простейшими циклами, используемыми для выполнения в процедуре повторяющихся инструкций.
    Существуют два типа циклов. Это и . Циклы начинаются с инструкции DO и завершаются инструкцией END. Ниже приведено краткое описание элементов, обсуждаемых в этом разделе:
    Повторяет цикл фиксированное число раз.
    Подсчитывает каждый проход по циклу. Устанавливает начальное и конечное значение переменной.
    Проверяет истинность или ложность некоторого выражения в начале цикла. Повторяет цикл, если значение истинно. В противном случае выполнение процедуры продолжается с инструкции, следующей за END.
    Проверяет истинность или ложность некоторого выражения в конце цикла. Повторяет цикл, если значение ложно. В противном случае выполнение процедуры продолжается с инструкции, следующей за END.
    Приказывает интерпретатору выйти из цикла.
    Повторяет выполнение инструкций до тех пор, пока пользователь не решит закончить.
    Требует нажатия комбинации клавиш Ctrl+Break.
    Закрепляет за каждым словом в группе различные переменные.



    Повторяющиеся циклы


    Простые повторяющиеся циклы могут быть выполнены определенное количество раз. Вы можете указать число повторений цикла или использовать переменную, которая имеет изменяющееся значение.
    Ниже приведен пример цикла, который повторяется фиксированное число раз.
    DO num инструкция1 инструкция2 инструкция3 ... END
    Num представляет собой целое число, указывающее количество повторений цикла.
    Процедура LOOP.CMD является примером простого повторяющегося цикла.
    /* Простой цикл */ DO 5 SAY 'Спасибо' END EXIT
    Ниже приведен протокол работы процедуры LOOP.CMD:
    [C:\]loop Спасибо Спасибо Спасибо Спасибо Спасибо
    [C:\]

    Инструкция DO может также иметь следующий вид:
    DO XYZ = 1 to 10
    Инструкция DO такого типа подсчитывает каждый проход по циклу, поэтому этот счетчик можно использовать как переменную. Значение XYZ изменяется (на 1) каждый раз, когда отрабатывает цикл. Значение 1 (или любое другое число) присваивается переменной, когда цикл выполняется первый раз. Значение 10 (или любое другое число) будет присвоено переменной при последнем проходе по циклу.
    Процедура NEWLOOP.CMD является примером подобного цикла:
    /* Цикл с инструкцией DO другого типа */ sum = 0 DO XYZ = 1 to 7 SAY 'Введите значение' XYZ PULL value sum = sum + value END SAY 'Общий итог равен' sum EXIT
    Ниже приведен протокол работы процедуры NEWLOOP.CMD:
    [C:\]newloop Введите значение 1 2 Введите значение 2 4 Введите значение 3 6 Введите значение 4 8 Введите значение 5 10 Введите значение 6 12 Введите значение 7 14 Общий итог равен 56
    [C:\]
    После завершения цикла выполнение процедуры продолжается с инструкции, следующей за инструкцией END (которая свидетельствует о конце цикла).


    Разбор слов

    Инструкция PULL получает ответ и помещает его в память некоторой переменной. PULL может также использоваться для помещения в память нескольких переменных каждого слова из группы слов. В языке REXX это называется разбором. В следующем примере используются переменные с именами: first, second, third и rest.
    SAY 'Введите, пожалуйста, три слова или более' PULL first second third rest Предположим, Вы ввели следующий ответ:
    garbage in garbage out После нажатия клавиши Enter выполнение процедуры продолжится. При этом указанные переменные получат следующие значения:
    Переменной first присваивается значение GARBAGE.
    Переменной second присваивается значение IN.
    Переменной third присваивается значение GARBAGE.
    Переменной rest присваивается значение OUT.

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





    Условные циклы

    Условные циклы выполняются до тех пор, пока удовлетворяется условие истинности или ложности некоторого выражения. Рассмотрим несколько инструкций, которые используются для условных циклов:

    DO WHILE и DO UNTIL - Инструкции DO WHILE и DO UNTIL выполняются, пока удовлетворяется некоторое условие или до тех пор, пока оно не удовлетворится. Инструкция DO WHILE имеет следующую структуру:
    DO WHILE выражение инструкция1 инструкция2 инструкция3 END
    Инструкция DO WHILE проверяет истинность или ложность некоторого выражения в начале цикла; т.е. перед выполнением последующих инструкций. Если выражение является истинным, то инструкции выполняются. Если выражение является ложным, то цикл завершается и управление передается инструкции, следующей за END.
    На диаграмме, приведенной ниже, представлена наглядная структура инструкции DO WHILE:
    Условные циклы

    Чтобы просмотреть примеры использования инструкции DO WHILE в процедурах, выберите =>.
    DO UNTIL - Инструкция DO UNTIL отличается от DO WHILE тем, что она сначала выполняет инструкции, образующие тело цикла, а затем проверяет значение выражения. Если выражение ложно, то инструкции повторяются (в цикле). Если выражение истинно, то цикл завершается и управление передается инструкции, следующей за END.
    Так как инструкция DO UNTIL проверяет значение выражения в конце цикла, инструкции внутри цикла DO выполняются по крайней мере один раз.
    Инструкция DO UNTIL имеет следующую структуру:
    DO UNTIL выражение инструкция1 инструкция2 инструкция3
    END
    На диаграмме, приведенной ниже, представлена наглядная структура инструкции DO UNTIL:
    Условные циклы

    Чтобы просмотреть примеры использования инструкции DO UNTIL в процедурах, выберите =>.

    LEAVE - Вам может понадобиться выйти из цикла до того, как он завершится естественным образом по удовлетворении некоторого условия. Вы можете сделать это с помощью инструкции LEAVE. Эта инструкция завершает цикл, и управление передается инструкции, следующей за END. Проиллюстрируем на примере процедуры LEAVE.CMD использование инструкции LEAVE.

    /* Использование инструкции LEAVE в цикле */ SAY ' введите сумму наличных денег' PULL salary spent = 0 /* Присваивает spent значение 0 */ DO UNTIL spent > salary SAY 'Введите стоимость товара или END для завершения' PULL cost IF cost = 'END' THEN LEAVE spent = spent + cost END SAY 'Пустые карманы.' EXIT


    DO FOREVER - Иногда Вы не можете определить, сколько раз нужно повторить цикл. Например, может потребоваться, чтобы пользователь вводил цифровые данные (числа, которые должны складываться), а процедура выполняла вычисления до тех пор, пока сложены), а процедура выполняла вычисления до тех пор, пока пользователь не прикажет остановиться. Для процедур подобного типа Вы можете использовать инструкцию DO FOREVER вместе с инструкцией LEAVE.

    Проиллюстрируем на следующем примере использование инструкции DO FOREVER.

    /* Использование цикла DO FOREVER для сложения чисел */ sum = 0 DO FOREVER SAY 'Введите число или END для завершения' PULL value IF value = 'END' THEN LEAVE /* процедура завершается при получении "end" */ sum = sum + value END SAY 'Сумма равна ' sum EXIT



    Выход из циклов

    Чтобы прекратить выполнение большинства процедур REXX, пользуйтесь комбинацией клавиш Ctrl+Break. REXX распознает комбинацию Ctrl+Break после окончания выполнения текущей инструкции. Бывают случаи (как, например, в приведенной ниже процедуре), когда для того, чтобы выйти из цикла, нужно нажать комбинацию клавиш Ctrl+Break, а затем Enter.
    /* Угадайте пароль ! */ DO UNTIL answer = "Sesame" SAY "Введите, пожалуйста, пароль . . ." PULL answer END EXIT
    Если Вы все-таки не смогли завершить процедуру, то нажмите комбинацию клавиш Alt+Esc, чтобы завершить сеанс OS/2 и остановить выполнение процедуры.


    Расширенные функции REXX

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




    ADDRESS

    ADDRESS
    Инструкция ADDRESS используется для того, чтобы послать на выполнение в указанную среду, представленную на диаграмме словом среда, одну команду. В качестве обозначения среды может выступать текстовая цепочка или символ, которые являются константами и позиционно предшествуют выражению. Выражение вычисляется и результирующая командная строка направляется в указанную среду. После того, как команда выполнится, среда устанавливается в то состояние, в котором она находилась до выполнения команды. Таким образом происходит временное изменение адресата для одной команды.
    Пример: ADDRESS CMD "DIR C:\STARTUP.CMD" /* OS/2 */
    Если указана только среда, то происходит постоянное изменение адресата: все последующие команды (предложения, которые не являются инструкциями REXX и операторами присваивания) будут направляться в указанную командную среду до тех пор, пока не будет введена следующая инструкция ADDRESS. Сохраняется среда, установленная ранее.
    Пример:

    Предположим, что в качестве среды для текстового редактора зарезервировано имя "EDIT": address CMD 'DIR C:\STARTUP.CMD' if rc=0 then 'COPY STARTUP.CMD *.TMP' address EDIT
    Все последующие команды направляются на выполнение в среду текстового редактора до тех пор, пока не будет введена очередная инструкция ADDRESS.
    Чтобы выполнить постоянное изменение среды, можно также использовать форму VALUE. В этом случае выражение1 (которое может быть просто именем переменной) вычисляется и результат формирует имя среды. Вложенное ключевое слово VALUE может быть опущено при условии, что выражение1 начинается со специального символа (для того, чтобы не ошибиться с символом или строкой).
    Пример: ADDRESS ('ENVIR'number)
    Если инструкция введена без аргументов, то команды направляются для выполнения в среду, которая была установлена до предыдущего постоянного изменения среды, и имя этой текущей среды сохраняется. Поэтому повторное выполнение инструкции ADDRESS без аргументов приводит к попеременному переключению командных сред с одной на другую. Пустая строка (" "), указанная для имени среды, означает то же самое, что и среда, принимаемая по умолчанию.


    ARG

    ARG
    Инструкция ARG используется для восстановления строк аргументов, предоставляемых программе или внутренней подпрограмме, и присваивания их значений некоторым переменным. Представляет собой краткую форму следующей инструкции:
    ARG
    Шаблон представляет собой список символов, разделенных пробелами.
    Если выполняется не подпрограмма или внутренняя функция, то интерпретатор считывает аргументы, указанные при вызове программы; встречающиеся буквы переводит в прописные (например, строчные a-z в прописные A-Z), а затем присваивает значения считанных аргументов некоторым переменным. Если Вы не хотите переводить строчные буквы в прописные, то используйте инструкцию PARSE ARG.
    Если выполняется подпрограмма или внутренняя функция, то использованные данные будут строками аргументов, переданных программе.
    Инструкции ARG и PARSE ARG могут выполняться как угодно часто (как правило, с различными шаблонами), при этом всегда разбирая по переменным одну и ту же текущую строку ввода. Не существует ограничений на длину или содержание разбираемых данных, кроме тех, которые налагаются вызывающей программой.
    Пример: /* Переданная строка - "Easy Rider" */
    Arg adjective noun
    /* Теперь: "ADJECTIVE" содержит 'EASY' */ /* "NOUN" содержит 'RIDER' */
    Если ожидается, что программе будут доступны несколько строк аргументов, то каждая из них может быть выбрана по очереди, ориентируясь на разделяющую запятую в разбираемом шаблоне.
    Пример: /* функция вызывается следующим образом: FRED('data X',1,5) */
    Fred: Arg string, num1, num2
    /* Теперь: "STRING" содержит 'DATA X' */ /* "NUM1" содержит '1' */ /* "NUM2" содержит '5' */
    Примечания:
  • Строки аргументов для процедур REXX или внутренних программ можно восстановить или проверить и с помощью встроенной функции ARG.
  • Источник данных, которые будут обрабатываться, также предоставляется при входе в программу. Для получения более подробной информации обращайтесь к описанию инструкции PARSE (режим SOURCE).


    CALL

    CALL
    Инструкция CALL используется для вызова программы (если Вы указали имя) или для управления отслеживанием некоторых условий (если Вы указали ON или OFF).
    Для управления отслеживанием укажите OFF или ON и условие, которое Вы хотите отследить. OFF прекращает процесс отслеживания указанного условия. ON запускает процесс отслеживания указанного условия.
    Для вызова программы укажите имя, являющееся символом или текстовой строкой, которые представляют собой константу. Имя должно быть действительным символом. Вызываемая программа может быть одной из следующих:
  • Внутренняя программа
  • Внешняя программа
  • Встроенная функция.
    Если для указания имени используется строка (т.е. имя заключено в кавычки), то поиск внутренних меток не производится и вызываются только встроенные функции или внешние программы. Следует отметить, что имена встроенных функций (и, как правило, имена внешних программ тоже) пишутся прописными буквами; поэтому и имя в текстовой строке должно быть указано прописными буквами.
    В необязательном порядке программа может возвращать результат, который функционально идентичен следующему предложению:
    CALL
    Исключительная ситуация возникает тогда, когда переменная result инициализируется при отсутствии результата, возвращенного вызванной программой.
    Имя, заданное в инструкции CALL, должно быть действительным символом.
    Интерпретатор OS/2 допускает возможность указания до 20 выражений, разделенных запятыми. Выражения вычисляются слева направо и формируют строки аргументов в процессе выполнения программы. Любая инструкция ARG или PARSE ARG, а также встроенная функция ARG в вызванной программе получит доступ к этим строкам прежде, чем они станут активными в вызывающей программе. При необходимости Вы можете опустить некоторые выражения, вставляя на их место дополнительные запятые.
    Инструкция CALL инициирует затем переход к программе с указанным именем, используя тот же механизм, что и при вызове функции. Порядок, в котором осуществляется поиск программ, описан в разделе, посвященном функциям.
    Ниже приведена краткая информация:

    Внутренние программы: Представляют собой последовательность инструкций, расположенных внутри основной программы и начинающихся с метки, которая соответствует имени, указанному в инструкции CALL. Если имя программы указано в кавычках, то данная внутренняя программа не рассматривается как объект для поиска.
    Встроенные программы: Представляют собой программы, встроенные в языковой процессор для обеспечения выполнения различных функций. Они всегда возвращают строку, содержащую результат выполнения функции.
    Внешние программы: Пользователи могут написать сами или использовать программы, которые являются внешними для языкового процессора или вызывающей программы. Внешняя программа может быть написана на любом языке, включая REXX, который поддерживает системно-зависимые интерфейсы. Если внешняя программа, написанная на языке REXX, вызвана как подпрограмма с помощью инструкции CALL, Вы можете восстановить любую строку аргументов, используя инструкции ARG или PARSE ARG, а также встроенную функцию ARG.


    DO

    DO
    повторитель:
    DO
    условие:
    DO
    DO используется для того, чтобы объединить некоторые инструкции и, необязательно, неоднократно их выполнить. В процессе неоднократного выполнения инструкций управляющая переменная (имя) может наращиваться, принимая различные значения из некоторого диапазона.
    Примечания по синтаксису:
  • Значения exprr, expri, exprb, exprt и exprf (если они указаны) представляют собой выражения, результат вычисления которых - число. Значения exprr и exprf представляют собой выражения, результат вычисления которых - целое неотрицательное число. При необходимости числа округляются в соответствии с установкой NUMERIC DIGITS.
  • Значения exprw или expru (если они указаны) могут быть любым выражением, результат вычисления которого равен 1 или 0.
  • Фразы TO, BY и FOR могут указываться в любом порядке, если они используются.
  • Инструкции могут включать в себя операторы присваивания, команды и ключевые инструкции (которые сами могут включать любую из более сложных конструкций, таких, как IF, SELECT и инструкцию DO).
  • Вложенные ключевые слова TO, BY, FOR, WHILE и UNTIL зарезервированы внутри инструкции DO, в которой они не могут использоваться в качестве имен переменных в выражениях, но могут выступать в качестве имени управляющей переменной. Вложенное ключевое слово FOREVER также зарезервировано, но только в том случае, если оно непосредственно следует за ключевым словом DO.
  • Значение exprb по умолчанию принимается равным 1, если это имеет отношение к делу.
    Простая группа DO:
    Если не указан ни повторитель, ни условие, то конструкция DO просто группирует вместе некоторое число инструкций. Они выполняются один раз. В противном случае группа инструкций образует повторяющийся цикл DO, который выполняется несколько раз, в зависимости от заданного повторителя и условия, которое может его изменять.
    В следующем примере инструкции выполняются один раз.
    Пример: /* Две инструкции между DO и END будут */ /* выполнены в случае, если A = 3. */ If a=3 then Do a=a+2 Say 'Улыбнитесь!' End

    Простые повторяющиеся циклы:

    Если повторитель опущен, но указано условие, или если повторителем является FOREVER, то группа инструкций, вообще говоря, будет выполняться постоянно, т.е. до тех пор, пока не удовлетворится требуемое условие, или не выполнится инструкция REXX, которая осуществит выход из цикла (например, LEAVE).

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

    Пример: /* Выводит "Привет" пять раз */ Do 5 say 'Привет' end

    Помните, чем отличается команда от оператора присваивания? Также и в инструкции DO: если первый знак exprr- символ, а второй - знак "=", то будет использоваться, скорее всего, управляемая форма повторителя.

    Управляемые повторяющиеся циклы:

    При использовании управляемой формы цикла указывается управляющая переменная имя, которой присваивается начальное значение (результат вычисления выражения expri, выполненного таким образом, как если бы был добавлен 0). Затем при каждом выполнении группы инструкций управляющая переменная наращивается (т.е. к ее значению в конце цикла добавляется результат вычисления exprb). Выполнение группы инструкций продолжается до тех пор, пока не встретится конечное условие (определенное как результат вычисления выражения exprt). Если значение exprb - положительное число или нуль, то цикл будет завершен, когда значение имени превысит значение exprt. В противном случае (если значение exprb - отрицательное число), цикл завершится, когда значение имени станет меньше значения exprt.

    Результаты вычисления выражений expri, exprt и exprb должны быть числами. Они вычисляются только один раз, перед началом цикла и перед присваиванием управляющей переменной ее начального значения. По умолчанию значение выражения exprb равно 1. Если опущено выражение exprt, то цикл выполняется бесконечно, пока его не завершит какое-либо другое условие.

    Пример: Do I=3 to -2 by -1 /* Выведет: */ say i /* 3 */ end /* 2 */ /* 1 */ /* 0 */ /* -1 */ /* -2 */


    Числа не обязательно должны быть целыми.

    Пример: X=0.3 /* Выведет: */ Do Y=X to X+4 by 0.7 /* 0.3 */ say Y /* 1.0 */ end /* 1.7 */ /* 2.4 */ /* 3.1 */ /* 3.8 */

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

    Следует отметить, что конечное условие проверяется в начале каждой итерации (повторения); а также после наращивания управляющей переменной, на второй и всех последующих итерациях. Поэтому группа инструкций может быть полностью пропущена, как только удовлетворится конечное условие. Отметим также, что на управляющую переменную ссылаются по ее имени. Если, например, для управляющей переменной используется составное имя A.I, то изменение I внутри цикла приведет к изменению управляющей переменной.

    Количество итераций управляемого цикла может быть дополнительно ограничено с помощью фразы FOR. В этом случае должно быть указано выражение exprf, и результатом его вычисления должно быть целое неотрицательное число. Это число играет роль счетчика повторений в простом повторяющемся цикле, устанавливая предел количества итераций внутри цикла, если никакое другое условие не завершит его прежде. Подобно выражениям во фразах TO и BY, выражение во фразе FOR вычисляется только один раз: когда инструкция DO выполняется первый раз и управляющая переменная получает свое начальное значение. Аналогично условию TO, условие FOR проверяется в начале каждой итерации.

    Пример: Do Y=0.3 to 4.3 by 0.7 for 3 /* Выведет: */ say Y /* 0.3 */ end /* 1.0 */ /* 1.7 */

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


    Данная возможность с минимальными издержками позволяет автоматически контролировать вложенность циклов.

    Пример: Do K=1 to 10 ... ... End k /* Определяет конец цикла K */

    Прим. Значения, которые принимает управляющая переменная, могут находиться под влиянием установок NUMERIC, так как вычисление приращения управляющей переменной выполняется по обычным арифметическим правилам, используемым REXX.

    Условные фразы (WHILE и UNTIL):

    Любой из типов повторителей (никакой, FOREVER, простой или управляемый) может предшествовать условной фразе, с помощью которой можно завершить цикл. Если Вы указали WHILE или UNTIL, то соответствующие выражения exprw или expru вычисляются при каждом проходе по циклу, используя при этом последние значения всех переменных (результатом вычисления должен быть либо 0, либо 1). При этом группа инструкций повторно выполняется, либо пока результат равен 1, либо до тех пор, пока результат не станет равным 1.

    Для цикла WHILE проверяемое условие вычисляется в начале группы инструкций; для цикла UNTIL проверяемое условие вычисляется в конце, перед наращиванием управляющей переменной.

    Пример: Do I=1 to 10 by 2 until i>6 say i end /* Выведет на экран: 1, 3, 5, 7 */

    Прим. Способ выполнения повторяющихся циклов может быть изменен инструкцией LEAVE или ITERATE.



    DROP

    DROP
    Каждое имя представляет собой имя действительной переменной, иногда заключенное в скобки (для обозначения дополнительного списка), и отделяется от любого другого имени одним или несколькими пробелами.
    Инструкция DROP используется для отмены назначений переменных; т.е. для восстановления их в первоначальное непроинициализированное состояние.
    Каждая указанная переменная удаляется из списка известных переменных. Если единственное указанное имя заключено в скобки, то его значение рассматривается как дополнительный список переменных, которые нужно освободить. Принцип расположения переменных в дополнительном списке должен подчиняться тем правилам, которые приняты и для основного списка (содержать действительные имена переменных, разделенные пробелами), но без пробелов в начале и конце списка. Переменные освобождаются последовательно слева направо. Не будет ошибкой указание одного и того же имени переменной несколько раз или попытка освободить переменную, имя которой неизвестно. Если указана проявляющаяся переменная (см. описание инструкции PROCEDURE), то эта переменная сама будет освобождена при последующей генерации.
    Пример: j=4 Drop a x.3 x.j /* освободит переменные: A, X.3, and X.4, поэтому */ /* последующая ссылка на них выдаст их имена. */
    В следующем примере имя переменной в скобках используется как дополнительный список.
    Пример: x=4;y=5;z=6; a='x y z' DROP (a) /* освободит x,y и z */
    Если указана основа (символ, содержащий только одну точку в качестве последнего знака), то освобождаются все переменные, начинающиеся с этой основы.
    Пример: Drop x. /* освободит все переменные, чьи имена начинаются с X. */


    EXIT

    EXIT
    Инструкция EXIT используется для безусловного завершения программы. В некоторых случаях EXIT возвращает вызывающей программе строку данных. Программа завершается немедленно, даже если при этом выполняется внутренняя программа. При отсутствии активных внутренних программ инструкции RETURN и EXIT идентичны по их воздействию на выполняющуюся программу.
    Если Вы указали выражение, то оно вычисляется и после завершения программы результирующая строка возвращается вызывающей программе.
    Пример: j=3 Exit j*4 /* Завершится с результирующей строкой '12' */
    Если Вы не указываете выражение, то вызывающей программе никакие данные не передаются. Если программа была вызвана как внешняя функция, то это воспринимается как ошибка, независимо от того, немедленно завершилась программа (при использовании EXIT) или по возврату в вызывающую программу (при использовании RETURN).
    Выражение "достижение конца" программы всегда равнозначно инструкции EXIT в той ее форме, когда она завершает всю программу и не возвращает результирующей строки.
    Прим. Языковой процессор не делает различий между вызовом программы, с одной стороны, и вызовом подпрограммы или функции, с другой. Если программа была вызвана через командный интерфейс, то делается попытка преобразовать полученное значение в код возврата, приемлемый для вызывающей процедуры REXX. Возвращенная результирующая строка должна быть целым числом со знаком в диапазоне от -2**15 до 2**15-1.



    IF

    IF
    Инструкция IF используется для условного выполнения инструкции или группы инструкций в зависимости от результата вычисления выражения. Результат вычисления выражения должен быть равен 0 или 1.
    Инструкция, следующая за THEN, выполняется только в том случае, если результат вычисления равен 1. Если Вы указали предложение ELSE, то инструкция, следующая за ELSE, выполняется только в том случае, если результат вычисления равен 0.
    Пример: if answer='ДА' then say 'Хорошо!' else say 'Почему нет?'
    Не забывайте, что если предложение ELSE находится в той же строке, что и последняя часть предложения THEN, то их нужно разделить точкой с запятой.
    Пример: if answer='ДА' then say 'Хорошо!'; else say 'Почему нет?'
    Предложение ELSE связывается с ближайшей инструкцией соответствующего уровня. Чтобы исключить ошибки и возможную путаницу при написании вложенных конструкций IF, можно использовать инструкцию NOP, как показано в следующем примере.
    Пример: If answer = 'ДА' Then If name = 'ФРЕД' Then say 'Хорошо, Фред.' Else nop Else say 'Почему нет?'
    Примечания:
  • Инструкцией может быть любой оператор присваивания, команда или ключевая инструкция, включающая любую более сложную конструкцию, такую как DO, SELECT или саму инструкцию IF. Предложение, содержащее пустую строку, не является инструкцией; поэтому указание за THEN или ELSE дополнительной точки с запятой не равнозначно выполнению фиктивной инструкции (как это принято в языке С). Для этих целей предназначена инструкция NOP.
  • Слово THEN нельзя использовать внутри выражения (в котором оно не предназначается для начала предложения), так как ключевое слово THEN обрабатывается иначе. Если же оно используется, то это может привести к завершению выражения в предложении IF посредством символа THEN, указанного без требуемого разделителя (;). Если бы это было не так, то пользователи других компьютерных языков испытывали бы определенные затруднения.


    INTERPRET

    INTERPRET
    Инструкция INTERPRET используется для выполнения инструкций, построенных динамически в процессе вычисления выражения.
    Выражение вычисляется, а затем обрабатывается (интерпретируется) так, как если бы результирующая цепочка символов была строкой, вставленной в исходный файл (и ограниченной DO; и END;).
    Допустимы любые инструкции (включая инструкции INTERPRET), но конструкции типа DO ... END и SELECT ... END должны иметь завершенный вид. Например, строка инструкций, которая интерпретируется, не может содержать инструкции LEAVE или ITERATE (действительные только внутри повторяющегося цикла DO), если она при этом не содержит полную повторяющуюся конструкцию DO ... END.
    Для удобства пользователя в конце выражения подразумевается точка с запятой.
    Пример: data='FRED' interpret data '= 4' /* a) построит строку "FRED = 4" */ /* b) вычислит FRED = 4; */ /* Теперь переменной "FRED" будет присвоено значение "4" */
    Пример: data='do 3; say "Привет!"; end' interpret data /* Выведет: */ /* Привет! */ /* Привет! */ /* Привет! */
    Примечания:
    1 Метки внутри интерпретируемой строки не являются неизменными и поэтому игнорируются. Поэтому выполнение инструкции SIGNAL из интерпретируемой строки приведет к немедленному выходу из этой строки до того, как начнется поиск метки.
    2 Если концепция инструкции INTERPRET для Вас нова и получаемые результаты непонятны, то полезно выполнить эту инструкцию, указывав в процедуре TRACE R или TRACE I.
    Пример: /* Мы имеем небольшую программу. */ Trace Int name='Китти' indirect='name' interpret 'say "Привет"' indirect'"!"'
    При выполнении этой процедуры на экран выводится следующая информация: [C:\]kitty kitty 3 *-* name='Китти' >L> "Китти" 4 *-* indirect='name' >L> "name" 5 *-* interpret 'say "Привет"' indirect'"!"' >L> "say "Привет"" >V> "name" >O> "say "Привет" name" >L> ""!"" >O> "say "Привет" name"!"" *-* say "Привет" name"!" >L> "Привет" >V> "Китти" >O> "Привет Китти" >L> "!" >O> "Привет Китти!" Привет Китти! [C:\]
    Строки 3 и 4 устанавливают переменные, используемые в строке 5. Вычисление строки 5 происходит в два этапа. Сначала строится строка, которая будет интерпретироваться при помощи текстовой строки, переменной (INDIRECT) и еще одного литерала. Затем результирующая строка, состоящая только из символов, интерпретируется так, как если бы она была частью исходной программы. Так как полученная строка является новым предложением, то она трассируется следующим образом (второй трассировочный флаг *-* под строкой 5), а затем выполняется. После этого текстовая строка объединяется со значением переменной (NAME) и вторым литералом, и окончательный результат выводится на экран в следующем виде: Привет Китти!
    3 Во многих случаях вместо инструкции INTERPRET можно использовать функцию VALUE. Например, строку 5 в последнем примере можно заменить следующей: say "Привет" value(indirect)"!"

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


    ITERATE

    ITERATE
    Инструкция ITERATE предназначена для изменения естественного потока инструкций внутри повторяющегося цикла DO (т.е. любой конструкции DO, кроме простых циклов DO).
    Выполнение группы инструкций прекращается и управление передается инструкции DO, как если бы встретилось предложение END. Управляющая переменная (если она существует) наращивается и проверяется как обычно, и выполнение группы инструкций возобновляется, если только цикл не завершится по инициативе инструкции DO.
    Если имя не указано, то инструкция ITERATE будет отноcиться к самому внутреннему активному повторяющемуся циклу. Если имя задано, то оно должно быть именем управляющей переменной текущего активного цикла, который может быть самым внутренним циклом; к этому циклу и будет применяться инструкция ITERATE. Любой активный цикл, вложенный в цикл, выбранный для итераций, завершается (как если бы встретилась инструкция LEAVE).
    Пример: do i=1 to 4 if i=2 then iterate say i end /* Будут выведены числа: 1, 3, 4 */
    Примечания:
  • Если указано имя, то оно должно совпадать с именем в инструкции DO во всех отношениях, кроме регистра клавиатуры (строчные или прописные буквы). При этом, когда выполняется сравнение имен, никакие подстановки для составных переменных не производятся.
  • Цикл считается активным, если он в настоящий момент обрабатывается. Если в процессе выполнения цикла была вызвана подпрограмма или началась обработка инструкции INTERPRET, то цикл становится неактивным до тех пор, пока не будет осуществлен возврат из подпрограммы или не завершится выполнение инструкции INTERPRET. Инструкцию ITERATE нельзя использовать в неактивных циклах.
  • Если одна и та же управляющая переменная используется в нескольких активных циклах, то инструкция ITERATE относится к самому внутреннему циклу.


    Ключевые инструкции

    Ключевая инструкция представляет собой одно или несколько предложений, первое из которых начинается ключевым словом, определяющим инструкцию. Если инструкция состоит из нескольких предложений, то они должны отделяться друг от друга точкой с запятой (;).
    Некоторые ключевые инструкции, например, начинающиеся ключевым словом DO, могут включать в себя вложенные инструкции.
    В синтаксических диаграммах символы (слова), изображенные прописными буквами, представляют ключевые слова; остальные слова (такие как выражение) являются набором символов. Ключевые слова не зависят от того, какими буквами они набраны (прописными или строчными), поэтому все нижеперечисленные слова: if, If и iF будут вызывать выполнение одной и той же инструкции IF. Вы можете также опускать большинство указанных разделителей (;), приведенных в синтаксисе для обозначения конца строки.


    LEAVE

    LEAVE
    Инструкция LEAVE используется для немедленного выхода из одного или нескольких повторяющихся циклов DO (т.е. из любой конструкции DO, отличной от простого цикла DO).
    Выполнение группы инструкций завершается, и управление передается инструкции, следующей за предложением END, как если бы цикл закончился естественным образом после обработки условия завершения. Однако при этом управляющая переменная, если она есть, на выходе будет иметь то значение, которое она имела перед выполнением инструкции LEAVE.
    Если имя не указано, то инструкция LEAVE завершает самый внутренний активный повторяющийся цикл. Если имя указано, то оно должно быть именем управляющей переменной текущего активного цикла, который может быть самым внутренним циклом; этот цикл (как и все активные циклы, вложенные в него) будет завершен. Потом управление передается инструкции, следующей за предложением END, соответствующим предложению DO выбранного цикла.
    Пример: do i=1 to 5 say i if i=3 then leave end /* Будут выведены числа: 1, 2, 3 */
    Примечания:
  • Если указано имя, то оно должно совпадать с именем в инструкции DO во всех отношениях, кроме регистра клавиатуры (строчные или прописные буквы). При этом, когда выполняется сравнение имен, никакие подстановки для составных переменных не производятся.
  • Цикл считается активным, если он в настоящий момент обрабатывается. Если в процессе выполнения цикла была вызвана подпрограмма или началась обработка инструкции INTERPRET, то цикл становится неактивным до тех пор, пока не выполнится возврат из подпрограммы или не завершится выполнение инструкции INTERPRET. Инструкцию LEAVE нельзя использовать для завершения неактивного цикла.
  • Если одна и та же управляющая переменная используется в нескольких активных циклах, то инструкция LEAVE завершит самый внутренний цикл.


    NOP

    NOP
    NOP - это фиктивная инструкция, которая не выполняет никаких действий. Может использоваться в качестве инструкции в предложениях THEN или ELSE.
    Пример: Select when a=b then nop /* Ничего не делать */ when a>b then say 'A > B' otherwise say 'A < B' end
    Прим. Если вместо инструкции NOP указать дополнительную точку с запятой, то будет вставлено пустое предложение, которое игнорируется. При этом второе предложение WHEN воспримется как первая инструкция, следующая за THEN, и поэтому будет истолковано как синтаксическая ошибка. Однако NOP является корректной инструкцией и действительным целевым назначением для предложения THEN.



    NUMERIC

    NUMERIC
    Инструкция NUMERIC используется для изменения способа выполнения арифметических операций. Режимы данной инструкции подробно описаны в документе Язык процедур 2/REXX для OS/2. Справочник.
    Инструкция NUMERIC с режимом DIGITS управляет точностью вычисления арифметических выражений и арифметических встроенных функций. Если выражение опущено, то по умолчанию используется значение 9. В противном случае результат выражения при необходимости округляется в соответствии с текущим назначением NUMERIC DIGITS. Используемое значение должно быть целым положительным числом, большим, чем текущее назначение NUMERIC FUZZ.
    Не существует ограничений на значение DIGITS (кроме объема доступной памяти), но следует отметить, что высокая точность вычислений обычно требует много процессорного времени. Поэтому рекомендуется во всех возможных случаях использовать значение по умолчанию.
    Текущее назначение NUMERIC DIGITS можно получить с помощью встроенной функции DIGITS.
    Инструкция NUMERIC с режимом FORM управляет формой экспоненциального представления результатов выполнения арифметических операций и встроенных арифметических функций, используемой в языке REXX. Это может быть SCIENTIFIC (в этом случае перед десятичной точкой появляется только одна цифра, отличная от нуля) или ENGINEERING (в этом случае степень числа 10 всегда кратна трем). По умолчанию принимается значение SCIENTIFIC. Режим FORM устанавливается либо с помощью прямого указания вложенного ключевого слова (SCIENTIFIC или ENGINEERING), либо принимается как результат вычисления выражения, следующего за VALUE. Результат в этом случае может быть либо SCIENTIFIC, либо ENGINEERING. Вы можете опустить вложенное ключевое слово VALUE, если выражение начинается не с символа или текстовой строки (например, если оно начинается со специального знака: оператора или скобки).
    Текущее значение NUMERIC FORM можно получить с помощью встроенной функции FORM.
    Инструкция NUMERIC с режимом FUZZ указывает, сколько цифр результата, полученного с указанной точностью, можно отбросить при выполнении операции сравнения.
    Если выражение опущено, то по умолчанию принимается значение 0. В противном случае результат вычисления выражения должен быть нулевым или целым положительным числом, которое перед использованием нужно округлить в соответствии с текущей установкой NUMERIC DIGITS. Используемое значение должно быть целым положительным числом, меньшим, чем текущее назначение NUMERIC DIGITS.

    Режим FUZZ временно уменьшает значение DIGITS на величину FUZZ перед каждой операцией числового сравнения. Сравниваемые числа вычитаются одно из другого, используя точность (DIGITS - FUZZ), а потом результат сравнивается с нулем.

    Текущее значение NUMERIC FUZZ можно получить с помощью встроенной функции FUZZ.

    Прим. Все три числовых назначения автоматически сохраняются при вызове подпрограммы или внутренней функции. Для получения более подробной информации смотрите описание инструкции CALL.


    OPTIONS

    OPTIONS
    Инструкция OPTIONS используется для передачи специальных запросов или параметров языковому процессору. Например, это могут быть режимы языкового процессора или определения специального набора символов.
    Результат вычисления выражения проверяется слово за словом. Если слова распознаются языковым процессором, то они принимаются. Нераспознанные слова игнорируются. Считается, что это инструкции другого процессора.
    Языковый процессор распознает следующие слова:
    ETMODE Определяет, что в программе могут использоваться текстовые строки, содержащие наборы двухбайтовых символов (DBCS).
    NOETMODE Определяет, что в программе не могут использоваться текстовые строки, содержащие символы DBCS. NOETMODE принимается по умолчанию.
    EXMODE Определяет, что данные DBCS в смешанных строках обрабатываются инструкциями, операторами и функциями, основываясь на понятии логического элемента. При этом сохраняется целостность данных DBCS.
    NOEXMODE Определяет, что любые данные в строках обрабатываются на основе байта. При этом целостность символов DBCS может быть нарушена. NOEXMODE принимается по умолчанию.

    Примечания:
  • Из-за просмотра процедур языковым процессором в программах, содержащих текстовые строки DBCS, помещайте инструкцию OPTIONS ETMODE в качестве первой инструкции.
  • Чтобы не сомневаться в правильности просмотра программы, содержащей символы DBCS, вводите режимы ETMODE, NOETMODE, EXMODE и NOEXMODE инструкции OPTIONS как текстовые строки (в кавычках).
  • Назначения OPTIONS ETMODE и OPTIONS EXMODE сохраняются на время выполнения подпрограммы или функции, а затем восстанавливаются.
  • Слова ETMODE, EXMODE, NOEXMODE и NOETMODE могут встретиться несколько раз внутри результирующей строки. При этом режим, который будет принят к исполнению, определяется последним действительным словом, указанным между парами ETMODE/NOETMODE и EXMODE/NOEXMODE.


    PARSE

    PARSE
    Инструкция PARSE используется для присваивания данных из различных источников одной или нескольким переменным в соответствии с правилами и шаблонами, описанными в разделе по разбору слов документа Язык процедур 2/REXX для OS/2. Справочник.
    Если указан шаблон, то он представляет собой список символов, разделенных пробелами.
    Если шаблон не указан, то переменные не назначаются, но при необходимости выполняется подготовка данных к разбору. Например, для PARSE PULL строка данных перемещается из текущей очереди данных; для PARSE LINEIN (и PARSE PULL, если текущая очередь пуста) строка выбирается из входного потока значений по умолчанию; для PARSE VALUE вычисляется выражение. Для PARSE VAR выбирается указанная переменная. Если эта переменная не имеет никакого значения, то устанавливается условие NOVALUE, если оно разрешено.
    Если указан режим UPPER, то буквы в строке, которую нужно разобрать, сначала переводятся в прописные (например, строчные a-z в прописные A-Z). В противном случае при разборе слов не производится перевод строчных букв в прописные.
    Данные, используемые для каждого из вариантов инструкции PARSE, приведены ниже:
    PARSE ARG - Разбираются строки, которые передаются программе, подпрограмме или функции в качестве входного списка аргументов. Для получения более подробной информации смотрите описание инструкции ARG.
    Прим. Строки аргументов в процедуру REXX или внутреннюю программу могут также передаваться с помощью встроенной функции ARG.

    PARSE LINEIN - Разбирается следующая строка из входного потока значений по умолчанию. (Смотрите документ Язык процедур 2/REXX для OS/2. Справочник для получения сведений о формате входных данных REXX). PARSE LINEIN - это краткая форма следующей инструкции:
    PARSE
    Если нет готовых доступных строк, то выполнение программы временно приостанавливается до тех пор, пока строка не завершится. Отметим, что инструкцию PARSE LINEIN нужно использовать только в том случае, когда необходим прямой доступ к входному потоку символов.
    Обычный построчный диалог с пользователем лучше вести с помощью инструкций PULL или PARSE PULL.

    Чтобы проверить, есть ли доступные строки во входном потоке значений по умолчанию, используйте встроенную функцию LINES.

    PARSE PULL - Разбирается следующая строка из очереди. Если очередь пуста, то строки считываются с устройства ввода, определенного по умолчанию; обычно это пользовательская клавиатура. Вы можете добавить данные в начало или конец очереди, пользуясь инструкциями PUSH и QUEUE соответственно. Вы можете также определить количество строк в очереди на данный момент, используя встроенную функцию QUEUED. Очередь остается активной до тех пор, пока активен языковый процессор. Очередь может изменяться другими программами в операционной системе и может использоваться как средство взаимодействия между этими программами и процедурами REXX.

    Прим. Инструкции PULL и PARSE PULL сначала считывают данные из текущей очереди данных. Если очередь пуста, то считывание производится из входного потока, принятого по умолчанию, - STDIN (обычно это клавиатура).
    PARSE SOURCE - Разобранные данные описывают исходную программу, которую нужно выполнить.

    Исходная строка содержит символы OS/2, за которыми могут следовать COMMAND, FUNCTION или SUBROUTINE в зависимости от того, как была вызвана программа: как команда системы, как функция в выражении или с помощью инструкции CALL. Указанные символы предшествуют спецификации полного пути программного файла.

    Поэтому разобранная строка могла бы быть выведена в следующем виде: OS/2 COMMAND C:\OS2\REXTRY.CMD

    PARSE VALUE - Данные, которые должны быть разобраны, являются результатом вычисления выражения. Следует отметить, что WITH в данном контексте является вложенным ключевым словом и поэтому не может использоваться в качестве символа внутри выражения. Например: PARSE VALUE time() WITH hours ':' mins ':' secs

    получает текущее время и разбивает его на составные части.

    PARSE VAR имя - Разбирается значение переменной, указанной с помощью имени. Имя должно быть символом, действительным для определения имени переменной; т.е.


    не может начинаться с точки или цифры. Заметим, что переменная имя не изменяется до тех пор, пока она не появится в шаблоне. Например: PARSE VAR string word1 string извлекает первое слово из string и помещает его в переменную word1, передавая остаток назад в string. Аналогично: PARSE UPPER VAR string word1 string перед тем, как разобрать данные, переводит буквы string из строчных в прописные.

    PARSE VERSION - Разбирается информация, содержащая сведения о версии языка и дате языкового процессора. Она состоит из пяти слов (разделенных пробелами): сначала строка "REXXSAA", затем описание версии языка ("4.00")и, наконец, даты выпуска("13 июня 1989").

    Прим.   Информация PARSE VERSION должна разбираться на основе слов, а не на основе абсолютной позиции столбца .


    PROCEDURE

    PROCEDURE
    Инструкцию PROCEDURE можно использовать во внутренней программе (подпрограмме или функции) для защиты всех существующих переменных путем удаления их из числа известных для последующих инструкций. При выполнении инструкции RETURN восстанавливается исходная среда переменных. Все переменные, использованные в программе (которые не были проявлены), освобождаются.
    Режим EXPOSE изменяет приведенный порядок действий. Любая переменная, указанная именем, проявляется, т.е. любое обращение к ней (включая назначение и освобождение) направляется в среду переменных, которая принадлежит вызывающей программе. Указывая режим EXPOSE, Вы должны определить по крайней мере одно имя, т.е. символ, отделенный от другого имени одним или несколькими пробелами. При необходимости Вы можете заключить единственное имя в скобки, чтобы определить дополнительный список переменных. Все переменные, не указанные с помощью своих имен в инструкции PROCEDURE EXPOSE, остаются защищенными. Следовательно, некоторый ограниченный набор переменных вызываемой программы может быть доступным, и эти переменные могут изменяться (или создаваться новые переменные в этом множестве). Все выполненные изменения будут видимы для вызывающей программы после возвращения из подпрограммы.
    Все переменные проявляются последовательно слева направо. Не считается ошибкой указание одного и того же имени переменной несколько раз или указание имени, которое не использовано в качестве переменной в вызывающей программе.
    Пример: /* Это основная программа */ j=1; x.1='a' call toft say j k m /* выведет на экран "1 7 M" */ exit
    toft: procedure expose j k x.j say j k x.j /* выведет на экран "1 K a" */ k=7; m=3 /* переменная "M" не проявляется */ return
    Заметим, что если бы в предыдущем примере X.J в списке EXPOSE было помещено перед J, то значение J не было бы видимым в настоящий момент, таким образом и переменная X.1 не проявилась бы.
    Если имя заключено в скобки (пробелы внутри или снаружи скобок необязательны, но при желании их можно добавить), то после проявления этой переменной ее значение немедленно будет использовано в качестве дополнительного списка переменных.
    Принцип расположения переменных в дополнительном списке тот же, что и для основного списка, однако скобки или пробелы в начале и конце списка не допускаются. Переменные, перечисленные в дополнительном списке, тоже проявляются слева направо.

    Пример: j=1;k=6;m=9 a ='j k m' test:procedure expose (a) /* будут проявлены j, k и m */

    Если в списке имен указана основа, то проявляются все возможные составные переменные, чьи имена начинаются с этой основы. (Основа - это символ, содержащий только одну точку в качестве последнего знака).

    Пример: lucky7:Procedure Expose i j a. b. /* Проявляет "I", "J" и все переменные, чьи */ /* имена начинаются с "A." или "B." */ A.1='7' /* Назначит "A.1" для среды вызывающей */ /* программы, даже если эта переменная */ /* ранее не существовала. */

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

    На каждом уровне вызова программы допускается только одна инструкция PROCEDURE; все остальные (и те, которые встретились за пределами внутренних программ) считаются ошибочными.

    Примечания:

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

  • Инструкция PROCEDURE должна быть первой инструкцией, выполняющейся после CALL или вызова функции, т.е. первой инструкцией, следующей за меткой.

    Для получения более подробной информации о вызове программ смотрите описание инструкции CALL.



    PULL

    PULL
    Инструкция PULL используется для чтения первой строки из очереди данных REXX, активной в данный момент. ниже приведена краткая форма инструкции:
    PULL
    Текущее начало очереди данных читается как одна строка. Если в инструкции не указан шаблон, то никакие дальнейшие действия не производятся и считанная строка отвергается. Если шаблон указан, то он представляет собой список символов, отделенных друг от друга пробелами. Буквы в строке переводятся в прописные (например, строчные a-z в прописные A-Z), а затем строка разбирается по переменным в соответствии с правилами, описанными в разделе по разбору слов документа Язык процедур 2/REXX для OS/2. Справочник. Если не нужно переводить строчные буквы в прописные, то используйте инструкцию PARSE PULL.
    Прим. Если текущая очередь данных пуста, то инструкция PULL выполняет чтение из STDIN (обычно это клавиатура). Длина данных, прочитанных с помощью инструкции PULL, ограничивается длиной строк, содержащихся в переменных.

    Пример: Say 'Вы хотите удалить файл? Ответьте Да или Нет:' Pull answer . if answer='НЕТ' then Say 'Файл не будет удален.'
    Здесь в шаблоне используется пустая метка-заполнитель "." для того, чтобы изолировать первое слово, введенное пользователем.
    С помощью встроенной функции QUEUED можно определить количество строк в очереди на данный момент.


    PUSH

    PUSH
    Инструкция PUSH используется для занесения строки, являющейся результатом вычисления выражения, по принципу LIFO (последним вошел, первым вышел) в очередь данных REXX, активную в настоящий момент. Если Вы не указали выражение, то в очередь данных заносится пустая строка.
    Пример: a='Fred' push /* Помещает в очередь пустую строку */ push a 2 /* Помещает в очередь строку "Fred 2" */
    С помощью встроенной функции QUEUED можно определить количество строк, находящихся в очереди на данный момент.


    QUEUE

    QUEUE
    Инструкция QUEUE используется для добавления строки, являющейся результатом вычисления выражения, в конец очереди данных REXX, активной в настоящий момент. При этом добавление осуществляется по принципу FIFO (первым вошел, первым вышел).
    Если Вы не указали выражение, то в конец очереди данных добавится пустая строка.
    Пример: a='Toft' queue a 2 /* Добавит в конец очереди строку "Toft 2" */ queue /* Добавит в конец очереди пустую строку */
    С помощью встроенной функции QUEUED можно определить количество строк, находящихся в очереди на данный момент.


    RETURN

    RETURN
    Инструкция RETURN используется для возврата управления (и, возможно, результата) из программы REXX или внутренней программы в точку, откуда она была вызвана.
    Если нет активной внутренней программы (подпрограммы или функции), то инструкции RETURN и EXIT идентичны по своему действию на выполняющуюся программу.
    Если выполняется подпрограмма (см. инструкцию CALL), то вычисляется выражение (если оно указано), управление передается назад вызывающей программе и специальной переменной RESULT языка REXX присваивается значение выражения. Если выражение опущено, то специальная переменная RESULT освобождается (становится непроинициализированной). Различные назначения, сохраненные на время выполнения CALL (трассировка, адреса и т.д.), также восстанавливаются.
    Если выполняется функция, то предпринимаемые действия идентичны описанным, исключая то, что в инструкции RETURN должно быть указано выражение. Результат вычисления выражения используется затем в исходном выражении в точке, из которой была вызвана функция.
    Если внутри программы (подпрограммы или внутренней функции) выполняется инструкция PROCEDURE, то после вычисления выражения и до того, как результат будет использован или присвоен переменной RESULT, все переменные текущей генерации освобождаются (и проявленные переменные из предыдущей генерации тоже).


    SAY

    SAY
    Инструкция SAY используется для записи в выходной поток результата вычисления выражения. Результат обычно выводится на экран пользователя, однако назначение для выходного потока зависит от конкретного применения. Результат вычисления выражения может иметь любую длину.
    > Примечания:
  • Данные из инструкции SAY посылаются в выходной поток, принимаемый по умолчанию (STDOUT:). Однако для вывода инструкции SAY применимы стандартные правила перенаправления выходных потоков, принятые в OS/2.
  • Инструкция SAY не форматирует данные; упаковка строки выполняется операционной системой и аппаратурой. Несмотря на то, что форматирование все же происходит, выходные данные представляют собой единую логическую строку.
    Пример: data=100 Say data ', разделенное на 4 =>' data/4 /* Выведет на экран: "100, разделенное на 4 => 25" */


    SELECT

    SELECT
    Инструкция SELECT используется для условного выполнения одной из нескольких альтернативных инструкций.
    По очереди вычисляется каждое выражение после фразы WHEN. Результат вычисления должен быть равен 0 или 1. Если результат равен 1, то выполняется инструкция, следующая за фразой THEN (которая может быть составной инструкцией, например, IF, DO или SELECT), а затем управление передается фразе END. Если результат равен 0, то управление передается следующей фразе WHEN.
    Если ни один из результатов вычисления выражений WHEN не равен 1, то управление передается инструкциям, следующим за OTHERWISE (если они есть). В этом случае отсутствие предложения OTHERWISE приводит к ошибке.
    Пример balance = balance - check Select when balance > 0 then say 'Поздравляем! У Вас на счету' balance 'долларов.' when balance = 0 then do say 'Внимание! Баланс равен нулю! ПРЕКРАТИТЕ все траты!' say "Вы подрезали свой счет в этом месяце. Надеемся," say "что Вы не будете подписывать крупные чеки." end Otherwise say "Вы уже перекрыли свой счет." say "Ваш баланс составляет сейчас" balance "долларов." say "Ооо! Остается надеяться, что банк не закроет Ваш счет." end /* Select */
    Примечания:
  • В качестве инструкции может выступать любой оператор присваивания, команда или ключевая инструкция, включающая любую более сложную конструкцию, например, DO, IF или SELECT.
  • Предложение, содержащее пустую строку, не является инструкцией, поэтому указание за WHEN дополнительной точки с запятой не равнозначно помещению в файл фиктивной инструкции. Для этих целей предназначена инструкция NOP.
  • Слово THEN нельзя использовать внутри выражения, где оно не предназначается для начала предложения, так как ключевое слово THEN обрабатывается иначе. Если же оно используется, то это может привести к завершению выражения в предложении WHEN посредством слова THEN, указанного без требуемого разделителя ";".


    SIGNAL

    SIGNAL
    Инструкция SIGNAL используется для выполнения аварийного изменения потока управления или, если указаны ON или OFF, для управления отслеживанием некоторых условий.
    Для управления отслеживанием укажите OFF или ON и условие, которое Вы хотите отследить. Значение OFF прекращает процесс отслеживания указанного условия. Значение ON запускает процесс отслеживания указанного условия.
    Прим. Для получения информации по отслеживанию требуемых условий обращайтесь к документу Язык процедур 2/REXX для OS/2. Справочник.
    Чтобы изменить поток управления, имя метки выбирается из имени-метки или принимается как результат вычисления выражения, следующего за VALUE. В качестве имени-метки можно указать символ, трактующийся буквально, или текстовую строку, которая является константой. Вложенное ключевое слово VALUE можно опустить, если выражение не начинается символом или текстовой строкой (например, если оно начинается со специального знака, такого как оператор или скобка). Все активные незавершенные инструкции DO, IF, SELECT и INTERPRET в текущей программе завершаются; т.е. их невозможно активизировать повторно. Затем управление передается первой метке в программе, которая соответствует требуемой строке.
    Пример: Signal fred; /* Переходит на метку "FRED" */ .... .... Fred: say 'Привет!'
    Так как поиск обычно начинается с начала программы, то при наличии нескольких одинаковых меток управление всегда передается первой метке в программе, которая соответствует указанной.
    Когда управление передается на указанную метку, специальной переменной SIGL присваивается значение, равное номеру строки с инструкцией SIGNAL. Это помогает при отладке программы, так как можно определить, откуда был выполнен переход на метку.
    Использование SIGNAL с инструкцией INTERPRET
    Если инструкция SIGNAL выдается как результат выполнения инструкции INTERPRET или происходит событие, которое отслеживается, то остаток интерпретируемой строки не просматривается с целью поиска указанной метки. В действительности метки внутри интерпретируемых строк игнорируются.


    TRACE

    TRACE
    Альтернативная форма:
    TRACE
    Инструкция TRACE используется для отладки. Она управляет трассировкой событий (т.е. выводом процесса их выполнения), имеющих место при работе программы REXX. Синтаксис инструкции TRACE более сжатый и конкретный, в отличие от других инструкций языка REXX. Немногочисленность ключевых слов, используемых в данной инструкции, особенно удобна, так как TRACE обычно вводится вручную в процессе диалоговой отладки.
    Число представляет собой целое число.
    Результатом вычисления строки или выражения может быть:
  • Число
  • Один из действительных префиксов, алфавитных режимов (слов), либо и то, и другое, как показано на данной панели.
  • Ноль.
    Символ является константой и может представлять собой:
  • Число
  • Один из действительных префиксов, алфавитных режимов (слов), либо и то, и другое, как показано на данной панели.
    Действие трассировки определяется указанным режимом инструкции TRACE или результатом вычисления выражения. При наличии выражения можно опустить вложенное ключевое слово VALUE, если выражение начинается со специального символа или оператора (во избежание ошибок для символа или строки).
    Алфавитные режимы (слова)
    Несмотря на то, что режим можно задать полным словом, значащей является только первая прописная буква; остальные буквы игнорируются. Поэтому эти режимы и называются алфавитными.
    Ниже приведено соответствие алфавитных режимов и действий, выполняемых при этом инструкцией TRACE:
    All Трассируются (выводятся) все предложения перед их выполнением.
    Commands Трассируются все команды операционной системы перед их выполнением и выводятся все коды возврата.
    Error Трассируется после своего выполнения любая команда операционной системы, завершившаяся с ненулевым кодом возврата.
    Failure Трассируется после своего выполнения любая команда операционной системы, завершившаяся аварийно. Этот режим аналогичен режиму Normal.
    Intermediates Трассируются все предложения перед их выполнением. Трассируются также промежуточные результаты вычисления выражений и имена, полученные после подстановки.
    Labels Трассируются метки, встретившиеся в процессе выполнения. Использование этого режима особенно полезно при отладке, когда языковый процессор делает остановку после каждой метки. Пользователю также удобно отмечать при этом все вызовы подпрограмм.
    Normal Трассируется после своего выполнения любая команда операционной системы, завершившаяся аварийно. Этот режим принимается по умолчанию.
    Для стандартного командного процессора операционной системы OS/2 попытка выполнить несуществующую команду приводит к формированию условия FAILURE. Попытка направить команду на выполнение в несуществующую среду подкоманд также приводит к формированию условия FAILURE; в этом случае переменная RC принимает значение 2, что соответствует коду возврата для сообщения "Файл не найден" операционной системы OS/2.
    Off Трассировка не выполняется. Все действия, выполнявшиеся ранее по указанным префиксам режимов (см. выше), завершаются.
    Results Трассируются все предложения перед их выполнением. Трассируются конечные результаты вычисления выражений (в противоположность Intermediates). Также выводятся значения, присвоенные переменным при выполнении инструкций PULL, ARG и PARSE. Указанный режим рекомендуется использовать для общей отладки.
    <
    Префиксный режим

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

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

    Если режим диалоговой отладки активен, то Вы можете выключить его, используя инструкцию TRACE с префиксом ?. Таким образом, повторное использование префикса ? приводит к поочередному включению и выключению режима диалоговой отладки. Режим диалоговой отладки можно выключить в любое время, выполнив инструкцию TRACE O или TRACE без режимов.

    Числовые режимы

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

    Если диалоговая отладка неактивна, то числовые режимы игнорируются.

    Формат вывода инструкции TRACE

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

    Все строки, выводимые в процессе трассировки, имеют трехсимвольный префикс для идентификации типа трассируемых данных. Префиксы и их определения перечислены ниже:
    "*-*" Определяет одно исходное предложение, т.е. данные, фактически указанные в программе.
    "+++" Определяет сообщение трассировки. Это может быть ненулевой код возврата из команды, приглашающее сообщение, выдаваемое в режиме диалоговой отладки, индикация синтаксической ошибки в режиме диалоговой отладки или протрассированные предложения после синтаксической ошибки в программе.
    ">>>" Определяет результат выражения (для TRACE R), значение, присвоенное переменной в процессе разбора, или значение, возвращенное из подпрограммы после ее выполнения.
    ">.>" Определяет значение, присвоенное в процессе разбора метке-заполнителю.
    <

    ABBREV

    ABBREV
    Функция ABBREV возвращает результат 1, если значение инфо совпадает с первыми символами значения информации и длина инфо не меньше, чем длина. Функция ABBREV возвращает результат 0, если вышеперечисленные условия не выполняются.
    Длина, если она указана, должна представлять собой целое неотрицательное число. Длина, принимаемая по умолчанию, равна количеству символов в значении инфо.
    Ниже приведено несколько примеров: ABBREV('Print','Pri') -> 1 ABBREV('PRINT','Pri') -> 0 ABBREV('PRINT','PRI',4) -> 0 ABBREV('PRINT','PRY') -> 0 ABBREV('PRINT','') -> 1 ABBREV('PRINT','',1) -> 0
    Прим.Если указана длина, равная 0, то это соответствует пустой строке (или значению по умолчанию). Поэтому при желании можно автоматически выбирать ключевые слова, принимаемые по умолчанию. Например: say 'Введите режим:'; pull option . select /* keyword1 принимается по умолчанию */ when abbrev('keyword1',option) then ... when abbrev('keyword2',option) then ... ... otherwise nop; end;



    ABS (Абсолютное значение)

    ABS (Абсолютное значение)
    Функция ABS возвращает абсолютное значение числа. Результат не имеет знака и форматирован в соответствии с текущими установками NUMERIC.
    Ниже приведено несколько примеров: ABS('12.3') -> 12.3 ABS(' -0.307') -> 0.307


    ADDRESS

    ADDRESS
    Функция ADDRESS возвращает текущее имя среды, в которую будут направляться команды компьютера. Обрамляющие пробелы из результата удаляются.
    Ниже приведено несколько примеров: ADDRESS( ) -> 'CMD' /* среда OS/2 */ ADDRESS( ) -> 'EDIT' /* среда редактора */


    ARG

    ARG
    Функция ARG возвращает процедуре или внутренней программе строку аргументов или информацию о строках аргументов.
    Если Вы не указываете параметр, то в качестве результата будет возвращено количество аргументов, переданных процедуре или внутренней программе.
    Если Вы укажете только n, то в качестве результата будет возвращена строка аргументов с порядковым номером n. При отсутствии строки аргументов в качестве результата возвращается пустая строка. Значение n должно быть целым положительным числом.
    Если указан режим, то функция ARG проверяет наличие строки аргументов с порядковым номером n. Действительными режимами для функции ARG (при указании которых имеют значение только начальные буквы, остальные игнорируются) являются следующие:

    Exists Возвращает результат 1, если существует аргумент с порядковым номером n; т.е. если этот аргумент был явно указан при вызове программы. В противном случае возвращается результат 0.
    Omitted Возвращает результат 1, если опущен аргумент с порядковым номером n; т.е. если этот аргумент не был явно указан при вызове программы. В противном случае возвращается результат 0.

    Ниже приведено несколько примеров: /* строка вызова подпрограммы: "Call name;" (без аргументов) */ ARG( ) -> 0 ARG(1) -> '' ARG(2) -> '' ARG(1,'e') -> 0 ARG(1,'O') -> 1
    /* строка вызова подпрограммы: "Call name 'a',,'b';" */ ARG( ) -> 3 ARG(1) -> 'a' ARG(2) -> '' ARG(3) -> 'b' ARG(n) -> '' /* для n>=4 */ ARG(1,'e') -> 1 ARG(2,'E') -> 0 ARG(2,'O') -> 1 ARG(3,'o') -> 0 ARG(4,'o') -> 1
    Примечания:
  • Вы можете восстановить и непосредственно разобрать по переменным строки аргументов для программы или внутренней функции с помощью инструкции ARG или PARSE ARG.
  • Программы, вызываемые как команды, могут иметь только одну строку аргументов или не иметь их вовсе. Считается, что программа не имеет аргументов, если она вызывается только по имени; и имеет одну строку аргументов, если к имени команды добавлено еще что-нибудь (включая пробелы).
  • Программы, вызываемые с помощью точки входа REXXSTART, могут иметь множество строк аргументов.




    B2X (Двоичное в шестнадцатеричное)

    B2X (Двоичное в шестнадцатеричное)
    Функция B2X преобразует двоичную_строку, т.е. строку, состоящую из цифр (0 или 1), в эквивалентную строку шестнадцатеричных символов. В двоичную_строку для обеспечения лучшей читабельности можно при желании включать пробелы (не обрамляющие, а только ограничивающие четыре цифры); при преобразовании они игнорируются.
    При записи шестнадцатеричных цифр в результирующей строке для значений A-F используются строчные буквы; пробелы в строку не включаются.
    Двоичная_строка может иметь любую длину; если она пустая, то и результирующая строка тоже будет пустой. Если количество двоичных цифр в строке не кратно четырем, то перед выполнением преобразования слева добавляются нули (максимум три нуля), пока количество цифр не станет кратно четырем.
    Ниже приведено несколько примеров: B2X('11000011') == 'C3' B2X('10111') == '17' B2X('101') == '5' B2X('1 1111 0000') == '1F0'
    Функция B2X( ) может использоваться вместе с функциями X2D( ) и X2C( ) для преобразования двоичного числа в число с другим представлением. Например: X2D(B2X('10111')) == '23' /* десятичное 23 */





    BEEP

    BEEP
    Функция BEEP подает звуковой сигнал на частоте (герц) с указанной длительностью (миллисекунд). Частота может быть любым числом в диапазоне от 37 до 32767 герц. Длительность может быть любым числом в диапазоне от 1 до 60000 миллисекунд.
    Эта функция полезна в случае, когда ее вызывают как подпрограмму. Возвращенная пустая строка свидетельствует об успешном завершении функции.
    Ниже приведен пример: /* C гамма */ note.1 = 262 /* среднее C */ note.2 = 294 /* D */ note.3 = 330 /* E */ note.4 = 349 /* F */ note.5 = 392 /* G */ note.6 = 440 /* A */ note.7 = 494 /* B */ note.8 = 524 /* C */
    do i=1 to 8 call beep note.i,250 /* держит каждую ноту */ /* в течение четверти секунды */ end


    BITAND

    BITAND
    Функция BITAND в качестве результата возвращает строку, состоящую из двух логически объединенных вводных строк (бит за битом с помощью оператора логического И). Результирующая строка имеет длину, равную длине большей из двух объединяемых строк. Если символ-заполнитель не указан, то операция логического И завершается по достижении конца более короткой строки, и необработанная часть более длинной строки добавляется в конец результата. Если же символ-заполнитель указан, то перед выполнением логической операции более короткая строка расширяется путем добавления справа этого символа-заполнителя. По умолчанию в качестве строки2 принимается строка нулевой длины (пустая).
    Ниже приведено несколько примеров: BITAND('73'x,'27'x) -> '23'x BITAND('13'x,'5555'x) -> '1155'x BITAND('13'x,'5555'x,'74'x) -> '1154'x BITAND('pQrS',,'DF'x) -> 'PQRS' /* только в ASCII */


    BITOR

    BITOR
    Функция BITOR в качестве результата возвращает строку, состоящую из двух логически объединенных вводных строк (бит за битом с помощью оператора логического ИЛИ). Результирующая строка имеет длину, равную длине большей из двух объединяемых строк. Если символ-заполнитель не указан, то операция логического ИЛИ завершается по достижении конца более короткой строки, и необработанная часть более длинной строки добавляется в конец результата. Если же символ-заполнитель указан, то перед выполнением логической операции более короткая строка расширяется добавлением справа этого символа-заполнителя. По умолчанию в качестве строки2 принимается строка нулевой длины (пустая).
    Ниже приведено несколько примеров: BITOR('15'x,'24'x) -> '35'x BITOR('15'x,'2456'x) -> '3556'x BITOR('15'x,'2456'x,'F0'x) -> '35F6'x BITOR('1111'x,,'4D'x) -> '5D5D'x BITOR('pQrS',,'20'x) -> 'pqrs' /* только в ASCII */


    BITXOR

    BITXOR
    Функция BITXOR в качестве результата возвращает строку, состоящую из двух логически объединенных вводных строк (бит за битом с помощью оператора исключающего ИЛИ). Результирующая строка имеет длину, равную длине большей из двух объединяемых строк. Если символ-заполнитель не указан, то операция исключающего ИЛИ завершается по достижении конца более короткой строки, и необработанная часть более длинной строки добавляется в конец результата. Если же символ-заполнитель указан, то перед выполнением логической операции более короткая строка расширяется путем добавления справа этого символа-заполнителя. По умолчанию в качестве строки2 принимается строка нулевой длины (пустая).
    Ниже приведено несколько примеров: BITXOR('12'x,'22'x) -> '30'x BITXOR('1211'x,'22'x) -> '3011'x BITXOR('C711'x,'222222'x,' ') -> 'E53302'x /* ASCII */ BITXOR('1111'x,'444444'x) -> '555544'x BITXOR('1111'x,'444444'x,'40'x) -> '555504'x BITXOR('1111'x,,'4D'x) -> '5C5C'x


    C2D (Символьное в десятичное)

    C2D (Символьное в десятичное)
    Функция C2D в качестве результата возвращает десятичное значение двоичного представления указанной строки. Если результат не может быть представлен в виде целого числа, то выдается сообщение об ошибке. Результат не должен содержать больше цифр, чем определено в текущем назначении NUMERIC DIGITS.
    Если указанная строка пустая, то в качестве результата возвращается 0.
    Если не указано значение n, то строка обрабатывается как двоичное число без знака.
    Ниже приведено несколько примеров: C2D('09'X) -> 9 C2D('81'X) -> 129 C2D('FF81'X) -> 65409 C2D('a') -> 97 /* ASCII */
    Если значение n определено, то указанная строка заполняется слева символами 00х (без знака), или усекается слева до количества символов, равного значению n. Полученная строка из n шестнадцатеричных цифр рассматривается как двоичное число со знаком: положительное, если крайний левый бит сброшен (установлен в OFF), и отрицательное (в форме дополнения до двоичного числа два), если крайний левый бит установлен в ON. Если значение n равно 0, то в качестве результата всегда возвращается 0.
    Ниже приведено несколько примеров: C2D('81'X,1) -> -127 C2D('81'X,2) -> 129 C2D('FF81'X,2) -> -127 C2D('FF81'X,1) -> -127 C2D('FF7F'X,1) -> 127 C2D('F081'X,2) -> -3967 C2D('F081'X,1) -> -127 C2D('0031'X,0) -> 0
    Максимально допустимое значение: Вводная строка не может состоять более чем из 250 символов, которые будут значащими при формировании окончательного результата. Начальные символы, определяющие знак (00x и ffx), не учитываются в этом общем итоге.


    C2X (Символьное в шестнадцатеричное)

    C2X (Символьное в шестнадцатеричное)
    Функция C2X преобразует строку, состоящую из символов, в строку, состоящую из шестнадцатеричного представления этих символов. Данные, которые требуется преобразовать, могут иметь любую длину. Строка, полученная в результате выполнения функции, может иметь длину, вдвое превышающую первоначальную, из-за литерального представления вводной строки.
    Ниже приведено несколько примеров: C2X('0123'X) -> '0123' C2X('ZD8') -> '5A4438' /* ASCII */


    CENTER/CENTRE

    CENTER/CENTRE
    Функция CENTER или CENTRE возвращает строку указанной длины, содержащую центрированную вводную строку с символами-заполнителями, добавляемыми для увеличения длины, если это необходимо. По умолчанию символом-заполнителем является пробел. Если строка длиннее указанной длины, то она в равной мере усекается с обоих концов. Если добавляется или усекается нечетное количество символов, то справа усекается или добавляется на один символ больше, чем слева.
    Ниже приведено несколько примеров: CENTER(abc,7) -> ' ABC ' CENTER(abc,8,'-') -> '--ABC---' CENTRE('The blue sky',8) -> 'e blue s' CENTRE('The blue sky',7) -> 'e blue '
    Прим.Данная функция может быть вызвана как по имени CENTRE, так и по имени CENTER. Это позволяет избежать синтаксических ошибок, которые могут возникнуть из-за различного написания слова 'ЦЕНТР' в английской и американской интерпретации.



    CHARIN

    CHARIN
    Функция CHARIN возвращает в качестве результата строку размером до указанной длины, состоящую из символов, прочитанных из вводного потока с указанным именем. Форма, в которой указывается имя, зависит от среды применения. Если имя опущено, то символы читаются из вводного потока STDIN:, определяемого по умолчанию. Длина, принимаемая по умолчанию, равна 1.
    В устойчивых потоках позиция чтения ведется для каждого потока. В операционной системе OS/2 эта позиция та же, что и позиция записи. По умолчанию любое чтение из потока начинается с текущей позиции чтения. Когда чтение завершено, позиция чтения наращивается на величину прочитанных символов. Значение начала может быть указано для определения конкретной позиции чтения и должно быть целым положительным числом в пределах длины потока. Данная позиция чтения не может быть указана для переменных потоков (порт или другое последовательное устройство). Значение 1, указанное для начала, определяет первый символ в потоке.
    Если значение длины задано равным нулю, то позиция чтения устанавливается по значению, указанному в начале, но символы не читаются и в качестве результата возвращается пустая строка.
    В переменных потоках, если количество доступных символов меньше указанной длины, то выполнение программы временно приостанавливается до тех пор, пока достаточное количество символов не станет доступным. Если требуемое количество символов невозможно сделать доступным вследствие ошибки или других проблем, то будет сформировано условие NOTREADY и функция CHARIN вернет результирующую строку с количеством символов, меньшим, чем требовалось.
    Ниже приведено несколько примеров: CHARIN(myfile,1,3) -> 'MFC' /* первые 3 */ /* символа */ CHARIN(myfile,1,0) -> '' /* в начало */ CHARIN(myfile) -> 'M' /* после последнего вызова */ CHARIN(myfile,,2) -> 'FC' /* после последнего вызова */
    /* Чтение из вводного потока (здесь с клавиатуры) */ /* Пользователь вводит строку 'abcd efg' */ CHARIN( ) -> 'a' /* по умолчанию */ /* читается 1 символ */ CHARIN(,,5) -> 'bcd e'
    Примечание 1:

    Функция CHARIN в результирующую строку помещает все символы, встретившиеся во вводном потоке, включая символы перевода строки, возврата каретки и конца файла.
    Примечание 2:

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


    CHAROUT

    CHAROUT
    Функция CHAROUT возвращает количество символов, оставшихся после попытки записать строку в выходной поток символов с указанным именем. Форма, в которой указывается имя, зависит от среды применения. Если имя опущено, то символы в строке будут записаны в выходной поток STDOUT: (обычно это дисплей), принимаемый по умолчанию в операционной системе OS/2. строка может быть пустой; в этом случае символы в выходной поток не записываются и в качестве результата всегда возвращается значение 0.
    В устойчивых потоках позиция записи ведется для каждого потока. В операционной системе OS/2 эта позиция та же, что и позиция чтения. По умолчанию любая запись в выходной поток начинается с текущей позиции записи. Когда запись завершена, позиция записи наращивается на величину записанных символов. Первоначальной позицией записи является конец потока, поэтому обращение к функции CHAROUT обычно влечет за собой добавление символов в конец выходного потока.
    Значение начала может быть указано для устойчивого потока, чтобы определить конкретную позицию записи, и должно быть целым положительным числом в пределах длины потока (хотя оно может указывать позицию символа, непосредственно следующего за последним символом данного потока). Значение 1, указанное для начала, определяет первый символ в потоке.
    Прим.В некоторых средах перезапись потока с помощью функций CHAROUT или LINEOUT может удалить (разрушить) все существующие данные в потоке. Однако это не относится к среде OS/2.

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

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

    Ниже приведено несколько примеров: CHAROUT(myfile,'Hi') -> 0 /* как обычно */ CHAROUT(myfile,'Hi',5) -> 0 /* как обычно */ CHAROUT(myfile,,6) -> 0 /* сейчас в позиции 6 */ CHAROUT(myfile) -> 0 /* в конце потока */ CHAROUT(,'Hi') -> 0 /* как обычно */ CHAROUT(,'Hello') -> 2 /* может быть */

    Прим. Эту функцию зачастую лучше вызывать как подпрограмму. Остаточное количество символов в этом случае будет доступно в качестве значения переменной RESULT.
    Например: Call CHAROUT myfile,'Hello' Call CHAROUT myfile,'Hi',6 Call CHAROUT myfile



    CHARS

    CHARS
    Функция CHARS в качестве результата возвращает общее количество символов, оставшихся во вводном потоке с указанным именем. Это количество включает в себя все символы-разделители, если они определены для данного потока; и в случае устойчивых потоков представляет собой количество символов, начиная с текущей позиции чтения до конца потока. Если имя опущено, то операционная система OS/2 будет использовать STDIN: в качестве значения по умолчанию.
    Для некоторых потоков (например, STDIN) невозможно определить общее количество оставшихся символов. Для потоков такого рода функция CHARS в качестве результата возвращает 1 при наличии данных и 0 - при их отсутствия. Для устройств операционной системы OS/2 функция CHARS всегда возвращает результат 1.
    Ниже приведено несколько примеров: CHARS(myfile) -> 42 /* возможно */ CHARS(nonfile) -> 0 /* возможно */ CHARS() -> 1 /* возможно */


    COMPARE

    COMPARE
    Функция COMPARE в качестве результата возвращает 0, если строки строка1 и строка2 идентичны. В противном случае функция COMPARE в качестве результата возвращает позицию первого несовпадающего символа. При необходимости более короткая строка дополняется справа символами-заполнителями. По умолчанию в качестве символа-заполнителя используется пробел.
    Ниже приведено несколько примеров: COMPARE('abc','abc') -> 0 COMPARE('abc','ak') -> 2 COMPARE('ab ','ab') -> 0 COMPARE('ab ','ab',' ') -> 0 COMPARE('ab ','ab','x') -> 3 COMPARE('ab-- ','ab','-') -> 5


    CONDITION

    CONDITION
    Функция CONDITION в качестве результата возвращает информацию, связанную с условием, которое отслеживается в настоящий момент. Вы можете получить следующую информацию:
  • Имя условия, которое отслеживается в настоящий момент
  • Любую описательную строку, связанную с этим условием
  • Инструкцию, выполненную как результат отслеживания условия (CALL или SIGNAL)
  • Состояние отслеживаемого условия.
    В функции CONDITION могут быть указаны следующие режимы (значащими являются только заглавные буквы режимов, остальные игнорируются):
    Condition name Возвращает имя условия, которое отслеживается в настоящий момент.
    Description Возвращает любую описательную строку, связанную с условием, которое отслеживается в настоящий момент. Если описательные строки отсутствуют, то в качестве результата возвращается пустая строка.
    Instruction Возвращает ключевое слово инструкции, выполнявшейся в момент обнаружения условия, которое отслеживается в настоящий момент. Ключевыми словами могут быть CALL или SIGNAL. Если Вы не укажете режим, то будет принят режим по умолчанию.
    Status Возвращает состояние условия, которое отслеживается в настоящий момент. Оно может меняться в процессе выполнения и принимать следующие значения:


    ON - отслеживание условия включено
    OFF - отслеживание условия выключено
    DELAY - обработка любого последующего условия требуемого типа задерживается.

    Если нет условий, которые требуется отслеживать (т.е. не существует условия, которое отслеживается в настоящий момент), то функция CONDITION в качестве результата возвращает пустую строку для всех четырех режимов.
    Ниже приведено насколько примеров: CONDITION() -> 'CALL' /* возможно */ CONDITION('C') -> 'FAILURE' CONDITION('I') -> 'CALL' CONDITION('D') -> 'FailureTest' CONDITION('S') -> 'OFF' /* возможно */
    Прим. Информация об условии, выдаваемая функцией CONDITION, в случае обращения процедуры к подпрограммам сохраняется и восстанавливается (включая информацию, получаемую по CALL ON). Поэтому, когда подпрограмма, вызванная по CALL ON, завершается, то условием, отслеживаемым в настоящий момент, становится то, которое имело место перед выполнением инструкции CALL. Функция CONDITION возвращает значения перед тем, как отслеживаемое условие было обнаружено.



    COPIES

    COPIES
    Функция COPIES в качестве результата возвращает n связанных вместе копий указанной строки. n должно быть целым неотрицательным числом.
    Ниже приведено несколько примеров: COPIES('abc',3) -> 'abcabcabc' COPIES('abc',0) -> ''





    D2C (Десятичное в символьное)

    D2C (Десятичное в символьное)
    Функция D2C в качестве результата возвращает символьную строку, являющуюся представлением десятичного числа в коде ASCII. Если Вы укажете n, то это значение будет являться длиной полученного символьного результата (при необходимости для достижения требуемой длины добавляются символы начальных нулей).
    Если значение n не указано, то целое-число должно быть неотрицательным числом и результирующая строка имеет фактическую длину; поэтому возвращенный результат не содержит символов начальных нулей.
    Ниже приведено несколько примеров: D2C(65) -> 'A' /* '41'x = 'A' в коде ASCII */ D2C(65,1) -> 'A' D2C(65,2) -> ' A' D2C(65,5) -> ' A' D2C(109) -> 'm' /* '6D'x = 'm' в коде ASCII */ D2C(-109,1) -> 'У' /* '147'x = 'У' в коде ASCII */ D2C(76,2) -> ' L' /* '76'x = ' L' в коде ASCII */ D2C(-180,2) -> ' L'


    D2X (Десятичное в шестнадцатеричное)

    D2X (Десятичное в шестнадцатеричное)
    Функция D2X в качестве результата возвращает строку шестнадцатеричных символов, которые являются шестнадцатеричным представлением десятичного числа.
    Если значение n не указано, то целое-число должно быть неотрицательным числом и при этом возвращенный результат не содержит символов начальных нулей.
    Если значение n определено, то оно представляет собой длину окончательного результата в символах; т.е. после преобразования исходной строки результат расширяется знаковым разрядом до требуемой длины. Если преобразованное число слишком велико, чтобы поместиться в указанные n символов, то оно усекается слева.
    Ниже приведено несколько примеров: D2X(9) -> '9' D2X(129) -> '81' D2X(129,1) -> '1' D2X(129,2) -> '81' D2X(129,4) -> '0081' D2X(257,2) -> '01' D2X(-127,2) -> '81' D2X(-127,4) -> 'FF81' D2X(12,0) -> ''
    Максимально возможное значение: Результирующая выводная строка не может состоять более чем из 250 значащих шестнадцатеричных символов, хотя возможно получение более длинной строки результата за счет добавочных начальных символов, определяющих знак (0 и F).


    DATATYPE

    DATATYPE
    Функция DATATYPE определяет, являются ли 'данные' цифровыми или алфавитными, и в качестве результата возвращает соответственно NUM или CHAR. Если из параметров указана только строка, то DATATYPE в качестве результата возвращает NUM (если строка представляет собой число (в любом формате), действительное для REXX); в противном случае результатом будет CHAR.
    Если указан тип, то результат будет равен 1 (если тип символов в строке совпадает с требуемым); в противном случае результат будет равен 0. Если указана пустая строка, то в качестве результата возвращается 0 (исключая случаи, когда типом является X, что влечет за собой возврат результата 1). Ниже приведен список типов, действительных для функции DATATYPE. Следует отметить, что только заглавные буквы в указанных типах являются значащими (все остальные игнорируются).
    Alphanumeric Возвращает 1, если указанная строка содержит только те символы, которые находятся в диапазонах a-z, A-Z и 0-9.
    Bits Возвращает 1, если указанная строка содержит только символы 0 и/или 1.
    C Возвращает 1, если указанная строка является смешанной строкой, состоящей из символов SBCS/DBCS.
    Dbcs Возвращает 1, если указанная строка является чистой строкой DBCS.
    Lowercase Возвращает 1, если указанная строка содержит только те символы, которые находятся в диапазоне a-z.
    Mixed case Возвращает 1, если указанная строка содержит только те символы, которые находятся в диапазонах a-z и A-Z.
    Number Возвращает 1, если указанная строка является числом, действительным для REXX.
    Symbol Возвращает 1, если указанная строка содержит только лишь те символы, которые действительны для REXX. Заметим, что допустимо указание как строчных, так и прописных букв.
    Uppercase Возвращает 1, если указанная строка содержит только те символы, которые находятся в диапазоне A-Z.
    Whole number Возвращает 1, если указанная строка является целым числом (по правилам REXX) по текущему назначению NUMERIC DIGITS.
    heXadecimal Возвращает 1, если указанная строка содержит только те символы, которые находятся в диапазонах a-f, A-F, 0-9 и пробел (в случаях, когда пробелы появляются между парами шестнадцатеричных символов). Возвращает 1 и в том случае, если указанная строка является пустой.
    DATATYPE(' 12 ') -> 'NUM' DATATYPE('') -> 'CHAR' DATATYPE('123*') -> 'CHAR' DATATYPE('12.3','N') -> 1 DATATYPE('12.3','W') -> 0 DATATYPE('Fred','M') -> 1 DATATYPE('','M') -> 0 DATATYPE('Fred','L') -> 0 DATATYPE('?20K','S') -> 1 DATATYPE('BCd3','X') -> 1 DATATYPE('BC d3','X') -> 1


    DATE

    DATE
    Функция DATE по умолчанию возвращает текущую дату в следующем формате: дд мес гггг (например, "27 Авг 1988") без указания начального нуля или пробела перед числом, которое определяет день. Для мес используются три первых буквы русского названия месяца.
    Для получения текущей даты в альтернативном формате можно использовать следующие режимы (при указании которых значащими являются только заглавные буквы, остальные игнорируются):
    Basedate Возвращает количество полных дней (т.е. не включая текущий день), начиная от базовой даты (Январь 1, 0001) и включая ее. Результат выдается в следующем формате: дддддд (без начальных нулей). Функция, заданная в виде DATE(B)//7, в качестве результата возвращает число из диапазона 0-6, где 0 соответствует Понедельнику и 6 - Воскресенью.
    Прим. Базовая дата Январь 1, 0001 основана на Григорианском календаре. Несмотря на то, что этот календарь не существовал до 1582 года, количество дней, истекших с 1 Января 0001 года, вычисляется следующим образом: 365 дней в году плюс 1 дополнительный день на каждые четыре года (исключая годы, символизирующие век: 100, 200 и т.д.) плюс 1 дополнительный день на каждый 400-ый год (400, 800 и т.д.). В расчет не принимаются ошибки в календарной системе, которые изначально привели к созданию Григорианского календаря.
    Days Возвращает количество дней (включая текущий), прошедших с начала настоящего года, в следующем формате: ддд (без начальных нулей)
    European Возвращает дату в следующем формате: дд/мм/гг.
    Language Возвращает дату в формате, зависящем от языка и реализации, либо в формате текущей даты. В операционной системе OS/2 формат Language имеет следующий вид: дд Месяц гггг. Если недоступен ни один текущий формат, то дата возвращается в формате, принятом по умолчанию.
    Прим. Данный формат предназначается для использования целиком; процедуры REXX не должны делать никаких предположений, касающихся формы или содержимого строки результата.
    <
    Month Возвращает полное русское название текущего месяца, например, "Август"
    Normal Возвращает дату в формате, принятом по умолчанию: дд мес гггг
    Ordered Возвращает дату в формате: гг/мм/дд (удобно для сортировки и т.п.)
    Sorted Возвращает дату в формате: ггггммдд (удобно для сортировки и т.п.)
    Usa Возвращает дату в формате: мм/дд/гг
    Weekday Возвращает русское название дня недели, выдаваемое на смешанном регистре. Например,
    Ниже приведено несколько примеров: DATE( ) -> '27 Авг 1988' /* возможно */ DATE('B') -> 725975 DATE('D') -> 240 DATE('E') -> '27/08/88' DATE('L') -> '27 Август 1988' DATE('M') -> 'Август' DATE('N') -> '27 Авг 1988' DATE('O') -> '88/08/27' DATE('S') -> '19880827' DATE('U') -> '08/27/88' DATE('W') -> 'Суббота'

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


    DELSTR (Удаление строки)

    DELSTR (Удаление строки)
    Функция DELSTR удаляет из указанной строки подстроку, которая начинается с n-ного символа и имеет указанную длину. Если длина не определена, то удаляется остаток строки. Если значение n больше, чем длина указанной строки, то результирующая строка возвращается неизмененной. Значение n должно быть целым положительным числом.
    Ниже приведено несколько примеров: DELSTR('abcd',3) -> 'ab' DELSTR('abcde',3,2) -> 'abe' DELSTR('abcde',6) -> 'abcde'


    DELWORD

    DELWORD
    Функция DELWORD удаляет из указанной строки подстроку, которая начинается с n-ного слова. В качестве длины указывается число слов, разделенных между собой пробелами. Если длина не определена, то по умолчанию удаляется остаток слов в строке. Значение n должно быть целым положительным числом. Если значение n больше, чем количество слов в строке, то строка возвращается неизмененной. Удаленная строка включает в себя все пробелы, следующие за последним удаляемым словом.
    Ниже приведено несколько примеров: DELWORD('Now is the time',2,2) -> 'Now time' DELWORD('Now is the time ',3) -> 'Now is ' DELWORD('Now is the time',5) -> 'Now is the time'


    DIGITS

    DIGITS
    Функция DIGITS возвращает текущее назначение NUMERIC DIGITS.
    Ниже приведен пример: DIGITS() -> 9 /* по умолчанию */


    DIRECTORY

    DIRECTORY
    Функция DIRECTORY в качестве результата возвращает имя текущего каталога, если функция используется без параметров; и изменяет имя текущего каталога на новый-каталог, если аргумент указан и каталог с указанным именем существует.
    Возвращенная результирующая строка включает в себя префикс буквы устройства в качестве первых двух символов имени каталога. Указание префикса буквы устройства как части значения нового-каталога приводит к тому, что указанное устройство становится текущим. Если буква устройства не указана, то текущее устройство остается неизменным.
    Например, в приведенном ниже фрагменте процедуры сохраняется имя текущего каталога и происходит переключение на новый каталог. В этом каталоге выполняются некоторые действия, а затем осуществляется возврат к старому каталогу. /* получить текущий каталог */ curdir = directory() /* поиграть в игру */ newdir = directory("d:/usr/games") if newdir = "d:/usr/games" then do fortune /* вызов игры */ /* возврат к старому каталогу */ call directory curdir end else say 'Невозможно найти /usr/games'





    ENDLOCAL

    ENDLOCAL
    Функция ENDLOCAL восстанавливает каталог и переменные среды, которые были активны перед последним выполнением функции SETLOCAL. Если функция ENDLOCAL не включена в процедуру, то при выходе из процедуры восстанавливается исходная среда, сохраненная функцией SETLOCAL.
    ENDLOCAL в качестве результата возвращает значение 1, если исходная среда успешно восстановлена, и значение 0, если восстановление прошло неуспешно, либо функция SETLOCAL предварительно не выдавалась.
    Прим.В отличие от своих двойников в языке команд OS/2 (операторы Setlocal и Endlocal), функции языка REXX SETLOCAL и ENDLOCAL могут быть вложенными.

    Ниже приведен пример: n = SETLOCAL() /* сохраняет имя текущей среды */
    /* Теперь программа изменяет переменные */ /* среды (с помощью функции VALUE) и затем */ /* работает в измененной среде. */
    n = ENDLOCAL() /* восстанавливает текущую среду */
    Для просмотра дополнительных примеров обратитесь к описанию функции SETLOCAL.


    ERRORTEXT

    ERRORTEXT
    Функция ERRORTEXT в качестве результата возвращает сообщение об ошибке, которое соответствует указанному номеру n. Значение n должно быть в пределах от 0 до 99; указание любого другого значения является ошибкой. Если указанное значение n находится в допустимом диапазоне, но для него не определено никакое сообщение об ошибке языка REXX, то в качестве результата возвращается пустая строка.
    Ниже приведено несколько примеров: ERRORTEXT(16) -> 'Метка не найдена' ERRORTEXT(60) -> ''


    FILESPEC

    FILESPEC
    Функция FILESPEC в качестве результата возвращает выбранный элемент из указанной спецификации-файла. Выбор элемента осуществляется в соответствии с указанным режимом, перечень которых приведен ниже:
    Drive Возвращает букву устройства для файла с указанной спецификацией-файла.
    Path Возвращает путь через каталоги для файла с указанной спецификацией-файла.
    Name Возвращает имя файла для указанной спецификации-файла.

    Если запрашиваемая строка не найдена, то в качестве результата функция FILESPEC возвращает пустую строку (" ").
    Прим. При задании режима значащей будет только первая буква, остальные игнорируются.

    Ниже приведено несколько примеров: thisfile = "C:\OS2\UTIL\EXAMPLE.EXE" say FILESPEC("drive",thisfile) /* выведет "C:" */ say FILESPEC("path",thisfile) /* выведет "\OS2\UTIL\" */ say FILESPEC("name",thisfile) /* выведет "EXAMPLE.EXE" */
    part = "name" say FILESPEC(part,thisfile) /* выведет "EXAMPLE.EXE" */


    FORM

    FORM
    Функция FORM в качестве результата возвращает текущее назначение NUMERIC FORM.
    Ниже приведен пример: FORM() -> 'SCIENTIFIC' /* по умолчанию */


    FORMAT

    FORMAT
    Функция FORMAT в качестве результата возвращает число, округленное и форматированное.
    Указанное число сначала округляется и форматируется в соответствии со стандартными правилами языка REXX, как если бы была выполнена операция число+0. Если указано только число, то результат будет в точности равен результату данной операции. Если указан какой-либо режим, то число форматируется в соответствии с правилами, оговоренными для каждого режима.
    Режимы до и после указывают, сколько позиций должно использоваться для записи соответственно целой и дробной части результата. Если оба этих режима или какой-либо из них опущен, то результат возвращается таким, каков он на самом деле.
    Если указанное значение режима до недостаточно велико, чтобы вместить целую часть числа, то выдается сообщение об ошибке. Если же значение до слишком велико, то целая часть числа дополняется слева пробелами. В случаях, когда указанное значение режима после не совпадает с размером десятичной части числа, число округляется до требуемого количества знаков или дополняется справа нулями. Если же в качестве значения данного режима указывается 0, то число округляется до целого.
    Ниже приведено несколько примеров: FORMAT('3',4) -> ' 3' FORMAT('1.73',4,0) -> ' 2' FORMAT('1.73',4,3) -> ' 1.730' FORMAT('-.76',4,1) -> ' -0.8' FORMAT('3.03',4) -> ' 3.03' FORMAT(' - 12.73',,4) -> '-12.7300' FORMAT(' - 12.73') -> '-12.73' FORMAT('0.000') -> '0'
    Первые три режима описаны выше. Режимы expp и expt управляют выводом результата в экспоненциальной форме: expp указывает число позиций, требующихся для написания показателя степени; по умолчанию используется столько, сколько нужно. expt устанавливает точку отсчета для представления результата в экспоненциальной форме. Если количество позиций целой части числа превышает значение expt, то используется экспоненциальная форма представления результата. Экспоненциальная форма используется и тогда, когда количество позиций, требующихся для записи десятичной части числа, вдвое превышает значение expt.
    По умолчанию принимается текущее назначение NUMERIC DIGITS. Если в качестве значения expt указан 0, то экспоненциальная форма записи результата будет использоваться всегда, несмотря на то, что показатель степени может быть равен 0. Значение expp должно быть меньше 10, а на остальные режимы ограничений не существует. Если в качестве значения expp указан 0, то экспоненциальная форма представления результата не используется, и число записывается в простой форме с дополнительными нулями, если это необходимо (отменяет значение 0 режима expt). Однако, если значение expp не настолько велико, чтобы вместить требуемый показатель степени, то выдается сообщение об ошибке. Если же показатель степени равен 0, то в этом случае (при ненулевом значении expp) для записи экспоненциальной части результата используется expp+2 пробела.

    Ниже приведено несколько примеров: FORMAT('12345.73',,,2,2) -> '1.234573E+04' FORMAT('12345.73',,3,,0) -> '1.235E+4' FORMAT('1.234573',,3,,0) -> '1.235' FORMAT('12345.73',,,3,6) -> '12345.73' FORMAT('1234567e5',,3,0) -> '123456700000.000'



    Функции API

    Следующие встроенные функции REXX можно использовать в процедурах REXX для регистрации, освобождения или опроса пакетов внешних функций, а также для создания и манипуляции очередями внешних данных.
    RXFUNCADD
    Функции API
    RXFUNCADD регистрирует функцию с указанным именем и делает ее доступной для процедур REXX. Код возврата, равный 0, свидетельствует об успешной регистрации.
    RXFUNCDROP
    Функции API
    RXFUNCDROP перемещает (удаляет) функцию с указанным именем из списка доступных функций. Код возврата, равный 0, свидетельствует об успешном удалении.
    RXFUNCQUERY
    Функции API
    RXFUNCQUERY запрашивает список доступных функций для регистрации функции с указанным именем. Код возврата, равный 0, свидетельствует о регистрации функции; код возврата, равный 1, свидетельствует о том, что функция не зарегистрирована.
    RXQUEUE
    Функции API
    RXQUEUE используется в процедурах REXX для создания и удаления очередей внешних данных, а также для установления и опроса имен этих очередей.


    Примечания:

  • Вызов внешней программы REXX как функции аналогичен вызову внутренней программы. Однако внешняя программа является неявной ПРОЦЕДУРОЙ, в которой всегда удаляются все переменные вызывающей программы и состояние внутренних значений (назначения NUMERIC и т.д.) принимается по умолчанию (а не передаются из вызывающей программы).

  • Другие программы REXX могут быть вызваны как функции. Вы можете использовать инструкции EXIT или RETURN для выхода из вызванной программы REXX; в любом случае нужно указать выражение.

    Порядок просмотра

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

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

    Пример: /* Модифицированная DATE, выдающая по умолчанию отсортированную дату */ date: procedure arg in if in='' then in='Sorted' return 'DATE'(in)

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

    Внешние функции и подпрограммы имеют системно-зависимый порядок поиска.

    REXX осуществляет поиск внешних функций в следующем порядке:

  • Функции, которые были загружены в макропространство для внеочередного выполнения
  • Функции, являющиеся частью пакета функций
  • Функции REXX, расположенные в текущем каталоге, с текущим расширением
  • Функции REXX, расположенные по пути, заданному переменной среды PATH, с текущим расширением
  • Функции REXX, расположенные в текущем каталоге, со стандартным расширением
  • Функции REXX, расположенные по пути, заданному переменной среды PATH, со стандартным расширением
  • Функции, которые были загружены в макропространство для выполнения в последнюю очередь.


    Ошибки во время выполнения

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

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

    Возвращаемые значения

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

    Способ обработки значений, возвращенных в результате выполнения функции (или любой программы REXX), зависит от того, как она была вызвана: как функция или как подпрограмма с помощью инструкции CALL.

    Программа, вызываемая как подпрограмма: Если программа возвращает некоторое значение, то оно запоминается в специальной переменной с именем RESULT. В противном случае переменная RESULT освобождается и ее значением является строка RESULT.

    Программа, вызываемая как функция: Если функция возвращает некоторое значение, то оно подставляется в выражение в ту позицию, в которой ранее был указан вызов функции. В противном случае REXX прекращает обработку и выдает сообщение об ошибке.

    Примеры:

    /* Различные способы вызова процедуры REXX */ call Beep 500, 100 /* Пример 1: вызов подпрограммы */ bc = Beep(500, 100) /* Пример 2: вызов функции */ Beep(500, 100) /* Пример 3: результат, переданный */ /* как команда */

  • В примере 1 встроенная функция BEEP вызывается как подпрограмма REXX. Значение, возвращаемое из BEEP, помещается в специальную переменную RESULT языка REXX.

  • В примере 2 BEEP вызывается как функция REXX. Значение, возвращаемое функцией, записывается в ту позицию, в которой ранее был указан вызов функции. Предложение само по себе является оператором присваивания, поэтому значение, возвращенное после выполнения функции BEEP, помещается в переменную bc.


  • В примере 3 функция BEEP выполняется и значение, полученное после ее выполнения, подставляется в выражение для вызова функции, как в примере 2. Однако в этом случае предложение сводится к единственному выражению; поэтому вычисленное выражение передается как команда в текущую среду.

    Прим. Многие другие языки (такие как С) не используют значение, возвращаемое после выполнения функции, если оно не присвоено какой-либо переменной. Однако в языке REXX возвращаемое значение (как показано в примере 3) передается в текущую среду либо обработчику подкоманд. Если текущая среда - CMD (по умолчанию), то это действие вызовет поиск операционной системой на диске команды с указанным именем.
    Встроенные функции

    Язык REXX предлагает широкий выбор встроенных функций. Среди них есть функции для работы с символами, функции преобразования и информационные функции.

    Ниже приведены общие замечания, касающиеся встроенных функций:

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

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

  • Вы можете указать пустую строку там, где имеется ссылка на строку.

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

  • Если последний аргумент необязателен, то Вы можете указать вместо него запятую, чтобы обозначить его отсутствие; например, DATATYPE(1,) и DATATYPE(1) будут выполняться совершенно аналогично.

  • Если Вы указываете символ-заполнитель, то его длина не должна превышать длину одного символа.

  • Если у функции есть подрежимы, которые Вы можете выбрать, указывая первый символ строки, то этот символ может быть записан строчными или прописными буквами.

  • Преобразование между символьным и шестнадцатеричным видом влечет за собой машинное представление символьных строк, поэтому машины, работающие в кодах ASCII и EBCDIC, возвращают соответственно различные результаты.

  • Некоторые функции, описанные в этом разделе, поддерживают набор двухбайтовых символов (DBCS). Список таких функций приведен в документе Язык процедур 2/REXX для OS/2. Справочник.


    Функции

    Синтаксис
    Вы можете включить вызов функции в выражение, расположенное во внутренней или внешней программе в любом месте, где могут использоваться данные (например, строка). Вызов функции осуществляется по следующей схеме:
    Функции
    Имя-функции представляет собой текстовую строку или единственный символ, которые являются константами.
    В скобках можно указать до 20 выражений, разделенных запятыми. Эти выражения называются аргументами функции. Каждое выражение может также включать в себя вызов функции.
    Скобка должна следовать непосредственно за именем функции без пробелов между ними, иначе конструкция не будет распознана как вызов функции. (В этом случае предполагается наличие пустого оператора.)
    Аргументы вычисляются по очереди слева направо, а затем результаты передаются функции. Это влечет за собой выполнение некоторых операций (обычно зависящих от переданных аргументов, хотя аргументы задавать необязательно) и, возможно, возврат единственной строки символов. Полученная строка затем включается в исходное выражение, как если бы обращение к функции было заменено именем переменной, содержащей данные результирующей строки.
    Например, функция SUBSTR встроена в языковый процессор. Ее можно использовать следующим образом: N1='abcdefghijk' Z1='Частью N1 является: 'Substr(N1,2,7) /* присвоит Z1 строку 'Частью N1 является: bcdefgh' */
    Если функция вызывается без аргументов, то после ее имени нужно указать скобки, иначе конструкция не будет распознана как вызов функции. date() /* возвращает дату в стандартном формате дд мм гггг */
    Обращения к функциям и подпрограммам
    Для вызова подпрограмм используется тот же механизм, что и для вызова функций. Единственное отличие состоит в том, что функции должны возвращать результаты, тогда как подпрограммы не обязаны этого делать. Следующие типы программ могут быть вызваны как функции:

    Внутренняя Если имя программы присутствует в процедуре в качестве метки, то сохраняется текущее состояние выполнения, так чтобы позднее можно было вернуться в точку вызова программы для продолжения выполнения процедуры. Затем управление передается первой найденной метке, которая совпадает с именем программы. Как и при вызове программы с помощью инструкции CALL, сохраняется также и некоторая другая информация состояния (назначения TRACE, NUMERIC и тому подобное). Для получения более подробной информации смотрите подраздел Инструкция CALL. Если внутренняя программа, которую нужно вызвать, является функцией, то Вы должны указать выражение в инструкции RETURN для возврата из функции. Это необязательно, если функцию вызывают в качестве подпрограммы.
    Пример:
    /* Рекурсивное выполнение внутренней функции... */ arg x say x'! =' factorial(x) exit
    factorial: procedure /* вычисление факториала .. */ arg n /* .. рекурсивный вызов. */ if n=0 then return 1 return factorial(n-1) * n
    FACTORIAL необычен тем, что он вызывает сам себя (это называется рекурсивным вызовом). Использование инструкции PROCEDURE гарантирует, что новая переменная n генерируется для каждого вызова).
    Встроенная Функции такого типа всегда доступны и описываются в этом разделе позднее.
    Внешняя Вы можете написать сами или использовать существующие функции, которые будут внешними для программы и языкового процессора. Внешняя функция может быть написана на любом языке (включая REXX), который поддерживает системно-зависимые интерфейсы, используемые языковым процессором для ее вызова. Следует напомнить, что внешняя программа, вызванная как функция, должна вернуть результаты данные вызывающей программе.
    <

    FUZZ

    FUZZ
    Функция FUZZ в качестве результата возвращает текущее назначение NUMERIC FUZZ.
    Ниже приведен пример: FUZZ() -> 0 /* по умолчанию */


    INSERT

    INSERT
    Функция INSERT вставляет новую строку, дополненную символами-заполнителями до требуемой длины, в целевую строку после n-ного символа. Если значение n определено, то оно должно быть неотрицательным целым числом. Если значение n больше длины целевой строки, то данная строка также будет расширена до требуемой длины с помощью символов-заполнителей. По умолчанию символом-заполнителем является пробел. Значением по умолчанию для режима n является 0, что означает вставку новой строки перед началом целевой.
    Ниже приведено несколько примеров: INSERT(' ','abcdef',3) -> 'abc def' INSERT('123','abc',5,6) -> 'abc 123 ' INSERT('123','abc',5,6,'+') -> 'abc++123+++' INSERT('123','abc') -> '123abc' INSERT('123','abc',,5,'-') -> '123--abc'





    LASTPOS

    LASTPOS
    Функция LASTPOS в качестве результата возвращает позицию последнего появления одной строки, строки-поиска, в другой, целевой-строке. Если строка-поиска не найдена в указанной строке, то в качестве результата возвращается 0. По умолчанию поиск начинается с последнего символа целевой-строки (т.е. начало=LENGTH(строка)) и строка просматривается в обратном направлении. Вы можете отменить просмотр, выполняемый по умолчанию, указав значение для режима Содержание, что будет воспринято в качестве точки, с которой начнется обратный просмотр строки. Значение режима Содержание должно быть положительным целым числом или приравниваться к значению LENGTH(строка) в случае, если указанное значение превышает длину целевой строки.
    Ниже приведено несколько примеров: LASTPOS(' ','abc def ghi') -> 8 LASTPOS(' ','abcdefghi') -> 0 LASTPOS(' ','abc def ghi',7) -> 4


    LEFT

    LEFT
    Функция LEFT в качестве результата возвращает строку указанной длины, содержащую крайние левые символы в количестве, определенном длиной, выбранные из указанной строки. Возвращенная результирующая строка при необходимости дополняется справа символами-заполнителями (или усекается). По умолчанию символом-заполнителем является пробел. Значение длины должно быть неотрицательным. Функция LEFT в точности эквивалентна следующей функции SUBSTR(строка,1,длина[,символ]).
    Ниже приведено несколько примеров: LEFT('abc d',8) -> 'abc d ' LEFT('abc d',8,'.') -> 'abc d...' LEFT('abc def',7) -> 'abc de'


    LENGTH

    LENGTH
    Функция LENGTH в качестве результата возвращает длину указанной строки.
    Ниже приведено несколько примеров: LENGTH('abcdefgh') -> 8 LENGTH('abc defg') -> 8 LENGTH('') -> 0


    LINEIN

    LINEIN
    Функция LINEIN в качестве результата возвращает содержимое некоторого количества (0 или 1) строк, прочитанных из вводного потока символов с указанным именем. Форма имени зависит от среды применения. Если имя опущено, то строка считывается из вводного потока, принимаемого по умолчанию; в операционной системе OS/2 это STDIN:. Режим количество по умолчанию принимает значение 1.
    В устойчивых потоках позиция чтения ведется для каждого потока. В операционной системе OS/2 эта позиция та же, что и позиция записи. По умолчанию любое чтение из потока начинается с текущей позиции чтения. Обращение к функции LINEIN может привести к возврату только лишь части строки, если текущая позиция чтения не установлена на начало строки. После завершения чтения позиция чтения перемещается на начало следующей строки. Позиция чтения может быть установлена на начало потока с помощью указания значения 1 для режима строка. Значение 1 - единственное действительное значение для режима строка в операционной системе OS/2.
    Если значение режима количество равно 0, то символы из вводного потока не читаются и в качестве результата возвращается пустая строка.
    В переменных потоках при отсутствии возможности прочитать из вводного потока полную строку выполнение программы временно приостанавливается до тех пор, пока строка не заполнится. Если заполнение строки невозможно вследствие ошибки или других проблем, то формируется условие NOTREADY, и функция LINEIN возвращает результирующую строку, содержащую столько символов, сколько удалось прочитать.
    Ниже приведено несколько примеров: LINEIN() /* Считывает одну строку из */ /* входного потока, принимае- */ /* мого по умолчанию; обычно */ /* это клавиатура */
    myfile = 'ANYFILE.TXT' LINEIN(myfile) -> 'Текущая строка' /* Считывает одну строку */ /* файла ANYFILE.TXT, начиная */ /* с текущей позиции чтения. */ /* (При первом обращении */ /* файл открывается и считы- */ /* вается первая строка) */
    LINEIN(myfile,1,1) ->'Первая строка' /* Открывает и считывает */ /* первую строку файла */ /* ANYFILE.TXT (если файл уже */ /* открыт, считывает первую */ /* строку); позиция чтения */ /* устанавливается на вторую строку */

    LINEIN(myfile,1,0) -> '' /* Чтение отсутствует; открывает ANYFILE.TXT */ /* (если файл уже открыт, */ /* устанавливает позицию */ /* чтения на первую строку) */

    LINEIN(myfile,,0) -> '' /* Чтение отсутствует; открывает ANYFILE.TXT */ /* ( если файл уже открыт, ни- */ /* какие действия не выполняются) */

    LINEIN("QUEUE:") -> 'Строка из очереди' /* Считывает строку из очереди; */ /* Если очередь пуста, то про- */ /* грамма ожидает до тех пор, */ /* пока строка не будет помещена в очередь */

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


    LINEOUT

    LINEOUT
    Функция LINEOUT в качестве результата возвращает количество строк, оставшихся после попытки записать строку в выводной поток символов с указанным именем. Значение результата может быть равно 0 (если строка была записана успешно) или 1 (если в процессе записи строки произошла какая-либо ошибка). В качестве строки может быть указана пустая строка, в этом случае будут выполнены только те действия, которые связаны с завершением строки. Функция LINEOUT добавляет в конец строки символы конца строки и возврата каретки.
    Форма имени зависит от среды применения. Если имя опущено, то строка записывается в выводной поток, принимаемый по умолчанию. В операционной системе OS/2 это STDOUT: (обычно экран дисплея).
    В устойчивых потоках позиция записи ведется для каждого потока. В операционной системе OS/2 эта позиция та же, что и позиция чтения. По умолчанию любая запись в выводной поток начинается с текущей позиции записи. Символы, записанные с помощью обращения к функции LINEOUT, могут быть добавлены к частичной строке. Функция LINEOUT концептуально завершает строку в конце каждого обращения к ней. После завершения записи позиция записи устанавливается на начало строки, непосредственно следующей за записанной. Исходной позицией записи является конец потока, т.е. обычно обращение к функции LINEOUT приводит к добавлению строк в конец выводного потока.
    Вы можете установить позицию записи на первый символ устойчивого потока, указав для режима линия значение 1 (единственное действительное значение).
    Прим. В некоторых средах перезапись потока с помощью функций CHAROUT или LINEOUT может удалить (разрушить) все существующие данные в потоке. Однако это не относится к среде OS/2.

    Для устойчивых потоков значение режима строка может быть опущено. Если Вы указываете режим линия, то позиция записи устанавливается на начало потока, но в выводной поток ничего не записывается и в качестве результата возвращается 0. Если же ни линия, ни строка не указаны, то позиция записи устанавливается на конец потока.
    Подобное использование функции LINEOUT имеет дополнительный эффект закрытия потока в средах (таких как OS/2), поддерживающих данную концепцию.

    Выполнение программы обычно временно приостанавливается до тех пор, пока не завершится операция вывода. Однако если строка не может быть записана, то формируется условие NOTREADY, и функция LINEOUT в качестве результата возвращает значение 1 (что свидетельствует о наличии остаточного счетчика при записи строк).

    Ниже приведено несколько примеров: LINEOUT(,'Display this') /* Записывает строку в выходной */ /* поток,принимаемый по умолчанию */ /* (обычно, это дисплей); возвра- */ /* щает 0, если действие успешно. */

    myfile = 'ANYFILE.TXT' LINEOUT(myfile,'A new line') /* Открывает файл ANYFILE.TXT и */ /* добавляет строку в конец файла.*/ /* Если файл уже открыт, строка */ /* записывается в текущую позицию */ /* записи. Возвращает 0, если */ /* действие прошло успешно. */

    LINEOUT(myfile,'A new start',1)/* Открывает файл (если он еще не */ /* открыт); записывает новую стро-*/ /* ку на место первой. Возвращает */ /* 0, если действие прошло успешно*/

    LINEOUT(myfile,,1) /* Открывает файл (если он еще не открыт); */ /* запись не выполняется. Позиция записи */ /* устанавливается на первый символ. */

    LINEOUT(myfile) /* Закрывает файл ANYFILE.TXT */

    Функцию LINEOUT полезно вызывать как подпрограмму. В этом случае результат ее выполнения доступен в качестве значения переменной RESULT. Например: Call LINEOUT 'A:rexx.bat','Shell',1 Call LINEOUT ,'Hello'

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


    LINES

    LINES
    Функция LINES в качестве результата возвращает 1, если между текущей позицией чтения и концом вводного потока символов с указанным именем находятся некоторые данные, и 0, если данные в этом промежутке отсутствуют. В действительности функция LINES дает информацию о том, будет ли успешным чтение из вводного потока, выполняемое функциями CHARIN или LINEIN.
    Форма имени зависит от среды применения. Если имя опущено, то проверяется наличие или отсутствие данных во вводном потоке, принимаемом по умолчанию (STDIN:). Для устройств OS/2 функция LINES в качестве результата всегда возвращает значение 1.
    Ниже приведено несколько примеров: LINES(myfile) -> 0 /* в конце файла */
    LINES() -> 1 /* данные, оставшиеся */ /* во вводном потоке STDIN:, */ /* принимаемом по умолчанию */
    LINES("COM1:") -> 1 /* Для устройств OS/2 */ /* всегда возвращается '1' */
    Прим.Функция CHARS в качестве результата возвращает количество символов, оставшихся в устойчивом потоке, либо результат, свидетельствующий о наличии либо отсутствии данных в переменном потоке.



    MAX

    MAX
    Функция MAX в качестве результата возвращает наибольшее число из указанного списка чисел, форматированное в соответствии с текущим назначением NUMERIC DIGITS. В списке можно указать до 20 чисел, а также использовать вложенное обращение к функции MAX, если нужно указать большее количество аргументов.
    Ниже приведено несколько примеров: MAX(12,6,7,9) -> 12 MAX(17.3,19,17.03) -> 19 MAX(-7,-3,-4.3) -> -3 MAX(1,2,3,4,5,6,7,8,9,MAX(10,11,12,13)) -> 13


    MIN

    MIN
    Функция MIN в качестве результата возвращает наименьшее число из указанного списка чисел, форматированное в соответствии с текущим назначением NUMERIC DIGITS. В списке можно указать до 20 чисел, а также использовать вложенное обращение к функции MIN, если нужно указать большее количество аргументов.
    Ниже приведено несколько примеров: MIN(12,6,7,9) -> 6 MIN(17.3,19,17.03) -> 17.03 MIN(-7,-3,-4.3) -> -7


    OVERLAY

    OVERLAY
    Функция OVERLAY в качестве результата возвращает указанную целевую строку, которая, начиная с n-ного символа, перекрыта новой строкой, дополненной символами-заполнителями или усеченной до требуемой длины. Если значение длины указано, то оно должно быть положительным числом или нулем. Если значение n больше длины целевой строки, то символы-заполнители добавляются перед новой строкой. По умолчанию символом-заполнителем является пробел; значение n, принимаемое по умолчанию, равно 1. Если значение n указано, то оно должно быть целым положительным числом.
    Ниже приведено несколько примеров: OVERLAY(' ','abcdef',3) -> 'ab def' OVERLAY('.','abcdef',3,2) -> 'ab. ef' OVERLAY('qq','abcd') -> 'qqcd' OVERLAY('qq','abcd',4) -> 'abcqq' OVERLAY('123','abc',5,6,'+') -> 'abc+123+++'





    POS

    POS
    Функция POS в качестве результата возвращает номер позиции одной строки, строки-поиска, в другой, целевой-строке. (Смотрите также описание функции LASTPOS.) Если строка-поиска не найдена в указанной строке, то в качестве результата возвращается 0. По умолчанию поиск начинается с первого символа целевой-строки (т.е. значение начала равно 1). Вы можете отменить просмотр, выполняемый по умолчанию, указав значение для режима Содержание (которое должно быть целым положительным числом) в качестве точки, с которой начнется просмотр строки.
    Ниже приведено несколько примеров: POS('day','Saturday') -> 6 POS('x','abc def ghi') -> 0 POS(' ','abc def ghi') -> 4 POS(' ','abc def ghi',5) -> 8


    QUEUED

    QUEUED
    Функция QUEUED в качестве результата возвращает количество строк, оставшихся в активной очереди данных REXX на момент вызова функции.
    Ниже приведен пример: QUEUED() -> 5 /* Возможно */


    RANDOM

    RANDOM
    Функция RANDOM в качестве результата возвращает псевдослучайное целое неотрицательное число в диапазоне от min до max включительно. Если указан только один аргумент, то диапазон считается от 0 до указанного числа. Значения по умолчанию для аргументов min и max - 0 и 999 соответственно. Для случайного числа в качестве третьего аргумента может быть указано специальное начальное-число (которое должно быть целым числом), если нужно получать повторяемые результаты.
    Величина диапазона (т.е. max - min) не должна превышать 100000.
    Ниже приведено несколько примеров: RANDOM() -> 305 RANDOM(5,8) -> 7 RANDOM(,,1983) -> 123 /* воспроизводимо */ RANDOM(2) -> 0
    Замечания:
  • Чтобы получить предсказуемую последовательность псевдослучайных чисел, используйте функцию RANDOM несколько раз, но при этом указание начального-числа требуется только при первом использовании. Например, чтобы смоделировать 40 бросков шестигранной игральной кости, можно использовать следующий фрагмент процедуры: sequence = RANDOM(1,6,12345) /* любое число может быть исполь- */ /* зовано в качестве начального */ do 39 sequence = sequence RANDOM(1,6) end say sequence
    Числа генерируются математически, используя начальное-число, так что до определенной степени их появление можно назвать случайным. Повторное выполнение программы приведет к генерации точно такой же последовательности; использование другого значения для начального-числа почти наверняка повлечет за собой генерацию другой последовательности псевдослучайных чисел.
  • Генератор случайных чисел является глобальным для всей программы; текущее назначение начального числа не сохраняется в процессе обращений к внутренним программам.
  • Генератор случайных чисел, используемый в действительности, может иметь отличия в различных средах применения.


    REVERSE

    REVERSE
    Функция REVERSE в качестве результата возвращает строку, в которой все символы записаны с точностью до наоборот.
    Ниже приведено несколько примеров: REVERSE('ABc.') -> '.cBA' REVERSE('XYZ ') -> ' ZYX'


    RIGHT

    RIGHT
    Функция RIGHT в качестве результата возвращает строку указанной длины, содержащую крайние правые символы в количестве, определенном длиной, выбранные из указанной строки. Возвращенная результирующая строка при необходимости дополняется слева символами-заполнителями (или усекается). По умолчанию символом-заполнителем является пробел. Значение длины должно быть неотрицательным.
    Ниже приведено несколько примеров: RIGHT('abc d',8) -> ' abc d' RIGHT('abc def',5) -> 'c def' RIGHT('12',5,'0') -> '00012'





    SETLOCAL

    SETLOCAL
    Функция SETLOCAL сохраняет текущее рабочее устройство и каталог, а также текущие значения переменных среды OS/2, которые являются локальными для процесса, выполняющегося в настоящий момент.
    Например, функцию SETLOCAL можно использовать для сохранения назначений текущей среды перед изменением выбранных назначений с помощью функции VALUE. Для восстановления устройства, каталога и среды используйте функцию ENDLOCAL.
    Функция SETLOCAL в качестве результата возвращает значение 1, если исходные устройство, каталог и среда успешно сохранены, и значение 0, если сохранение прошло неуспешно. Если в процедуре за функцией SETLOCAL не следует ENDLOCAL, то на выходе из процедуры восстанавливается исходная среда, сохраненная с помощью функции SETLOCAL.
    Ниже приведен пример: /* текущий путь: 'C:\PROJ\FILES' */ n = SETLOCAL() /* сохраняет все назначения среды */
    /* Использование функции VALUE для изменения переменной PATH */ p = VALUE('Path','C:\PROC\PROGRAMS'.'OS2ENVIRONMENT')
    /* Могут выполняться программы из каталога C:\PROC\PROGRAMS */
    n = ENDLOCAL() /* восстанавливает исходную среду (включая */ /* измененную переменную PATH, которая опять */ /* имеет значение 'C:\PROJ\FILES') */
    Прим. В отличие от своих двойников в языке команд OS/2 (операторы Setlocal и Endlocal), функции языка REXX SETLOCAL и ENDLOCAL могут быть вложенными.



    SIGN

    SIGN
    Функция SIGN в качестве результата возвращает число, которое определяет знак указанного числа. Значение числа сначала округляется в соответствии со стандартными правилами языка REXX так, как если бы была выполнена операция число+0. Если указанное число меньше нуля, то в качестве результата возвращается значение -1; если оно равно нулю, то возвращается 0, а если больше нуля, то возвращается 1.
    Ниже приведено несколько примеров: SIGN('12.3') -> 1 SIGN(' -0.307') -> -1 SIGN(0.0) -> 0


    SOURCELINE

    SOURCELINE
    Функция SOURCELINE в качестве результата возвращает порядковый номер последней строки исходного файла (если значение n не указано) или содержимое n-ной строки исходного файла (если значение n определено).
    Если значение n указано, то оно должно быть целым положительным числом и не должно превышать номер последней строки исходного файла.
    Ниже приведено несколько примеров: SOURCELINE() -> 10 SOURCELINE(1) -> '/* Это программа из 10 строк */'


    SPACE

    SPACE
    Функция SPACE разделяет отдельно стоящие слова в указанной строке с помощью n символов-заполнителей, вставляемых между словами. Значение n должно быть неотрицательным. Если оно равно нулю, то все пробелы удаляются. Обрамляющие пробелы также удаляются. По умолчанию значение n равно 1, и символом-заполнителем, принимаемым по умолчанию, является пробел.
    Ниже приведено несколько примеров: SPACE('abc def ') -> 'abc def' SPACE(' abc def',3) -> 'abc def' SPACE('abc def ',1) -> 'abc def' SPACE('abc def ',0) -> 'abcdef' SPACE('abc def ',2,'+') -> 'abc++def'


    STREAM

    STREAM
    Функция STREAM в качестве результата возвращает описание потока символов с указанным именем, либо результат выполнения над потоком некоторой операции. Эта функция используется для получения информации о состоянии вводного или выводного потока, либо для выполнения некоторых специфических операций над потоком.
    Первый аргумент имя определяет поток, к которому нужно получить доступ. В качестве второго аргумента может быть указана одна из следующих строк (при этом значащей будет только первая заглавная буква), описывающая действие, которое нужно выполнить:
    Command операция (указываемая в качестве третьего аргумента команда-потока), которая должна быть применена к выбранному вводному или выводному потоку. Возвращенная результирующая строка зависит от выполненной команды и может быть пустой строкой.
    Description Возвращает текущее состояние указанного потока. Функция STREAM с данным режимом идентична операции State, за исключением того, что после возвращенной строки следует двоеточие и дополнительная информация о состояниях ERROR или NOTREADY, если она доступна.
    State Возвращает строку, которая описывает текущее состояние указанного потока. Этот режим принимается по умолчанию.

    Функция STREAM, используемая с режимом State, возвращает одну из следующих строк:
    'ERROR' Над потоком была произведена операция, которая привела к возникновению ошибки (возможно, в процессе ввода, вывода или выполнения самой функции STREAM). Дополнительную информацию об ошибке можно получить с помощью функции STREAM с запросом на описание, зависящее от среды применения.
    'NOTREADY' Поток находится в состоянии, при котором любая попытка выполнить стандартную операцию ввода-вывода приводит к формированию условия NOTREADY. Например, простой вводной поток может иметь определенную длину; попытка чтения из этого потока (с помощью встроенных функций CHARIN или LINEIN) сверх указанной длины может сделать поток недоступным до тех пор, пока он не будет закрыт (с помощью функции LINEIN(имя), например), а затем открыт повторно.
    'READY' Поток находится в состоянии, при котором допустима любая стандартная операция ввода-вывода. Это обычное состояние для потока, хотя при этом не гарантируется, что любая конкретная операция будет выполнена успешно.
    'UNKNOWN' Состояние потока неизвестно. В среде OS/2 и ее прикладных программах это обычно означает, что поток закрыт (или еще не открывался). Однако данный ответ может означать в других средах, что состояние потока невозможно определить.
    <
    Прим. Состояние ( и выбранный режим) вводного или выводного потока является глoбальным для программы REXX, в которой оно не сохраняется и не восстанавливается при обращении к функциям и подпрограммам (включая и те, которые вызваны для отслеживания событий по CALL ON).
    Команды потока

    Обычно используются следующие команды потока:
  • Открыть поток для чтения или записи
  • Закрыть поток после выполнения операции
  • Установить позицию чтения или записи внутри устойчивого потока (например, файла)
  • Получить информацию о потоке (его существовании, размере и дате последнего изменения).

    Если Вы указали режим С (команда), то должен использоваться и аргумент команда-потока. Синтаксис при этом будет следующим:

    STREAM

    Функция STREAM, используемая в такой форме, сама возвращает строку, соответствующую указанной команде-потока, если эта команда завершилась успешно. Если же команда завершилась неуспешно, то функция STREAM возвращает строку с сообщением об ошибке в такой же форме, как и при выборе режима D (Описание).

    Командные строки - Аргумент команда-потока может быть любым выражением, которое в процессе вычислений приводится языком REXX к одной из следующих командных строк:
    'OPEN' Открывает поименованный поток. По умолчанию команда OPEN открывает поток как для чтения, так и для записи данных. Для того, чтобы указать конкретную операцию, которую нужно выполнить над потоком с указанным именем, добавьте в командную строку слово READ (если требуется только чтение из потока) или WRITE (если требуется только запись в поток).

    Функция STREAM сама возвращает строку 'READY', если указанный поименованный поток успешно открыт, или соответствующее сообщение об ошибке в случае неуспешного открытия.

    Примеры: stream(strout,'c','open') stream(strout,'c','open write') stream(strinp,'c','open read')
    'CLOSE' Закрывает поименованный поток. Функция STREAM сама возвращает строку 'READY', если указанный поименованный поток успешно закрыт, или соответствующее сообщение об ошибке в противном случае.


    Если была сделана попытка закрыть неоткрытый файл, то функция STREAM() возвратит пустую строку ("").

    Пример: stream('STRM.TXT','c','close')
    'SEEK' смещение Устанавливает внутри устойчивого потока позицию чтения или записи в соответствии с указанным числом (смещение).

    Прим. В операционной системе OS/2 позиция чтения и записи одна и та же. Чтобы использовать данную команду, откройте сначала поименованный поток с помощью команды потока 'OPEN', описанной выше.
    Перед числом, определяющим смещение, должен быть указан один из следующих символов:
    = Явно указывает смещение от начала потока. Это значение принимается по умолчанию, если перед смещением префикс не указан вообще.
    < Указывает смещение от конца потока.
    + Указывает смещение, отсчитываемое в направлении конца потока от текущей позиции чтения или записи.
    - Указывает смещение, отсчитываемое в направлении начала потока от текущей позиции чтения или записи.
    Функция STREAM сама возвращает новую позицию в потоке, если требуемая позиция чтения или записи успешно определена; в противном случае на экран выводится сообщение об ошибке.

    Примеры: stream(name,'c','seek =2') stream(name,'c','seek +15') stream(name,'c','seek -7') fromend = 125 stream(name,'c','seek <'fromend)
    Используемая с командами потока, описанными ниже, функция STREAM возвращает специальную информацию о потоке. stream('..\file.txt','c','query datetime')
    'QUERY EXISTS' Возвращает полную спецификацию пути поименованного потока, если он существует, и пустую строку в противном случае. stream('..\file.txt','c','query exists')
    'QUERY SIZE' Возвращает размер устойчивого потока в байтах. stream('..\file.txt','c','query size')
    'QUERY DATETIME' Возвращает отметку даты и времени указанного потока.


    STRIP

    STRIP
    Функция STRIP удаляет начальные и конечные символы из указанной строки в зависимости от режима, который Вы определили. Действительными режимами (при указании которых значащей будет только заглавная буква, остальные игнорируются) являются следующие:
    Both Удаляет как начальные, так и конечные символы из указанной строки. Этот режим принимается по умолчанию.
    Leading Удаляет начальные символы из указанной строки.
    Trailing Удаляет конечные символы из указанной строки.

    Третий аргумент символ определяет конкретный символ, который должен быть удален. Значением по умолчанию является пробел. В качестве значения аргумента символ может выступать любой одиночный символ.
    Ниже приведено несколько примеров: STRIP(' ab c ') -> 'ab c' STRIP(' ab c ','L') -> 'ab c ' STRIP(' ab c ','t') -> ' ab c' STRIP('12.7000',,0) -> '12.7' STRIP('0012.700',,0) -> '12.7'


    SUBSTR

    SUBSTR
    Функция SUBSTR в качестве результата возвращает подстроку указанной строки, которая начинается с n-ного символа, имеет требуемую длину и дополнена при необходимости символами-заполнителями. Значение n должно быть целым положительным числом.
    Если значение длины опущено, то в качестве результата возвращается остаток указанной строки. По умолчанию символом-заполнителем является пробел.
    Ниже приведено несколько примеров: SUBSTR('abc',2) -> 'bc' SUBSTR('abc',2,4) -> 'bc ' SUBSTR('abc',2,6,'.') -> 'bc....'
    Прим.В некоторых ситуациях для выбора подстрок более удобны позиционные(числовые) схемы разбора шаблонов, особенно в случаях, когда из одной строки требуется извлечь несколько подстрок.



    SUBWORD

    SUBWORD
    Функция SUBWORD в качестве результата возвращает подстроку указанной строки, которая начинается с n-ного слова и состоит из отдельно стоящих слов в количестве, определяемом значением длины. Значение n должно быть целым положительным числом. Если значение длины опущено, то по умолчанию оно принимается равным количеству оставшихся слов в строке. Возвращенная строка никогда не содержит начальных или конечных пробелов, но включает все пробелы, расположенные между выбранными словами.
    Ниже приведено несколько примеров: SUBWORD('Now is the time',2,2) -> 'is the' SUBWORD('Now is the time',3) -> 'the time' SUBWORD('Now is the time',5) -> ''


    SYMBOL

    SYMBOL
    Функция SYMBOL в качестве результата возвращает состояние символа с указанным именем. Если имя не является действительным символом языка REXX, то в качестве результата возвращается значение BAD. Функция SYMBOL возвращает значение VAR, если указанное имя является именем переменной (т.е. символом, которому присвоено некоторое значение). В противном случае функция SYMBOL возвращает значение LIT, свидетельствующее о том, что указанный символ либо является константой, либо символом, которому еще не присвоено никакое значение (т.е. литералом).
    Что касается символов, используемых в выражениях REXX, то строчные буквы указанного имени переводятся в прописные и по возможности выполняются подстановки для составных имен.
    Прим. Чтобы предотвратить подстановку значений перед передачей символа в функцию, в качестве имени нужно указывать текстовую строку (или выведенную из выражения).

    Ниже приведено несколько примеров: /* предшествовало: Drop A.3; J=3 */ SYMBOL('J') -> 'VAR' SYMBOL(J) -> 'LIT' /* проверяет "3" */ SYMBOL('a.j') -> 'LIT' /* проверяет "A.3" */ SYMBOL(2) -> 'LIT' /* константа */ SYMBOL('*') -> 'BAD' /* недействительный символ */





    TIME

    TIME
    Функция TIME по умолчанию в качестве результата возвращает текущее время в 24-часовом формате "чч:мм:сс" (часы, минуты, секунды); например: 04:41:37
    Для получения других форматов вывода времени или для получения доступа к счетчику прошедшего времени Вы можете использовать следующие режимы (при указании которых значащими являются только заглавные буквы):
    Civil Возвращает чч:ммxx, время в общепринятом формате, где чч может принимать значения от 1 до 12, а мм - от 00 до 59. Непосредственно за минутами следуют буквы "am" или "pm", чтобы отличить утреннее время (с полуночи 12:00am до 11:59am) от полуденного и послеполуденного времени (с полудня 12:00pm до 11:59pm). При отображении часа начальный ноль не добавляется. Для согласованности с прочими результатами функции TIME поле, отведенное для минут, содержит текущую минуту (а не ближайшую).
    Elapsed Возвращает ссссссссс.тт0000, количество секунд с сотыми долями секунды, прошедших с момента, когда счетчик прошедшего времени был запущен или сброшен (см. ниже). Возвращенное число не содержит начальных нулей, но всегда имеет четыре конечных нуля в десятичной части. Назначение NUMERIC DIGITS не влияет на формат выводимого по данному режиму результата.
    Hours Возвращает количество часов, прошедших с полуночи, в формате: чч (без начальных нулей).
    Long Возвращает время в формате чч:мм:сс.тт0000 (где тт представляет собой дробную часть секунд, определяемую в сотых долях секунды).
    Minutes Возвращает количество минут, прошедших с полуночи, в формате: мммм (без начальных нулей).
    Normal Возвращает время в формате, принятом по умолчанию - чч:мм:сс, как описано выше.
    Reset Возвращает ссссссссс.тт0000, число секунд с сотыми долями секунды, прошедших с момента, когда счетчик прошедшего времени был запущен или сброшен (см. ниже)? а также сбрасывает этот счетчик в ноль. Возвращенное число не содержит начальных нулей, но всегда имеет четыре конечных нуля в десятичной части.
    Seconds Возвращает количество секунд, прошедших с полуночи, в формате: ссссс (без начальных нулей).
    <
    Ниже приведено несколько примеров: TIME('L') -> '16:54:22.120000' /* Возможно */ TIME() -> '16:54:22' TIME('H') -> '16' TIME('M') -> '1014' /* 54 + 60*16 */ TIME('S') -> '60862' /* 22 + 60*(54+60*16) */ TIME('N') -> '16:54:22' TIME('C') -> '4:54pm'

    Счетчик прошедшего времени

    Счетчик прошедшего времени можно использовать для измерения интервалов реального времени. Часы запускаются при первом обращении к счетчику прошедшего времени. В качестве результата выполнения функций TIME('E') и TIME('R') возвращается значение 0.

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

    Ниже приведен пример использования счетчика прошедшего времени: time('E') -> 0 /* При первом обращении */ /* здесь пауза в одну секунду */ time('E') -> 1.020000 /* или около того */ /* здесь пауза в одну секунду */ time('R') -> 2.030000 /* или около того */ /* здесь пауза в одну секунду */ time('R') -> 1.050000 /* или около того */

    Прим. По вопросу соответствия времен внутри одного выражения обращайтесь к описанию функции DATE. Счетчик прошедшего времени синхронизирован для других обращений к функциям TIME и DATE, поэтому при неоднократных обращениях к данному счетчику всегда возвращается один и тот же результат. По той же причине интервал между обычными результатами выполнения функций TIME и DATE может быть точно вычислен с помощью счетчика прошедшего времени.
    Максимально допустимое значение: Если количество цифр в числе, определяющем количество прошедших секунд, превысит 9 (что соответствует 31.6 годам), то произойдет ошибка.



    TRANSLATE

    TRANSLATE
    Функция TRANSLATE переводит символы указанной строки в другие символы, либо переупорядочивает символы в строке. При отсутствии таблицы перекодировки буквенные символы указанной строки просто переводятся из строчных в прописные (например, строчные a-z переводятся в прописные A-Z). Выводной таблицей является таблица1, а вводной таблицей перекодировки является таблица2 (по умолчанию принимается XRANGE('00'x,'FF'x)). По умолчанию в качестве выводной таблицы принимается пустая строка; выводная таблица при необходимости дополняется символами-заполнителями или усекается. По умолчанию символом-заполнителем является пробел. Таблицы могут быть любой длины; в случае дублирования символов во вводной таблице значащим будет первое появление символа.
    Ниже приведено несколько примеров: TRANSLATE('abcdef') -> 'ABCDEF' TRANSLATE('abbc','&','b') -> 'a&&c' TRANSLATE('abcdef','12','ec') -> 'ab2d1f' TRANSLATE('abcdef','12','abcd','.') -> '12..ef' TRANSLATE('4123','abcd','1234') -> 'dabc'
    Прим. В последнем примере показано, как использовать функцию TRANSLATE для переупорядочения символов в строке. В примере последний символ любой четырехсимвольной строки, определенной в качестве второго аргумента, перемещается в начало строки.



    TRUNC

    TRUNC
    Функция TRUNC в качестве результата возвращает целую часть указанного числа и n десятичных цифр. По умолчанию значение n равно нулю, и функция TRUNC в этом случае возвращает только целую часть указанного числа. Если же значение n указано, то оно должно быть целым неотрицательным числом. Указанное число сначала округляется в соответствии со стандартными правилами языка REXX, т.е. как если бы была выполнена операция число+0. Затем число усекается до n десятичных цифр (или при необходимости добавляются конечные нули, чтобы довести результирующее число до требуемой длины). Результат никогда не представляется в экспоненциальной форме.
    Ниже приведено несколько примеров: TRUNC(12.3) -> 12 TRUNC(127.09782,3) -> 127.097 TRUNC(127.1,3) -> 127.100 TRUNC(127,2) -> 127.00
    Прим. При необходимости число округляется в соответствии с текущим назначением NUMERIC DIGITS до того, как оно будет передано на обработку функции TRUNC.



    VALUE

    VALUE
    Функция VALUE в качестве результата возвращает значение символа с указанным именем и, по требованию, присваивает ему новое значение. По умолчанию функция VALUE обращается к текущей среде переменных REXX, но могут быть выбраны и другие, внешние, коллекции переменных. Если Вы используете функцию VALUE для получения информации о переменных REXX, то значение имени должно быть действительным символом языка REXX. (Вы можете убедиться в этом, используя функцию SYMBOL). Строчные буквы указанного имени переводятся в прописные. Если имя является составным, то REXX подставляет значения символов для получения производного имени символа.
    Если Вы указали аргумент новое-значение, то указанной поименованной переменной присваивается это новое значение. Данное действие не влияет на возвращенный результат; т.е. функция возвращает значение указанного имени таким, каким оно было до выполнения новой операции присваивания.
    Ниже приведено несколько примеров: /* После: Drop A3; A33=7; K=3; fred='K'; list.5='Hi' */ VALUE('a'k) -> 'A3' VALUE('a'kk) -> '7' VALUE('fred') -> 'K' /* ищет FRED */ VALUE(fred) -> '3' /* ищет K */ VALUE(fred,5) -> '3' /* и устанавливает K=5 */ VALUE(fred) -> '5' VALUE('LIST.'k) -> 'Hi' /* ищет LIST.5 */
    Чтобы использовать функцию VALUE для манипуляции переменными среды OS/2, в качестве значения переключателя должна быть указана строка 'OS2ENVIRONMENT' или выражение, результатом вычисления которого будет эта же строка. В этом случае переменная с указанным именем не должна быть действительным символом языка REXX. Когда функция VALUE используется для установки или изменения значения переменной среды, новое значение сохраняется после завершения выполнения процедуры REXX.
    Ниже приведено несколько примеров: /* Дано: внешняя переменная FRED имеет значение 4 */ share = 'OS2ENVIRONMENT' say VALUE('fred',7,share) /* выводит '4' и присваивает */ /* переменной FRED значение 7 */
    say VALUE('fred',,share) /* выводит '7' */
    /* После выполнения процедуры FRED снова имеет значение 4 */ /* Получение доступа и изменение переменных среды OS/2 */ env = 'OS2ENVIRONMENT' new = 'C:\LIST\PROD;' say value('prompt',,env) /* выводит '$i[p]' (возможно) */ say value('path',new,env) /* выводит 'C:\EDIT\DOCS;' (возможно) */ /* и устанавливает PATH = 'C:LIST\PROD' */ say value('path',,env) /* выводит 'C:LIST\PROD' */ /* По завершении процедуры PATH = 'C:\LIST\PROD' */

    Примечания:

  • Если функция VALUE обращается к непроинициализированной переменной REXX, то в качестве результата всегда возвращается значение переменной, принимаемое по умолчанию; условие NOVALUE не формируется. Условие NOVALUE никогда не формируется при ссылке на внешнюю коллекцию переменных.

  • Функция VALUE используется, когда переменная содержит имя другой переменной, или в случаях, когда имя переменной строится динамически. Если в качестве значения имени указана отдельная текстовая строка, то символ является константой и поэтому обращение к функции можно, как правило, заменить этой строкой (т.е. символами, расположенными в кавычках). (Например, fred=VALUE('k'); идентично присваиванию fred=k;, если только не было отслежено условие NOVALUE).

  • Для осуществления временных изменений переменных среды используйте функции SETLOCAL и ENDLOCAL.



    VERIFY

    VERIFY
    Функция VERIFY в качестве результата возвращает некоторое число, указывающее, состоит ли заданная строка только лишь из символов справочника. VERIFY возвращает позицию первого символа в строке, который не был найден в справочнике. Если найдены все символы в справочнике, то в качестве результата возвращается значение 0.
    Третий аргумент режим может быть любым выражением, результатом вычисления которого является строка, начинающаяся с букв n или M (что соответствует режимам nomatch (по умолчанию) или Match соответственно). Значащей является только первая буква режима, которая может быть как строчной, так и прописной. Если указан режим nomatch, то в качестве результата возвращается позиция первого символа в строке, который не найден в справочнике. Если же все символы строки найдены в справочнике, то в качестве результата возвращается значение 0. Если указан режим Match, то в качестве результата возвращается позиция первого символа в строке, который найден в справочнике, или 0, если не найден ни один из символов.
    По умолчанию значением аргумента Содержание является 1, таким образом, просмотр начинается с первого символа строки. Вы можете отменить значение по умолчанию, указав конкретную точку начала просмотра; указываемое значение должно быть целым положительным числом.
    Функция VERIFY в качестве результата всегда возвращает 0, если указанная строка пуста или если значение начала больше, чем значение LENGTH(строка). Если справочник пустой, то функция VERIFY в качестве результата возвращает значение 0 (если указан режим Match) и 1 - в противном случае.
    Ниже приведено несколько примеров: VERIFY('123','1234567890') -> 0 VERIFY('1Z3','1234567890') -> 2 VERIFY('AB4T','1234567890') -> 1 VERIFY('AB4T','1234567890','M') -> 3 VERIFY('AB4T','1234567890','N') -> 1 VERIFY('1P3Q4','1234567890',,3) -> 4 VERIFY('AB3CD5','1234567890','M',4) -> 6





    WORD

    WORD
    Функция WORD в качестве результата возвращает n-ное отдельно стоящее слово в указанной строке. Значение n должно быть целым положительным числом. Если количество слов в строке меньше указанного значения n, то в качестве результата возвращается пустая строка. Данная функция эквивалентна следующей функции: SUBWORD(строка,n,1).
    Ниже приведено несколько примеров: WORD('Now is the time',3) -> 'the' WORD('Now is the time',5) -> ''


    WORDINDEX

    WORDINDEX
    Функция WORDINDEX в качестве результата возвращает позицию первого символа n-ного отдельно стоящего слова в указанной строке. Значение n должно быть целым положительным числом. Если количество слов в строке меньше указанного значения n, то в качестве результата возвращается число 0.
    Ниже приведено несколько примеров: WORDINDEX('Now is the time',3) -> 8 WORDINDEX('Now is the time',6) -> 0


    WORDLENGTH

    WORDLENGTH
    Функция WORDLENGTH в качестве результата возвращает длину n-ного отдельно стоящего слова в указанной строке. Значение n должно быть целым положительным числом. Если количество слов в строке меньше указанного значения n, то в качестве результата возвращается число 0.
    Ниже приведено несколько примеров: WORDLENGTH('Now is the time',2) -> 2 WORDLENGTH('Now comes the time',2) -> 5 WORDLENGTH('Now is the time',6) -> 0


    WORDPOS

    WORDPOS
    Функция WORDPOS просматривает указанную строку на предмет поиска первого появления последовательности отдельно стоящих слов, определяемых аргументом фраза, и в качестве результата возвращает порядковый номер первого слова фразы в просматриваемой строке. Несколько пробелов между словами как во фразе, так и в строке при сравнении обрабатываются как один пробел, но остальные слова должны в точности совпадать.
    По умолчанию просмотр начинается с первого слова указанной строки. Вы можете отменить значение по умолчанию, указав значение аргумента Содержание (которое должно быть положительным); это значение будет определять порядковый номер слова, с которого следует начать просмотр строки.
    Ниже приведено несколько примеров: WORDPOS('the','now is the time') -> 3 WORDPOS('The','now is the time') -> 0 WORDPOS('is the','now is the time') -> 2 WORDPOS('is the','now is the time') -> 2 WORDPOS('is time ','now is the time') -> 0 WORDPOS('be','To be or not to be') -> 2 WORDPOS('be','To be or not to be',3) -> 6


    WORDS

    WORDS
    Функция WORDS в качестве результата возвращает количество отдельно стоящих слов в указанной строке.
    Ниже приведено несколько примеров: WORDS('Now is the time') -> 4 WORDS(' ') -> 0


    X2B (Шестнадцатеричное в двоичное)

    X2B (Шестнадцатеричное в двоичное)
    Функция X2B преобразует шестнадцатеричную-строку (т.е. строку, состоящую из шестнадцатеричных символов) в эквивалентную строку двоичных символов. Шестнадцатеричная-строка может иметь любую длину; каждый шестнадцатеричный символ преобразуется в строку из четырех двоичных цифр. Возвращенная результирующая строка не содержит ни одного пробела и имеет длину, в четыре раза превышающую длину исходной строки.
    При желании для читабельности можно добавить пробелы (только на границе байта, а не начальные и конечные); в процессе преобразования они игнорируются.
    Если в качестве шестнадцатеричной-строки указана пустая строка, то функция X2B возвращает значение 0.
    Ниже приведено несколько примеров: X2B('C3') == '11000011' X2B('7') == '0111' X2B('1 C1') == '000111000001'
    Вы можете использовать функцию X2B(..) в сочетании с функциями D2X(..) и C2X(..) для преобразования десятичных чисел или символьных строк в двоичную форму.
    Ниже приведено несколько примеров: X2B(C2X('C3'x)) == '11000011' X2B(D2X('129')) == '10000001' X2B(D2X('12')) == '1100'


    X2C (Шестнадцатеричное в символьное)

    X2C (Шестнадцатеричное в символьное)
    Функция X2C преобразует шестнадцатеричную-строку (т.е. строку, состоящую из шестнадцатеричных символов) в эквивалентную символьную строку.
    Шестнадцатеричная-строка может иметь любую длину. При желании для читабельности в шестнадцатеричную-строку можно добавить пробелы (только на границе байта, а не начальные или конечные); в процессе преобразования они игнорируются.
    При необходимости шестнадцатеричная-строка дополняется начальным нулем для получения четного числа шестнадцатеричных цифр.
    Ниже приведено несколько примеров: X2C('4865 6c6c 6f') -> 'Hello' /* ASCII */ X2C('3732 73') -> '72s' /* ASCII */ X2C('F') -> '0F'x


    X2D (Шестнадцатеричное в десятичное)

    X2D (Шестнадцатеричное в десятичное)
    Функция X2D преобразует шестнадцатеричную-строку (т.е. строку, состоящую из шестнадцатеричных символов) в эквивалентную строку, содержащую десятичное число. Если результат не может быть представлен в виде целого числа, то происходит ошибка. Результат не может состоять из большего количества цифр, чем это установлено в текущем назначении NUMERIC DIGITS.
    При желании для читабельности в шестнадцатеричную-строку можно добавить пробелы (только на границе байта, а не начальные или конечные); в процессе преобразования они игнорируются.
    Если в качестве шестнадцатеричной-строки указана пустая строка, то функция X2D возвращает значение 0.
    Если значение n не указано, то шестнадцатеричная-строка обрабатывается как двоичное число без знака.
    Ниже приведено несколько примеров: X2D('0E') -> 14 X2D('81') -> 129 X2D('F81') -> 3969 X2D('FF81') -> 65409 X2D('c6 f0'X) -> 240
    Если значение n указано, то данная последовательность шестнадцатеричных цифр слева дополняется нулями (отметим, что без знакового разряда) или усекается слева до n символов. Результирующая строка, состоящая из n шестнадцатеричных цифр, рассматривается как двоичное число со знаком - положительное, если старший левый бит сброшен, и отрицательное (в форме дополнения до двоичного числа два), если старший левый бит установлен. Если значение n равно нулю, то функция X2D в качестве результата возвращает 0.
    Ниже приведено несколько примеров: X2D('81',2) -> -127 X2D('81',4) -> 129 X2D('F081',4) -> -3967 X2D('F081',3) -> 129 X2D('F081',2) -> -127 X2D('F081',1) -> 1 X2D('0031',0) -> 0


    XRANGE

    XRANGE
    Функция XRANGE в качестве результата возвращает строку всех однобайтных кодов, расположенных между значениями аргументов Содержание и конец, включая начальное и конечное значения. Значением по умолчанию для аргумента Содержание является '00'x, а для аргумента конец- 'FF'x. Если значение аргумента Содержание больше, чем значение аргумента конец, то значения выводятся в направлении от 'FF'x к '00'x. Если значения аргументов Содержание и конец указаны, то они должны представлять собой одиночные символы.
    Ниже приведено несколько примеров: XRANGE('a','f') -> 'abcdef' XRANGE('03'x,'07'x) -> '0304050607'x XRANGE(,'04'x) -> '0001020304'x XRANGE('i','j') -> '898A8B8C8D8E8F9091'x /* EBCDIC */ XRANGE('FE'x,'02'x) -> 'FEFF000102'x XRANGE('i','j') -> 'ij' /* ASCII */





    Функция RXQUEUE

    Функцию RxQueue используйте в процедуре REXX для создания и удаления очередей, а также для назначения и опроса имен этих очередей. Первый параметр определяет функцию, которая должна быть выполнена; имя функции указывайте полностью, строчными или прописными буквами.
    Синтаксис: Функция RXQUEUE
    Параметры:
    Create Создает очередь с именем, определяемым аргументом имя-очереди (если этот аргумент указан); если же имя не указано, то REXX сам определяет имя очереди. В любом случае в качестве результата возвращает имя созданной очереди.
    Delete Удаляет поименованную очередь; в случае успешного удаления возвращает значение 0, в случае ошибки возвращает ненулевой результат; возможные результирующие значения перечислены ниже:
    0 Очередь удалена.
    5 Неправильное имя очереди.
    9 Указанная очередь не существует.
    10 Очередь занята; подождите, пока она не станет активной.
    12 Произошла ошибка при обращении к памяти.
    1000 Ошибка инициализации; проверьте файл OS/2.INI
    Get Возвращает имя очереди, используемой в настоящий момент.
    Set Присваивает текущей очереди имя, указанное в аргументе новое-имя-очереди, и в качестве результата возвращает предыдущее имя данной очереди.

    Пример: Простая очередь в процедуре REXX
    /* */ /* push/pull БЕЗ мультипрограммной поддержки */ /* */ push date() time() /* помещает в очередь дату и время */ do 1000 /* пропускается промежуток времени */ nop /* нет операции */ end /* конец цикла */ pull a b . /* получает информацию из очереди */ say 'Pushed at ' a b ', Pulled at ' date() time() /* выводит время от времени */
    /* */ /* push/pull С мультипрограммной поддержкой */ /* (без восстановления при ошибках и без проверки */ /* неподдерживаемых сред) */ newq = RXQUEUE('Create') /* создает единственную очередь */ oq = RXQUEUE('Set',newq) /* устанавливает новую очередь */ push date() time() /* помещает в очередь дату и время */ do 1000 /* пропускается промежуток времени */ nop /* нет операции */ end /* конец цикла */ pull a b . /* получает информацию из очереди */ say 'Pushed at ' a b ', Pulled at ' date() time() /* сообщает пользователю */ call RXQUEUE 'Delete',newq /* удаляет созданную очередь */ call RXQUEUE 'Set',oq /* восстанавливает имя очереди (не требуется)*/

    Специальные соображения

  • Внешние программы, которые должны взаимодействовать с процедурой REXX с помощью определенных очередей данных, могут использовать сеансовую очередь, очередь, принимаемую по умолчанию, либо получить имя очереди данных с помощью технологии межзадачного взаимодействия. Данная технология может включать передачу параметров, помещение в заранее подготовленную логическую очередь или использовать обычный механизм межзадачного взаимодействия OS/2 (например, каналы, разделенная память или очереди IPC).

  • Поименованные очереди доступны для всей операционной системы; поэтому и имена очередей должны быть уникальными. Если существует очередь с именем os2que и выдана следующая функция: newqueue = RXQUEUE('Create', 'os2que')

    то будет создана новая очередь, и имя для нее выберет REXX. Это новое имя будет возвращено в качестве результата выполнения функции.

  • Любая запущенная внешняя программа наследует в качестве очереди, принимаемой по умолчанию, очередь, используемую в данный момент вызывающей программой.

    Отсоединенные процессы

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

  • Процедуры REXX, которые должны выполняться как отсоединенные процессы, не могут использовать инструкции SAY, PULL и PARSE PULL, требующие ввода с клавиатуры или вывода на экран дисплея. Однако инструкции PULL и PARSE PULL, работающие только с очередью, допустимы для использования в отсоединенных процессах.

    Примечания по мультипрограммированию

    Механизм организации очередей данных в этом случае отличается от стандартного механизма организации очередей API операционной системы OS/2 следующим:

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

    Однако синхронизация запросов ( когда два процесса, имеющие доступ к одной и той же очереди, получают данные из этой очереди в порядке регистрации их запросов) является обязанностью пользователя и не обеспечивается подсистемой. Данный селектор принадлежит вызывающей прикладной программе и должен быть освобожден этой программой с помощью DosFreeSeg.

  • Стандартная очередь IPC операционной системы OS/2 принадлежит конкретному процессу (создается по его запросу). После завершения процесса очередь разрушается. В то же время очереди, созданные с помощью функции RxQueue('Create', имя-очереди) существуют до тех пор, пока не будут ЯВНО удалены. Завершение выполнения программы или процедуры, создавшей личную очередь, не влечет за собой принудительного удаления личной очереди. Любые данные в очереди после завершения процесса создания остаются в ней до тех пор, пока либо данная очередь не будет удалена (с помощью обращения к функции REXX RxQueue('Delete', имя-очереди), либо пока данные не будут прочитаны.

    Очереди данных должны быть явно удалены некоторой процедурой или программой (не обязательно программой, создавшей очередь). Удаление очереди, в которой остались элементы, разрушает эти элементы. Если очередь не удалена, то она будет потеряна и ее невозможно будет восстановить, кроме как при случайной попытке получить доступ к каждой очереди в определенном порядке.

    Интерфейс очередей

    REXX обеспечивает организацию и ведение собственных очередей отдельно от очередей межзадачных взаимодействий OS/2. Очереди, о которых будет идти речь в этом разделе, используются только в процедурах REXX.
    В процедурах работа с очередями REXX осуществляется с помощью следующих инструкций:
    PUSH Помещает строку в начало очереди (LIFO).
    QUEUE Добавляет строку в конец очереди (FIFO).
    PULL Считывает строку из начала очереди. Если очередь пуста, то строка считывается с консоли (STDIN:).

    Чтобы получить информацию о количестве элементов, оставшихся в очереди, используйте функцию QUEUED.
    Доступ к очередям
    REXX поддерживает два типа очередей. Доступ к этим очередям и их обработка осуществляется по именам.
    Сеансовые очереди - Для каждого активного сеанса OS/2 автоматически обеспечивается одна сеансовая очередь. Сеансовая очередь всегда имеет имя SESSION, и REXX создает ее при первом запросе от программы или процедуры на помещение информации в очередь. Все процессы (программы и процедуры) в сеансе могут получить доступ к сеансовой очереди. Однако каждый конкретный процесс может получить доступ к сеансовой очереди, определенной только для того сеанса, в котором он выполняется, и эта сеансовая очередь не является уникальной для любого одиночного процесса, выполняющегося в сеансе.
    Личные очереди - Личные очереди создаются (и удаляются) при выполнении Вашей конкретной программы. Вы можете сами дать имя очереди, либо оставить это на усмотрение языка REXX. Для того, чтобы Ваша программа могла использовать любую очередь, ей должно быть известно имя очереди.


    Использование сравнений

    Процедура TF.CMD использует сравнения и выражения равенства для определения того, являются ли числовые выражения истинными или ложными.
    /* Определение истинности или ложности выражения */ /* 1 - истина; 0 - ложь */ a = 4 b = 2 c = a > b SAY 'Результат' a '>' b 'равен' c c = a < b SAY 'Результат' a '<' b 'равен' c c = a = b SAY 'Результат' a '=' b 'равен' c EXIT
    Протокол работы этой процедуры выглядит следующим образом:
    [C:\]TF Результат 4 > 2 равен 1 Результат 4 < 2 равен 0 Результат 4 = 2 равен 0
    [C:\]

    Логические операторы - Примеры

    В процедуре AND.CMD демонстрируется, как с помощью оператора логического И проверить истинность двух выражений.
    /* Использование оператора логического И (&) */ /* 0 - ложь; 1 - истина */ a = 4 b = 2 c = 5 d = (a ≶ b) & (b ≶ c) SAY 'Результат (a ≶ b) & (b ≶ c) равен' d d = (a ≶ b) & (b < c) SAY 'Результат (a ≶ b) & (b < c) равен' d EXIT
    Протокол работы этой процедуры выглядит следующим образом:
    [C:\]AND Результат (a ≶ b) & (b ≶ c) равен 0 Результат (a ≶ b) & (b < c) равен 1
    [C:\]
    В процедуре OR.CMD демонстрируется, как оператор логического ИЛИ присваивает выражению значение истина, несмотря на то, что оба составляющих значения ложны:
    /* Использование оператора логического ИЛИ (|) */ /* 0 - ложь; 1 - истина */ a = 4 b = 2 c = 5 d = (a ≶ b) | (b ≶ c) SAY 'Результат (a ≶ b) | (b ≶ c) равен' d d = (a ≶ b) | (b < c) SAY 'Результат (a ≶ b) | (b < c) равен' d EXIT
    Протокол работы этой процедуры выглядит следующим образом: [C:\]OR Результат (a ≶ b) | (b ≶ c) равен 1 Результат (a ≶ b) | (b < c) равен 1
    [C:\]

    Пример цикла DO UNTIL

    Процедура DOUNTIL.CMD использует цикл DO UNTIL. Проверка условия на истину или ложь осуществляется в конце цикла: /* Использование цикла DO UNTIL */ SAY 'Введите сумму наличных денег' PULL salary spent = 0 /* Присваивает spent значение 0 */ DO UNTIL spent > salary SAY 'Введите стоимость товара' PULL cost spent = spent + cost END SAY 'Пустые карманы.' EXIT
    Протокол работы этой процедуры выглядит следующим образом: [C:\] DOUNTIL Введите сумму наличных денег 50 Введите стоимость товара 37 Введите стоимость товара 14 Пустые карманы. [C:\]

    Пример цикла DO WHILE

    Процедура DOWHILE.CMD использует цикл DO WHILE. Проверка условия на истину или ложь осуществляется в начале цикла.
    /* Использование цикла DO WHILE */ SAY 'Введите сумму наличных денег' PULL salary spent = 0 DO WHILE spent < salary SAY 'Введите стоимость товара' PULL cost spent = spent + cost END SAY 'Пустые карманы.' EXIT
    Протокол работы этой процедуры выглядит следующим образом:
    [C:\]dowhile Введите сумму наличных денег 100 Введите стоимость товара 57 Введите стоимость товара 24 Введите стоимость товара 33 Пустые карманы. [C:\]

    Примеры арифметических выражений

    В приведенной ниже процедуре MATH.CMD демонстрируется выполнение арифметических действий над переменными:
    /* Выполнение арифметических действий над переменными */ a = 4 b = 2 c = a + b SAY 'Результат 'a '+' b 'равен' c SAY c = a * b SAY 'Результат ' a '*' b 'равен' c SAY c = a - b SAY 'Результат ' a '-' b 'равен' c SAY c = a / b SAY 'Результат 'a '/' b 'равен' c EXIT
    Протокол работы этой процедуры выглядит следующим образом:
    [C:\]MATH Результат 4 + 2 равен 6 Результат 4 * 2 равен 8 Результат 4 - 2 равен 2 Результат 4 / 2 равен 2
    [C:\]

    

        Программирование: Языки - Технологии - Разработка