Seed7 - The extensible programming language
Seed7 FAQ Manual Screenshots Examples Libraries Algorithms Download Links
Manual Introduction Tutorial Declarations Statements Types Parameters Objects File System Syntax Tokens Expressions OS access Actions Foreign funcs Errors
Statements Assignment while repeat for for-step for-each if case
Manual
Statements
 previous   up   next 

4. PREDEFINED STATEMENTS

The library contains several predefined statements: assignment, while-statement, repeat-statement, for-statement, if-statement, case-statement and procedure call.

Syntax:
statement ::=
single_statement [ ';' [ statement ] ] .

single_statement ::=
assignment_statement | while_statement | repeat_statement |
for_statement | for_step_statement | for_each_statement |
if_statement | case_statement |
procedure_call | empty_statement .

empty_statement ::=
'noop' .

Everywhere where one statement can be written a sequence of statements can also be used. The semicolon-operator concatenates two statements giving a new statement. The semicolon operator can also be used behind the last statement of a statement sequence. In this case the semicolon is just ignored.

Declaration:

$ syntax expr: .(). ; .()   is <- 50;
$ syntax expr: .(). ;       is <- 50 [1];

const proc: (ref void: statement1) ; (ref void: statement2) is noop;

4.1 Assignment

For example:

minimum := maximum div 2;

Semantics:
The expression at the right side of the assignment symbol is evaluated and assigned to the variable at the left side.
Syntax:
assignment_statement ::=
designator ':=' expression .

The assignment statement is defined for every standard type.

If an assignment for a new user defined type is needed it must be defined additionally.

Declaration:

$ syntax expr: .(). := .()   is <-> 20;

const proc: (inout type: dest) := (ref type: source)             is action "TYP_CPY";
const proc: (inout proc: dest) := (ref proc: source)             is action "PRC_CPY";
const proc: (inout func aType: dest) := (ref func aType: source) is action "PRC_CPY";
const proc: (inout varfunc aType: dest) := (ref varfunc aType: source) is action "PRC_CPY";
const proc: (inout ACTION: dest) := (in ACTION: source)          is action "ACT_CPY";
const proc: (inout boolean: dest) := (in boolean: source)        is action "BLN_CPY";
const proc: (inout integer: dest) := (in integer: source)        is action "INT_CPY";
const proc: (inout char: dest) := (ref char: source)             is action "CHR_CPY";
const proc: (inout string: dest) := (ref string: source)         is action "STR_CPY";
const proc: (inout reference: dest) := (ref reference: source)   is action "REF_CPY";
const proc: (inout ref_list: dest) := (in ref_list: source)      is action "RFL_CPY";
const proc: (inout ptrType: dest) := (in ptrType: source)        is action "REF_CPY";
const proc: (inout varptrType: dest) := (in varptrType: source)  is action "REF_CPY";
const proc: (inout arrayType: dest) := (in arrayType: source)    is action "ARR_CPY";
const proc: (inout bitset: dest) := (in bitset: source)          is action "SET_CPY";
const proc: (inout structType: dest) := (in structType: source)  is action "SCT_CPY";
const proc: (inout enumType: dest) := (in enumType: source)      is action "ENU_CPY";
const proc: (inout clib_file: dest) := (ref clib_file: source)   is action "FIL_CPY";
const proc: (inout interfaceType: dest) := (ref interfaceType: source) is action "ITF_CPY";
const proc: (inout interfaceType: dest) := (ref aType: source)   is action "ITF_CPY2";

4.2 while-statement

For example:

while maximum > minimum do
  minimum := 2 * minimum + stepValue;
  decr(stepValue);
end while;

Semantics:
First the condition between while and do is evaluated. When this evaluation yields FALSE, the while-statement is finished. When the evaluation yields TRUE, the statement between do and end is executed and the whole while-statement is executed again.
Syntax:
while_statement ::=
'while' expression 'do'
  statement
'end' 'while' .

The expression must be of type boolean.

Declaration:

$ syntax expr: .while.().do.().end.while   is -> 25;

const proc: while (ref func boolean: condition) do (in proc: statement) end while is action "PRC_WHILE";
const proc: while (in boolean: condition)  do (in proc: statement) end while      is action "PRC_WHILE";

