nextupprevious

Next:1.6 Объявления процедур и формальные параметры
Up:1 Язык программирования Zonnon
Previous:1.4 Выражения


1.5 Операторы


Операторы обозначают действия. Имеются элементарные и структурные операторы. Элементарные операторы составляются из таких частей, которые сами являются операторами. Они являются присваиванием, вызовом процедуры, операторами await, return и exit. Структурные операторы образуются из частей, которые сами являются операторами. Они используются для выражения последовательного, условного, селективного и повторного выполнения. Оператор может быть также пустым, в этом случае он обозначает отсутствие действия. Пустой оператор включается для того, чтобы ослабить правила пунктуации в последовательности операторов.

Statement = [ Assignment

| ProcedureCall
| IfStatement
| CaseStatement
| WhileStatement
| RepeatStatement
| LoopStatement
| ForStatement
| await Expression
| exit
| return [ Expression ]
| BlockStatement
| launch Statement
| Send
| Receive ].


Последовательность операторов (statement sequence) обозначает последовательность действий, специфицированных компонентными операторами, которые разделяются точкой с запятой.

StatementSequence = Statement {";" Statement}.

Пример:

temp := a; a := b; b := temp; (*обмен значениями между a и b*)
 

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


Оператор присваивания (assignment statement) заменяет текущее значение переменной некоторым новым значением, специфицированным выражением. Выражение должно быть совместимым с переменной по присваиванию (см. 1.11.4). Знак операции присваивания записывается как “:=” и произносится “становится”.

Assignment = Designator ":=" Expression.

Примеры:

i := 0;
p := i = j;
x := i + 1;
k := log2(i+j);
F := log2;
s := {2, 3, 5, 7, 11, 13};
a[i] := (x+y) * (x-y);
t.key := I;
w[i+1].name := "John";
t := c;
 

1.5.2. Вызовы процедур


В module вызов процедуры активизирует процедуру. Когда она объявлена в object, на процедуру ссылаются как на метод. В каждом из этих случаев он может содержать список фактических параметров, которые заменяют соответствующие формальные параметры, определенные в объявлении процедуры (см. раздел 1.6). Соответствие устанавливается позиционно – относительным порядком параметров в списках фактических и формальных параметров. Имеется два вида параметров: параметры переменные и значения.

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

ProcedureCall = Designator.

Примеры:

WriteInt(i*2+1)
INC(w[k].count)
t.Insert("John")

Вызов метода состоит из имени объекта, за которым следует точка и затем имя некоторой процедуры, описанной в объявлении типа объекта для данного объекта. В методе зарезервированное слово self ссылается на объект, в котором вызывается метод.

Вызов конкретной процедуры может также быть “предохранен (safeguarded)” путем прибавления в качестве префикса объекта в определении. Например:

object T implements I, D; … end T;
var t: T;

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

D(t).f(..); ..; .. := D(t).x;

Порядок, в котором вычисляются параметры во время вызова процедуры/метода определены в деталях реализации компилятора (Compiler Implementation Details) [Compiler].
 

1.5.3. Оператор if


IfStatement =
    if Expression then StatementSequence
    {elsif Expression then StatementSequence}
    [else StatementSequence]
    end.

Пример:

if (ch >= "A") & (ch <= "Z") then ReadIdentifier
elsif (ch >= "0") & (ch <= "9") then ReadNumber
elsif (ch = " ' ") or (ch = ' " ') then ReadString
else SpecialCharacter
end

Оператор if специфицирует условное выполнение охраняемой последовательности операторов. Выражение, предшествующее операторной последовательности, называется ее предохранителем, и его тип должен быть boolean. Предохранители вычисляются в порядке их вхождения, если один из них принимает значение true, выполняется ассоциированная с ним последовательность операторов. Если не удовлетворяется ни один предохранителей, выполняется последовательность операторов, следующая за символом else, если он есть.
 

1.5.4. Оператор case


