Перевести страницу

Создание приложений для науки и производства ещё не было таким простым

Операции для управления алгоритмом

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


Те операции, которые принимают параметр типа block, могут вызывать исполняющую систему Ci, которая производит выполнение этого блока. При этом не обязательно передавать им константу типа блок, заключенную в фигурные скобки. Можно также передавать переменные типа block, которым ранее присвоено какое-то значение соответствующего типа. При этом не страшно, если во время “выполнения” такой переменной ее значение будет изменено (выполнена операция clear или ей будет присвоен новый блок). Операция, получившая такую переменную в качестве параметра, на самом деле, получает откомпилированную константу типа блок, на которую ссылалась переменная. Выполнение кода этой константы будет продолжаться до его нормального завершения. И только при следующем вызове выполнения блочной переменной будет использоваться ее новое значение.


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


Далее следует описание операций управления алгоритмом.


if

Формат вызова:

    if <parameter0> <parameter1> [<parameter2>];

ничего не возвращает, число параметров переменное от двух до трех;

первый параметр типа bool, допустим любой операнд, массив не допустим;

второй параметр типа block, допустим любой операнд, массив не допустим;

третий параметр типа block, допустим любой операнд, массив не допустим;

назначение операции: операция условного выполнения (аналог операторов ветвления в традиционных языках), первым параметром передается логическое значение, если оно истинно (равно TRUE), то будет выполнен программный блок, передаваемый вторым параметром, если же указан третий параметр и первым параметром передано значение ложь, то будет выполнен третий параметр. Примеры использования:

    boola;

    ifa

        {putsnothing” };

ничего не напечатает, т.к. после создания переменная a имеет значение FALSE.

    if( 100 > 1 )

        {puts “large”};

напечатает: large

    if( value == 100 )

        {puts “equal”}

        `else` {puts “not equal”};

выполняется так: если value равно 100, то напечатать equal, иначе напечатать not equal.


loop

Формат вызова:

    loop <parameter0> [<parameter1> [<parameter2> [<parameter3> [parameter4]]]];

ничего не возвращает, принимает от 1 до 5 параметров;

первый параметр типа block, допустим любой операнд, массив не допустим;

второй параметр типа беззнаковое целое, допустим любой операнд, массив не допустим;

третий параметр только числовая переменная (типа int, uint или float), массив не допустим;

четвертый параметр должен быть такого же типа, как третий, допустим любой операнд, массив не допустим;

пятый параметр должен быть такого же типа, как третий, допустим любой операнд, массив не допустим;

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


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


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

    loop {puts “message”} 3;

напечатает

    message

    message

    message

или

    floatstyle 2 FALSE;

    float f;

    loop {puts f} 3 f;

напечатает

    0.00

    1.00

    2.00

Или:

    floatstyle 2 FALSE;

    float f;

    loop {puts f} 3 f 0.1;

напечатает

    1.00E-1

    1.10

    2.10

Или:

    floatstyle 2 TRUE;

    float f;

    loop {puts f} 3 f 0.1 -0.03;

напечатает

    0.10

    0.07

    0.04


Цикл loop с числом повторений 0 можно использовать для исключения из выполнения кода, в котором содержатся комментарии. Поскольку вложенные комментарии в Ci недопустимы, то временно отключить код, уже содержащий множество комментариев, с их помощью затруднительно. Для этого можно использовать конструкцию:

    loop{

        ``код, содержащий комментарии

        puts “это не будет напечатано“

    } 0;

Причем, если в дальнейшем потребуется временно включить этот код для выполнения (при проверке алгоритма), то достаточно заменить 0 на 1 (после отладки желательно убрать цикл, чтобы не усложнять читабельность кода).Разумеется, можно использовать вложенные циклы loop{}0;


ВНИМАНИЕ!

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

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


for

Формат вызова:

    for <parameter0> <parameter1> <parameter2> <parameter3> <parameter4>;

ничего не возвращает, принимает один параметр;

первый параметр типа целое, допустима только переменная, массив не допустим;

второй параметр типа целое, допустим любой операнд, массив не допустим;

третий параметр типа целое, допустим любой операнд, массив не допустим;

четвертый параметр типа целое, допустим любой операнд, массив не допустим;

