Seed7 
 FAQ 
 Manual 
 Screenshots 
 Examples 
 Algorithms 
 Download 
 Links 

 Manual 
 Introduction 
 Tutorial 
 Declarations 
 Statements 
 Types 
 Parameters 
 Objects 
 File System 
 Syntax 
 Tokens 
 Expressions 
 OS access 
 Actions 
 Errors 

 Statements 
 Assignment 
 while 
 repeat 
 for 
 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 | 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 param) ; (ref void param) 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 param) := (ref type param) is           action "TYP_CPY";
    const proc: (inout proc param) := (ref proc param) is           action "PRC_CPY";
    const proc: (inout func aType param) := (ref func aType param) is action "PRC_CPY";
    const proc: (inout varfunc aType param) := (ref varfunc aType param) is action "PRC_CPY";
    const proc: (inout ACTION param) := (in ACTION param) is        action "ACT_CPY";
    const proc: (inout boolean param) := (in boolean param) is      action "BLN_CPY";
    const proc: (inout integer param) := (in integer param) is      action "INT_CPY";
    const proc: (inout char param) := (ref char param) is           action "CHR_CPY";
    const proc: (inout string param) := (ref string param) is       action "STR_CPY";
    const proc: (inout reference param) := (ref reference param) is action "REF_CPY";
    const proc: (inout ref_list param) := (in ref_list param) is    action "RFL_CPY";
    const proc: (inout ptrType param) := (in ptrType param) is      action "REF_CPY";
    const proc: (inout varptrType param) := (in varptrType param) is action "REF_CPY";
    const proc: (inout arrayType param) := (in arrayType param) is  action "ARR_CPY";
    const proc: (inout bitset param) := (in bitset param) is        action "SET_CPY";
    const proc: (inout structType param) := (in structType param) is action "SCT_CPY";
    const proc: (inout enumType param) := (in enumType param) is    action "ENU_CPY";
    const proc: (inout PRIMITIVE_FILE param) := (ref PRIMITIVE_FILE param) is action "FIL_CPY";
    const proc: (inout file param) := (ref file param) is           action "CLS_CPY";
    const proc: (inout file param) := (ref null_file param) is      action "CLS_CPY2";
    const proc: (inout file param) := (ref external_file param) is  action "CLS_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 param) do (ref proc param) end while is action "PRC_WHILE";
    const proc: while (ref boolean param)  do (ref proc param) end while is     action "PRC_WHILE";

Alternate declaration:

    const proc: while (ref func boolean: condition) do (ref 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 (ref proc param) until (ref func boolean param) is action "PRC_REPEAT";
    const proc: repeat (ref proc param) until (ref boolean param) is      action "PRC_REPEAT";

Alternate declaration:

    const proc: repeat (ref 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: lower_limit) to (in aType: upper_limit) do
            (in proc: statements) end for is func
          begin
            variable := lower_limit;
            if variable <= upper_limit then
              statements;
              while variable < upper_limit do
                incr(variable);
                statements;
              end while;
            end if;
          end func;

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

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

4.5 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_statement ::=
      'for' identifier 'range' expression 'do'
        statement
      'end' 'for' .

Declaration:

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

    const proc: for (ref reference param) range (ref ref_list param) do
                  (ref proc param)
                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 1 to length(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.6 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 param) ::= 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 param) ::= (ref ELSIF_RESULT param) is action "ENU_CREATE";

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

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

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

    const ELSIF_PROC: elsif (in boolean param) then
                        (in proc param)
                      (in ELSIF_PROC param) is         action "PRC_IF_ELSIF";

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


    const proc: if TRUE  then (in void param) end if is                           noop;
    const proc: if TRUE  then (in void param) (in ELSIF_PROC param) end if is     noop;
    const proc: if FALSE then (in proc param) end if is                           noop;
    const proc: if FALSE then (in proc param) (in ELSIF_RESULT param) end if is   noop;
    const ELSIF_PROC: elsif TRUE  then (in void param) is                         ELSIF_EMPTY;
    const ELSIF_PROC: elsif TRUE then (in void param) (in ELSIF_PROC param)   is  ELSIF_EMPTY;
    const ELSIF_PROC: elsif FALSE then (in proc param) is                         ELSIF_EMPTY;
    const ELSIF_PROC: elsif FALSE then (in proc param) (in ELSIF_RESULT param) is ELSIF_EMPTY;

4.7 case-statement

For example:

    case currChar of
      when {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
          'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
          'U', 'V', 'W', 'X', 'Y', 'Z'}:
        characterClass := LETTER;
      when {'0', '1', '2', '3', '4', '5', '6', '7', '8', '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' .

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 param) of end case                       is noop;
        const proc: case (ref aType param) of
                      (ref WHEN_PROC param)
                    end case                                                 is action "PRC_CASE";
        const proc: case (ref aType param) of
                      (ref WHEN_PROC param)
                      otherwise : (ref proc param)
                    end case                                                 is action "PRC_CASE_DEF";
        const proc: (ref WHEN_RESULT param) ::= enumlit                      is action "ENU_GENLIT";
        const WHEN_RESULT: WHEN_EMPTY (attr aType) is enumlit;
        const proc: (ref WHEN_PROC param) ::= (ref WHEN_RESULT param)        is action "ENU_CREATE";
        const WHEN_PROC: when (ref SELECTOR_TYPE param) : (ref proc param)   is WHEN_EMPTY(aType);
        const WHEN_PROC: when (ref SELECTOR_TYPE param) : (ref proc param)
                           (ref WHEN_PROC param)                             is WHEN_EMPTY(aType);
      end func;

    CASE_DECLS(integer);
    CASE_DECLS(char);


 previous   up   next