Оператор case специфицирует выбор и исполнение последовательности операторов в соответствии со значением выражения. Вначале вычисляется выражение case; затем вычисляется последовательность операторов, чья case метка содержит полученное значение. Выражение case должно быть целого или кардинального типа, который совместим (см. 1.11.6) с типами всех меток case, либо как выражение case, так и метки case должны иметь тип char или перечисления. Метки case являются константами, и ни одно значение метки не должно встречаться более одного раза. Если значение выражения не встречается в качестве ни одной метки case, то либо выбирается последовательность операторов, следующая за символом else, если он есть, либо возникает исключительная ситуация UnmatchedCase.

CaseStatement = case Expression of Case {"|" Case} [else StatementSequence] end.

Case = [CaseLabelList ":" StatementSequence].

CaseLabelList = CaseLabels {"," CaseLabels}.

CaseLabels = ConstExpression [".." ConstExpression].

Пример:

case ch of
    "A" .. "Z": ReadIdentifier (*предполагается последовательное кодирование букв*)
    | "0" .. "9": ReadNumber
    | "'", '"': ReadString
else SpecialCharacter
end

case month of
    Month.Apr, Month.Jun, Month.Sep, Month.Nov: days := 30
    | Month.Feb:    if Leap(year)
                           then days := 29
                            else days := 28
                            end
else days := 31
end
 

1.5.5 Оператор while


Оператор while специфицирует повторяющееся выполнение последовательности операторов, пока выражение типа boolean (ее предохранитель) сохраняет true. Предохранитель проверяется перед каждым выполнением последовательности операторов, и таким образом, последовательность операторов будет выполнена нуль или более раз.

WhileStatement = while Expression do StatementSequence end.

Примеры:

var i, k, idNumber: integer;

while i # 3 do writeln('Hello'); i := i + 1 end
read(idNumber);
while ~Valid(idNumber) do
        write('Type ID number again ');
        read(idNumber)