пятый параметр типа block, допустим любой операнд, массив не допустим;

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


Данная реализация цикла предназначена для упрощения переноса алгоритмов, написанных на других языках, она менее мощная и гибкая, чем цикл loop.


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

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


Значение границ, а также приращение внутри блока изменить нельзя (то есть, их изменение не скажется на выполнении цикла).

Если в результате ошибки приращение будет указано таким, что итерация начнет производиться в обратном направлении, и текущее значение итератора перейдет через его начальное значение, программа будет прервана с сообщением об ошибке, например, если написано for i 0 10 -1 {}; то цикл будет прерван после первой итерации, поскольку значение i окажется равно -1, то есть, меньше 0, то же самое произойдет, если в теле цикла значение итератора будет изменено таким образом, что она окажется меньше или больше начального значения (в зависимости от направления счета).


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

Примеры использования:

    for i 0 9 1 {stdout i” “};

будет напечатано 0 1 2 3 4 5 6 7 8 9, после чего цикл прекратится, а переменная i будет иметь значение 10.

    for i 0 -9 -1 {stdout i” “};

будет напечатано 0 -1 -2 -3 -4 -5 -6 -7 -8 -9, после чего цикл прекратится, а переменная i будет иметь значение -10.


continue

Формат вызова:

    continue;

ничего не возвращает, параметров не имеет;

назначение операции: вызывает переход к следующей итерации цикла, при выполнении в любом месте цикла for или loop приведет к немедленному переходу к следующей итерации, цикл for при этом выполнит приращение итератора, если вызывается внутри exec, прекращает выполнение всех вложенных блоков до ближайшей сверху операции call или цикла, если же вызывается внутри call, но не внутри вложенного цикла, то прекращает выполнение функции аналогично return без параметров. Пример использования:

    for i 0 9 1

    {

        if( i == 5 )

        {stdout “five ”; continue};

        stdout i ” “

    };

будет напечатано

    0 1 2 3 4 five 6 7 8 9


continueif

Формат вызова:

    continueif <parameter0>;

ничего не возвращает, принимает один параметр;

параметр типа bool, допустим любой операнд, массив не допустим;

назначение операции: следующая итерация цикла при условии, что значение ее параметра равно TRUE, в остальном аналогична continue. Пример использования:

    fori 0 9 1

    {

        continueif( i == 5 )

        stdouti” “

    };

будет напечатано

    0 1 2 3 4 6 7 8 9


break

Формат вызова:

    break;

ничего не возвращает, параметров не имеет;

назначение операции: немедленное прерывание цикла, при выполнении в любом месте цикла for или loop (либо операции switch) приведет к завершению цикла, итератор цикла for при этом будет иметь текущее значение. Важным отличием от языка C является то, что break прерывает выполнение цикла даже, если он выполняется внутри блока, вызванного операцией exec, если вызывается внутри exec, прекращает выполнение всех вложенных блоков до ближайшей сверху операции call или цикла, если же вызывается внутри call, но не внутри цикла, то прекращает выполнение функции аналогично return без параметров. Примеры использования:

    fori 0 9 1

    {

        if( i == 5 )

            {break};

        stdouti” “

    };

будет напечатано

    0 1 2 3 4


    block b

    {

        stdout “breaking”;

        break

    };

    for i 0 9 1

    {

        exec b;

        stdout “not executed”;

    }

будет напечатано: breaking – необходимо отметить, что переменная i внутри блока b недоступна.

break внутри операции switch прерывает выполнение блока, в котором встречается, но не прерывает цикл, в котором используется switch – это сделано для облегчения переноса алгоритмов, написанных на C.


breakif

Формат вызова:

    breakif <parameter0>;

ничего не возвращает, один параметр;

параметр типа bool, допустим любой операнд, массив не допустим;

назначение операции: прерывание цикла при выполнении условия, полностью аналогична break, но прерывает цикл только если полученное параметром логическое значение равно TRUE. Пример использования:

    fori 0 9 1

    {

        breakif( i == 5 );

        stdouti” “

   };

будет напечатано

    0 1 2 3 4


switch

Формат вызова:

    switch <parameter0> <parameter1> [<parameter2>…<parameter31>];

ничего не возвращает, число параметров переменное, от 2 до максимально допустимого;