Alternate declaration:

const proc: while (ref func boolean: condition) do (in proc: statement) end while is func
  begin
    if condition then
      statement;
      while condition do
        statement;
      end while;
    end if;
  end func;

4.3 repeat-statement

For example:

repeat
  incr(minimum);
  maximum := maximum - stepValue;
until 2 * minimum > maximum;

Semantics:
The statement between repeat and until is executed. Then the condition after until is evaluated. When this evaluation yields TRUE, the repeat-statement is finished. When the evaluation yields FALSE the repeat-statement is executed again.
Syntax:
repeat_statement ::=
'repeat'
  statement
'until' expression .

The expression must be of type boolean.

Declaration:

$ syntax expr: .repeat.().until.()   is -> 25;

const proc: repeat (in proc: statement) until (ref func boolean: condition) is action "PRC_REPEAT";
const proc: repeat (in proc: statement) until (in boolean: condition)       is action "PRC_REPEAT";

Alternate declaration:

const proc: repeat (in proc: statement) until (ref func boolean: condition) is func
  begin
    statement;
    if not condition then
      repeat
        statement;
      until condition;
    end if;
  end func;

4.4 for-statement

For example:

for index range min_index to max_index do
  sumValue +:= field[index];
end for;

Semantics:
When the to symbol is used the for-statement is defined as follows:
First the lower limit and the upper limit which stand behind range and to are evaluated. Then the lower limit is assigned to the control variable which stands behind for. If the value of the control variable is less than or equal the upper limit the statements behind do are executed. After that the control variable is incremented and compared with the upper limit again. This compare - execute - increment cycle is repeated until the control variable is greater than the upper limit.
When the downto symbol is used the for-statement is defined as follows:
First the upper limit and the lower limit which stand behind range and downto are evaluated. Then the upper limit is assigned to the control variable which stands behind for. If the value of the control variable is greater than or equal the lower limit the statements behind do are executed. After that the control variable is decremented and compared with the lower limit again. This compare - execute - increment cycle is repeated until the control variable is less than the lower limit.
Syntax:
for_statement ::=
'for' identifier 'range' expression [ 'to' | 'downto' ] expression 'do'
  statement
'end' 'for' .

Declaration:

$ syntax expr: .for.().range.().to.().do.().end.for       is -> 25;
$ syntax expr: .for.().range.().downto.().do.().end.for   is -> 25;

const proc: FOR_DECLS (in type: aType) is func
  begin
    const proc: for (inout aType: variable) range
        (in aType: lowerLimit) to (in aType: upperLimit) do
        (in proc: statements) end for is func
      begin
        variable := lowerLimit;
        if variable <= upperLimit then
          statements;
          while variable < upperLimit do
            incr(variable);
            statements;
          end while;
        end if;
      end func;

    const proc: for (inout aType: variable) range
        (in aType: upperLimit) downto (in aType: lowerLimit) do
        (in proc: statements) end for is func
      begin
        variable := upperLimit;
        if variable >= lowerLimit then
          statements;
          while variable > lowerLimit do
            decr(variable);
            statements;
          end while;
        end if;
      end func;
  end func;

FOR_DECLS(integer);
FOR_DECLS(char);
FOR_DECLS(boolean);

4.5 for-step-statement

For example:

for evenNumber range 0 to 10 step 2 do
  write(evenNumber);
end for;

Semantics:
When the to symbol is used the for-statement is defined as follows:
First the lower limit and the upper limit which stand behind range and to are evaluated. Then the lower limit is assigned to the control variable which stands behind for. If the value of the control variable is less than or equal the upper limit the statements behind do are executed. After that the control variable is incremented by the value behind step. Then the control variable is compared with the upper limit again. This compare - execute - increment cycle is repeated until the control variable is greater than the upper limit.
When the downto symbol is used the for-statement is defined as follows:
First the upper limit and the lower limit which stand behind range and downto are evaluated. Then the upper limit is assigned to the control variable which stands behind for. If the value of the control variable is greater than or equal the lower limit the statements behind do are executed. After that the control variable is decremented by the value behind step. Then the control variable is compared with the lower limit again. This compare - execute - increment cycle is repeated until the control variable is less than the lower limit.
Syntax:
for_step_statement ::=
'for' identifier 'range' expression [ 'to' | 'downto' ] expression 'step' expression 'do'
  statement