end;
(* Valid(idNumber) *)
while i > 0 do i := i div 2; k := k + 1 end
while (t # nil) & (t.key # i) do t := t.left end
 

1.5.6. Оператор repeat


Оператор repeat специфицирует повторяющееся выполнение последовательности операторов до тех пор, пока не выполнится условие, специфицированное выражением типа boolean. Указанная последовательность операторов выполняется по крайней мере один раз.

RepeatStatement = repeat StatementSequence until Expression.

Примеры:

var idNumber: integer;
repeat
    write ('Type ID number '); read(idNumber)
until Valid(idNumber);

var i, x: integer; buffer: array 10 of integer;

i := 0;
(* конвертировать неотрицательное значение x в десятичное представление *)
repeat buffer[i] := x mod 10; x := x div 10; inc(i) until x = 0;
(* распечатать цифры в правильном порядке *)
repeat dec(i); write(char(buffer[i] + integer("0"))) until i = 0
 

1.5.7. Оператор for


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

ForStatement = for ident ":=" Expression to Expression [by ConstExpression] do StatementSequence end.

Пример:

var i : integer;

for i := 0 to 79 do k := k + a[i] end
for i := 79 to 1 by -1 do a[i] := a[i-1] end

Оператор

for v := low to high by step do statements end

эквивалентен

v := low; temp := high;
if step > 0 then
    while v <= temp do statements; v := v + step end
else
    while v >= temp do statements; v := v + step end
end

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

1.5.8. Оператор loop


Оператор loop специфицирует повторяющееся выполнение последовательности операторов. Он завершается выполнением оператора exit в этой последовательности.

LoopStatement = loop StatementSequence end.

Пример:

loop (* копировать целые числа из input в output до первого отрицательного*)
    read(i);
    if i < 0 then exit end;
    write(i)
end

Оператор loop полезен для описания повторений с несколькими точками выхода или в тех случаях, когда условие выхода естественно разместить в середину последовательности операторов.

Оператор exit обозначается символом exit. Он специфицирует завершение объемлющего оператор loop и продолжение исполнения с оператора, следующего за этим оператором loop. Оператор exit контекстно, а не синтаксически ассоциируется с оператором loop, который его содержит.
 

1.5.9. Оператор return


Оператор return указывает на завершение процедуры. Он обозначается символом return, за которым следует выражение, если процедура является процедурой-функцией. Тип выражения должен быть совместим по присваиванию (см. 1.11.4) с типом результата, специфицированным в процедуре.

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

1.5.10. Операторы блока и запуска


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

BlockStatement = begin [ BlockModifiers ]

StatementSequence
{ ExceptionHandler }
[ CommonExceptionHandler ]
end.
BlockModifiers = "{" ident { "," ident } "}". // locked, concurrent

ExceptionHandler = on ExceptionName { "," ExceptionName } do StatementSequence.

CommonExceptionHandler = on exception do StatementSequence.

Исполняется последовательность операторов в блоке.
 

1.5.10.1. Обработка исключительных ситуаций


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

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


Пример:

var idNumber: integer; idValid: boolean;
begin
    read(idNumber);
    if Valid(idNumber) then idValid := true; Process(idNumber)
    else idValid := false (*неправильное число*)
    end
on exception do
idValid := false (*неправильный сорт литер*)
end
 

1.5.10.2. Модификаторы параллельности и операторы запуска


Факультативно блок может иметь модификатор. Определены следующие модификаторы:
 


В обоих случаях ограничители begin и end используются в качестве барьера.

Пример:

begin {locked}
… (*операторы в блоке выполняются последовательно, но отдельными единицами *)
end

begin {concurrent}...launch S; T; launch U; ... end

Действие этого оператора состоит в запуске S, затем исполнении T, затем запуске U и ожидании в end, когда завершаться все запущенные операторы. Это обеспечивает некоторую новую параллельность операторного уровня, которая позволяет программистам специфицировать ‘логику запусков’ без требования, чтобы операторы выполнялись последовательно.
 

1.5.11. Оператор await


Оператор await используется для условного планирования внутри активности в объекте или модуле.

await Expression

Он должен встречаться внутри оператора блока с модификатором locked. Выражение определяет предусловие продолжения выполнения.

Когда он выполняется вычисляется логическое выражение, и если результат есть true, то выполнение продолжается со следующего оператора. Однако, если результат есть false, то выполнение приостанавливается до тех пор, пока системный планировщик последовательно перевычислит условие (возможно неоднократно) и найдет, что оно стало равным true. Тогда выполнение продолжится со следующего оператора.

Примеры:

await (in + 1) mod bufLen # out; (*ждать пока не полон *)
await in # out; (*ждать пока не пуст*)
 

1.5.12. Оператор send


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

Send = send expression ["=>" activity].

Примеры:

send pi*x/180.0 => a
(*Конвертировать градусы в радианы и послать результат вызываемой активности ‘a’ *)
send "29 August 2003" (* Послать строку с датой назад вызвавшей активности*)
 

1.5.13. Оператор receive


Оператор receive может использоваться внутри реализации активности (см. раздел 1.8) для получения значения из диалога. Исполнение блокируется до тех пор, пока не станет значения, доступного для получения.

Receive = receive [activity "=>"] variable.

Примеры:

receive a => date     (* Получить строку date из вызываемой активности ‘a’ *)
receive angle       (* Получить значение angle из вызвавшей активности ‘a’ *)
 

1.5.14. Операторы accept


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

Accept = accept [activity "=>"] variable.

Примеры:

accept a => date (*Получить строку date из вызываемой активности ‘a’, или nil, если ничего сейчас не доступно*)
accept angle (*Получить значение angle из вызвавшей активности ‘a’*)
 
 

Next:1.6 Объявления процедур и формальные параметры
Up:1 Язык программирования Zonnon
Previous:1.4 Выражения


© В.Н. Касьянов, Е.В.Касьянова,2004