первый параметр типа беззнаковое целое, допустим любой операнд, массив не допустим;

второй параметр типа блок, допустим любой операнд, массив не допустим;

остальные параметры такие же, как предыдущий;

назначение операции: вариант условного выполнения, аналогичный switch/case в языке C, первым параметром принимает номер выполняемого блока, после чего выполняет блок, полученный соответствующим параметром (нумерация параметров от 0), если же блоков получено меньше, чем требуемый номер, то не выполняет ничего, наиболее эффективно совместное использование с case (смотри далее). Пример:

    for i 0 3 1

    {

        switch i

            {}

            { stdout “one ” }

            { stdout “two ” }

            { stdout “three ” };

    };

будет напечатано:

    one two three

Выполнение любого блока может быть прервано при помощи вызова операций break или breakif.


case

Формат вызова:

    (case <parameter0> <parameter1> [<parameter2>…<parameter31>])

возвращает беззнаковое целое, число параметров от двух до максимально допустимого;

первый параметр любого типа, допустим любой операнд, массив не допустим;

последующие параметры такие же, как предыдущий;

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

Совместно с switch эта операция более мощная, чем комбинация switch/case в языке C, поскольку в C для switch допустимы только интегральные (целочисленные) типы значений, а для Ci такого ограничения нет, например, его можно использовать для выбора совпадающей строки. Примеры использования:

    puts ( case (concatab” “cd”) “decf” “edfa” “abcd” “afdc” );

напечатает: 2

    switch (floatvar case 0.01, PI, 1e12, (sin val) )

        { puts “case 0” }

        { puts “case 1” }

        { puts “case 2” }

        { puts “case 3” }

        { puts “default no one” };

напечатает слово case и номер параметра операции case, которому равна переменная floatvar, либо default no one, если floatvar не равна ни одному из указанных значений.


exec

Формат вызова:

    exec <parameter0> [<parameter1>…<parameter31>];

ничего не возвращает, принимает число параметров от одного до максимально допустимого;

первый параметр типа блок, допустим любой операнд, массив не допустим;

второй и следующие параметры такие же, как предыдущий;

назначение операции: выполняет последовательно один за другим блоки, полученные параметрами, в сами блоки передать что-либо нельзя, а если в них встретятся вызовы операций par# или par@, то будет считаться, что они имеют отношение к ближайшей сверху операции call, операция exec аналогична операции call без параметров функции, но выполняется значительно быстрее, с ее помощью реализованы операции for и loop. Пример использования:

    block a;

    a = {puts “OOPS! “};

    exec a;

    puts “OOCH! “;

    exec a;

напечатает:

    OOPS! OOCH! OOPS!


call

Формат вызова:

    call <parameter0> [<parameter1>…<parameter31>];

возвращает значение неопределенного заранее типа, тип возврата определяется динамически, число параметров от 1 до максимально допустимого;

первый параметр типа блок, допустим любой операнд, массив не допустим;

второй и следующие параметры любого типа, допустимы любые операнды, массивы не допустимы;

назначение операции: вызов функции с передачей параметров и возможным возвратом значения; первым параметром принимает блок; логично передавать заданную и инициализированную ранее переменную типа блок, поскольку в передаче константы нет смысла, но также можно передавать результат вызова функции, которая может вернуть блок, в блок можно передать параметры, причем компилятор не контролирует их типы, параметры кладутся на внутренний стек и становятся доступны операциям par# и par@, для контроля типов внутри функции необходимо использовать указание типа возврата.


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


ВНИМАНИЕ!

В текущей реализации Ci имеется существенное отличие от других языков при рекурсивных вызовах – внутренние переменные блока в текущей реализации используются повторно – в то время, как в C они отдельные для каждого нового вхождения в рекурсию, то есть:

block b

{

    uint i;

    puts i;

    i ++;

    call b;

}

будет печатать инкрементируемое число, поскольку значение i сохраняется при каждом входе в рекурсию, как если бы переменная i была вне блока b.


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


Операция call может вернуть значение, если в вызываемом ей блоке есть вызов операции setret или return с параметром (подробнее смотри их описания).