'end' 'for' .

Declaration:

$ syntax expr: .for.().range.().to.().step.().do.().end.for       is -> 25;
$ syntax expr: .for.().range.().downto.().step.().do.().end.for   is -> 25;

const proc: FOR_STEP_DECLS (in type: aType) is func
  begin
    if getobj((inout aType: variable) +:= (in integer: delta)) <> NIL then

      const proc: for (inout aType: variable) range (in aType: lowerLimit) to (in aType: upperLimit)
          step (in integer: incr_step) do
          (in proc: statements) end for is func
        begin
          variable := lowerLimit;
          while variable <= upperLimit do
            statements;
            variable +:= incr_step;
          end while;
        end func;

    end if;
    if getobj((inout aType: variable) -:= (in integer: delta)) <> NIL then

      const proc: for (inout aType: variable) range (in aType: upperLimit) downto (in aType: lowerLimit)
          step (in integer: decr_step) do
          (in proc: statements) end for is func
        begin
          variable := upperLimit;
          while variable >= lowerLimit do
            statements;
            variable -:= decr_step;
          end while;
        end func;

    end if;
  end func;

FOR_STEP_DECLS(integer);

4.6 for-each-statement

For example:

for currObject range element_list do
  result &:= " " & str(currObject);
end for;

Semantics:
First the element list which stands behind range is evaluated. If the element list is empty the for-each-statement is finished. Otherwise the first element of the element list is assigned to the control variable which stands behind for. Then the statements behind do are executed. If there is no next element in the element the for-each-statement is finished. Otherwise the next element of the element list is assigned to the control variable. This check for next element - execute cycle is repeated until there is no next element in the element list.
Syntax:
for_each_statement ::=
'for' identifier 'range' expression 'do'
  statement
'end' 'for' .

Declaration:

$ syntax expr: .for.().range.().do.().end.for   is -> 25;

const proc: for (inout reference: variable) range (in ref_list: aRefList) do
              (in proc: statement)
            end for is action "RFL_FOR";

const proc: for (inout baseType: variable) range (in arrayType: arr_obj) do
              (in proc: statements)
            end for is func
  local
    var integer: number is 0;
  begin
    for number range minIdx(arr_obj) to maxIdx(arr_obj) do
      variable := arr_obj[number];
      statements;
    end for;
  end func;

const proc: for (inout baseType: variable) range (in setType: a_set) do
              (in proc: statements)
            end for is func
  begin
    for variable range min(a_set) to max(a_set) do
      if variable in a_set then
        statements;
      end if;
    end for;
  end func;

4.7 if-statement

For example:

if sumValue < minimum then
  factor := sumValue;
  sumValue := minimum;
elsif sumValue > maximum then
  factor := -sumValue;
  sumValue := maximum;
else
  factor := 0;
end if;

Semantics:
The expressions before then are evaluated in row. When such an expression evaluates to TRUE the statements behind then are executed and the if-statement is finished. If all expressions before then evaluate to FALSE and an else-part is present the statements behind else are executed and the if-statement is finished. If all expressions before then evaluate to FALSE and no else-part is present the if-statement is finished.
Syntax:
if_statement ::=
'if' expression 'then'
  statement
{ 'elsif' expression 'then'
  statement }
[ 'else'
  statement ]
'end' 'if' .

The expression must be of type boolean.

Declaration:

$ syntax expr: .if.().then.().end.if      is -> 25;
$ syntax expr: .if.().then.().().end.if   is -> 25;

$ syntax expr: .elsif.().then.()          is <- 60;
$ syntax expr: .elsif.().then.().()       is <- 60;
$ syntax expr: .else.()                   is <- 60;

const type: ELSIF_RESULT is newtype;
const proc: (ref ELSIF_RESULT: dest) ::= enumlit       is action "ENU_GENLIT";
const ELSIF_RESULT: ELSIF_EMPTY is enumlit;
const type: ELSIF_PROC                                 is func ELSIF_RESULT;
const proc: (ref ELSIF_PROC: dest) ::= (ref ELSIF_RESULT: source) is action "ENU_CREATE";