Пример использования:

    blockb

    {

        stdout "all " (par# 0)

    };

    call b "ok\n";

напечатает: all ok

    block b

    {

        stdout "b ", (par# 0), ((int par# 1) + 10), (par# 2)

    };

    call b "ok" 12 "\n";

напечатает: b ok22


par#

Формат вызова:

    (par# <parameter0> [<parameter1>])

возвращает значение неопределенного заранее типа, тип возврата определяется динамически, число параметров от одного до двух;

первый параметр типа беззнаковое целое, допустим любой операнд, массив не допустим;

второй параметр любого типа, допустим любой операнд, массив не допустим;

назначение операции: используется внутри функции, вызванной операцией call, для получения одного из параметров функции (нельзя путать параметры функции с параметрами операции), параметры нумеруются от 0.

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

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

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

Примеры использования:

смотри примеры операции call

    block b;

    code b

    {

        uint v1;

        v1 = (par# 1 100);

        puts "value", (par# 0), (v1 + 10)

    };

    call b "ok" 12; ``вызов b с двумя параметрами

    call b “good”; ``вызов b с одним параметром

напечатает:

    value ok 22

    value good 110


par@

Формат вызова:

    par@ <parameter0> <parameter1>;

ничего не возвращает, принимает два параметра;

первый параметр типа беззнаковое целое, допустим любой операнд, массив не допустим;

второй параметр любого типа, допустим любой операнд, массив не допустим;

назначение операции: используется внутри функции, вызванной операцией call, для изменения значения одного из параметров функции (нельзя путать параметры функции с параметрами операции), номер которого задается первым, параметры нумеруются от 0.

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

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

Пример использования:

    block b; uint i; str s;

    code b

    {

        par@ 0 ((int par# 2) + 100);

        par@ 1 “ok”

    };

    call b i s 12;

    puts i s;

напечатает:

    112 ok


npars

Формат вызова:

    (npars);

возвращает беззнаковое целое, параметров не имеет;

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

    block b;

    uint i;

    str s;

    code b

    {

        puts (npars);

    };

    call b i s 12;

напечатает: 3


ispar

Формат вызова:

    (ispar <parameter0>);

возвращает тип bool, принимает один параметр;

параметр типа беззнаковое целое, допустим любой операнд, массив не допустим;

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

    block b;

    uint i;

    str s;

    code b

    {

        puts (ispar 1) (ispar 4)

    };

    call b i s 12;

напечатает:

    TRUE FALSE


isparvar

Формат вызова:

    (isparvar <parameter0>);

возвращает тип bool, принимает один параметр;

параметр типа беззнаковое целое, допустим любой операнд, массив не допустим;

назначение операции: возвращает TRUE, если функции в качестве параметра с номером, указанным в качестве параметра этой операции, передана переменная (или элемент массива), в противном случае, а также, если такого параметра вообще не было передано, возвращает FALSE, это может быть удобно, например если функция может изменить какой-либо параметр, но алгоритм не должен прерваться по ошибке, если этим параметром передана не переменная, тогда можно сначала проверить, передана ли переменная, и если да, то изменять ее значение.

    block b; uint i; str s;

    code b

    {

        puts (isparvar 0) (isparvar 2) (isparvar 4)

    };

    call b i s 12;

напечатает:

    TRUE FALSE FALSE


return

Формат вызова:

    return [<parameter0>];

ничего не возвращает, может вызываться без параметров, или с одним параметром;

если присутствует параметр, то он может быть любого типа, допустим любой операнд, массив не допустим;

назначение операции: прекращает выполнение операции call, в блоке-функции которой вызвана, управление возвращается за вызов завершаемой операции call.

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

    block b;

    uint i;

    code b

    {

        puts 1;

        return;

        puts 2;

    };

    call b

напечатает: 1

    block b; uint i;

    code b

    {

        puts 1;

        return 10;

        puts 2;

    };

    puts (call b)

напечатает:

    1

    1.000000E1

код:

    block b;

    uint i 5;

    code b

    {

        puts 1;

        return;

        puts 2;

    };

    i = (call b);

    putsi;

напечатает:

    1

    0

Использование return позволяет применять call для создания функций, возвращающих значения, и включения их в математические или иные выражения:

    block diagonal ``вычисляет диагональ прямоугольного треугольника по его катетам

    {

        return( sqrt( ((par# 0) ^2 ) + ((par# 1) ^2) ) )

    };

    block i2m ``переводит дюймы в сантиметры

    {

        return( (float par# 0) * 2.54 )

    };

    puts (( call diagonal (call i2m 4) (call i2m 5) ) * 2)

напечатает удвоенную длину диагонали прямоугольника 4х5 дюймов, выраженную в сантиметрах.


setret

Формат вызова:

    setret <parameter0>;

ничего не возвращает, принимает один параметр;

параметр любого типа, допустим любой операнд, массив не допустим;

назначение операции: приготавливает значение для возврата функции, выполняемой операцией call, но выполнение функции не прерывает, используется совместно с последующим вызовом операции return, break или continue. Пример использования:

    block b;

    uint i;

    i = 5;

    code b

    {

        setret 3;

        stdout 1 " ";

        return;

        puts 2;

    };

    i = (call b);

    puts i;

напечатает: 1 3


code

Формат вызова:

    code <parameter0> <parameter1>;

ничего не возвращает, принимает 2 параметра;

первый параметр типа блок, допустима только переменная, массив не допустим;

второй параметр типа блок, допустима переменная, константа, операция, массив не допустим;

назначение операции: эквивалентно присвоению переменной типа блок допустимого значения, включена для совместимости с будущими реализациями Ci.


stop

Формат вызова:

    stop;

ничего не возвращает, параметров не имеет;

назначение операции: прекращает выполнение Ci программы, если ранее был задан блок завершения в операции onstop, то он выполняется, если stop встречается внутри него, то программа немедленно завершается, пример смотри в описании операции onstop.


onstop

Формат вызова:

    onstop <parameter0>;

ничего не возвращает, принимает 1 параметр;

параметр типа блок, допустима переменная, константа, операция, массив не допустим;

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

    onstop

    {

        puts “finished”

    };

    puts “finishing...”;

    stop;

напечатает

    finishing...

    finished


onerror

Формат вызова:

    onerror <parameter0>;

ничего не возвращает, принимает 1 параметр;

параметр типа блок, допустима переменная, константа, операция, массив не допустим;

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

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

    int i 100;

    onerror

    {

        puts "error";

        if( (errorcode) == 35 )

            { puts "Division by zero" }

                { puts "No parameters given" };

    };

    ``par@ 0 10;

    puts( i / 0 );

напечатает сообщение о делении на ноль, но если раскомментировать строку par@ 0 10; и перекомпилировать, то при выполнении возникнет ошибка обращения к несуществующему параметру блока, и будет напечатано сообщение No parameters given.


errorcode

Формат вызова:

    (errorcode)

возвращает беззнаковое целое, параметров нет;

назначение операции: используется совместно с onerror для получения кода ошибки, подробнее смотри в описании onerror;

если вызывается не в блоке обработки ошибки, то всегда возвращает 0;

возвращаемые коды ошибок:

  • 32 операции передано данное недопустимого типа;
  • 34 стек параметров пуст (попытка выполнить в блоке par# или par@ при том, что в блок не было ничего передано);
  • 35 деление на ноль;
  • 36 два массива не одинакового размера (в базовой библиотеке не используется);
  • 39 операции передано недопустимое значение;
  • 45 индекс вышел за границу массива;
  • 53 слишком глубокая вложенность вызовов блоков или операций с возвратом значения;
  • 60 попытка выполнить sizeof не инициализированного массива;
  • 61 невозможно преобразовать значение, возвращаемое операцией, способ преобразования типов не определен;
  • 71 недопустимая инициализация;
  • 72 недопустимое удаление;
  • 73 переменная цикла вышла за допустимые границы;
  • 76 массив нулевой длины;
  • 77 надо вернуть значение;
  • 78 невозможно открыть файл;
  • 79 невозможно записать в файл;
  • 80 невозможно закрыть файл;
  • 81 невозможно прочесть файл.

delay

Формат вызова:

    delay <parameter0>;

ничего не возвращает, принимает один параметр;

параметр типа вещественное число, допустим любой операнд, массив не допустим;

назначение операции: приостанавливает выполнение Ci-программы на указанное параметром число миллисекунд. Пример использования:

    delay 1000; ``задержка в 1 секунду