const proc:       if (in boolean: condition) then
                    (in proc: statements)
                  end if                               is action "PRC_IF";

const proc:       if (in boolean: condition) then
                    (in proc: statements)
                  (in ELSIF_PROC: elsifPart)
                  end if                               is action "PRC_IF_ELSIF";

const ELSIF_PROC: elsif (in boolean: condition) then
                    (in proc: statements)              is action "PRC_IF";

const ELSIF_PROC: elsif (in boolean: condition) then
                    (in proc: statements)
                  (in ELSIF_PROC: elsifPart)           is action "PRC_IF_ELSIF";

const ELSIF_PROC: else
                    (in void: elsePart)                is ELSIF_EMPTY;

4.8 case-statement

For example:

case currChar of
  when {'A' .. 'Z'} | {'a' .. 'z'}:
    characterClass := LETTER;
  when {'0' .. '9'}:
    characterClass := DIGIT;
  when {'!', '$', '%', '&', '*', '+', ',', '-', '.', '/',
      ':', ';', '<', '=', '>', '?', '@', '\', '^', '`',
      '|', '~'}:
    characterClass := SPECIAL;
  when {'(', ')', '[', ']', '{', '}'}:
    characterClass := PAREN;
  when {'"'}:  # Also possible '\"'
    characterClass := APPOSTROPHE;
  when {'''}:  # Also possible '\''
    characterClass := QUOTE;
  otherwise:
    characterClass := ILLEGAL;
end case;

Semantics:
The expression between case and of is evaluated. When the resulting value is element of a set behind a when the statements behind the corresponding colon are executed and the case-statement is finished. If the value is not element of a set behind a when and an otherwise part is present the statements behind the colon of the otherwise are executed and the case-statement is finished. If the value is not element of a set behind a when and no otherwise part is present the case-statement is finished.
Syntax:
case_statement ::=
'case' expression 'of'
  { 'when' set_expression ':'
    statement }
  [ 'otherwise' ':'
    statement ]
'end' 'case' .

set_expression ::=
expression .

Declaration:

$ syntax expr: .case.().of.().end.case                    is -> 25;
$ syntax expr: .case.().of.().otherwise. : .().end.case   is -> 25;
$ syntax expr: .case.().of.end.case                       is -> 25;

$ syntax expr: .when.(). : .().()   is <- 60;
$ syntax expr: .when.(). : .()      is <- 60;

const proc: CASE_DECLS (in type: aType) is func
  local
    var type: WHEN_RESULT is void;
    var type: WHEN_PROC is void;
    var type: SELECTOR_TYPE is void;
  begin
    WHEN_RESULT := newtype;
    WHEN_PROC := (func WHEN_RESULT);
    SELECTOR_TYPE := set of aType;
    const proc: case (ref aType: decisionValue) of end case                     is noop;
    const proc: case (ref aType: decisionValue) of
                  (ref WHEN_PROC: whenPart)
                end case                                                        is action "PRC_CASE";
    const proc: case (ref aType: decisionValue) of
                  (ref WHEN_PROC: whenPart)
                  otherwise : (ref proc: statements)
                end case                                                        is action "PRC_CASE_DEF";
    const proc: (ref WHEN_RESULT: dest) ::= enumlit                             is action "ENU_GENLIT";
    const WHEN_RESULT: WHEN_EMPTY (attr aType) is enumlit;
    const proc: (ref WHEN_PROC: dest) ::= (ref WHEN_RESULT: source)             is action "ENU_CREATE";
    const WHEN_PROC: when (ref SELECTOR_TYPE: whenSet) : (ref proc: statement)  is WHEN_EMPTY(aType);
    const WHEN_PROC: when (ref SELECTOR_TYPE: whenSet) : (ref proc: statement)
                       (ref WHEN_PROC: whenPart)                                is WHEN_EMPTY(aType);
  end func;

CASE_DECLS(integer);
CASE_DECLS(char);
CASE_DECLS(boolean);


 previous   up   next