Back: 4.8 Conditional operator Forward: 4.9.1 REPEAT loops   FastBack: 4. EDL Up: 4. EDL FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9 Control structures

Within the EXPERIMENT section flow control structures can be used. These are REPEAT, WHILE, UNTIL, FOR and FOREVER loops and IF-ELSE and UNLESS-ELSE constructs. (Please note: all of these keywords have to be spelt in upper case letters!).

Most flow control construct keywords are followed by a condition and all are then followed by a block of statements. Such a block of statements has to be enclosed in curly braces ({ and }) and may contain as many statements as needed (and still fit into the computers memory).


Back: 4.9 Control structures Forward: 4.9.2 WHILE loops   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.1 REPEAT loops

The most simple construct is the REPEAT loop. What is needed following the keyword REPEAT is a number and a block with commands. The number should be an integer number (or an expression resulting in an integer). The following block of statements will now be repeated as many times as specified by the number (or expression). Here's an example:

 
  I = 0;
  SUM = 0;

  REPEAT 100 {
      I = I + 1;
      SUM = SUM + I;
  }

This snippet will calculate the sum of all integers between 1 and 100 (of course, there are more elegant ways to do this, but it's just an example). After the initialization of the two variables `I' and `SUM' the REPEAT loop starts with 100 as the number of repetitions. Now, in curly braces, i.e. between `{' and `}', follow the statements to be executed in the loop.

Please note: If the number of repetitions of the loop is a variable or an expression the variable or expression will be evaluated just once at the very start, i.e. once before the loop is executed, so if you change the value of the variable (or the variables involved in the expression) within the loop the number of repetitions won't change.


Back: 4.9.1 REPEAT loops Forward: 4.9.3 UNTIL loops   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.2 WHILE loops

Nearly as simple a construct is the WHILE loop, but instead of a simple number following the keyword a condition is needed. Usually, this will be a comparison between two numbers, but also a simple number will suffice - if its value is non-zero it will be interpreted as TRUE. Of course, the keyword and the condition have to be followed by a block of statements.

Again, an example:

 
  I = 1;
  Fact = 1;

  WHILE I <= 6 {
      Fact = Fact * I;
      I = I + 1;
  }

This snippet (that also could have been written using a REPEAT loop) calculates the factorial of 6. After initializing the variables I and Fact it is tested in the loop condition if I is still not larger that 6. If this is true, the following block of statements is executed.

Here is now an example for using simple numbers in a condition, using the fact that a non-zero value is always interpreted as TRUE:

 
  I = 6;
  Fact = 1;

  WHILE I {
      Fact *= I;
      I -= 1;
  }

This example does exactly the same as the previous one, i.e. it calculates the factorial of 6. But the difference is that we start with `I' set to 6 and than decrement it successively. Thus we can use `I' in the loops condition by simply checking if it still is non-zero and thus the condition still TRUE and repeating the loop as long as it is.

Sometimes, you may want to check not for the truth but for the falsehood of an expression. In this case you have to prepend the expression with an exclamation mark, `!', or the equivalent logical not operator, `NOT', to reverse the meaning of a test (or use an UNTIL loop, see below).

If you want to check for combinations of expressions you can use the logical AND, OR or XOR (exclusive or) operators. Here is a list of these operators and their meaning:

NOT or !not: negates truth of an expression
AND or &and: true if both left and right hand side expressions are true
OR or |or: true if at least one of the left and right hand side expressions is true
XOR or ~exclusive or: true if either left or right hand side expression is true (but not both)

Please note: For both the logical or operator (`OR' or `|') and the logical and operator (`AND' or `&') the expressions are always only evaluated as far as necessary to determine the final result. Thus for the condition

 
A == 0 OR B != 3

only the first part, A == 0, is tested when A is 0 because in this case the result is already known to be true and does not depend on the second comparison. The same holds for expressions like

 
A != 0 AND lockin_phase( ) > 90.0

If A equals 0 the value of the whole expression is already known to be false even though the lock-ins phase may be less then 90 degrees. Thus no call of the function lockin_phase() will be done.

Thus the sequence in conditions containing the logical "or" and "and" operator is important.

To make it more clear please understand that the code (please read about the IF and ELSE constructs below for more details)

 
IF A == 0 OR B != 3 {
    do_something( );
}

is treated as if you would have written

 
IF A == 0 {
    do_something( );
} ELSE IF B != 3 {
    do_something( );
}

In the same way

 
IF A != 0 AND lockin_phase( ) > 90 {
    do_something( );
}

is logically equivalent to

 
IF A != 0 {
    IF lockin_phase( ) > 90 {
        do_something( );
    }
}

All comparison operators can also be used with strings. The test for equality has its usual meaning (but take care, in the comparison lower and upper case characters are treated as different). The comparison for larger or smaller than is based on the ASCII values of the characters of the string, not the lengths of the strings. For example, the comparison of the strings "ON" and "OFF" will result in "ON" being larger than "OFF" because for the first characters where the strings differ, 'N' and 'F', 'N' has a higher ASCII value than 'F'.


Back: 4.9.2 WHILE loops Forward: 4.9.4 FOR loops   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.3 UNTIL loops

Directly related to the WHILE loop is the UNTIL loop. The only difference is that, instead of repeating the loop until the condition becomes false, the UNTIL loop is repeated until the loop condition becomes true. Thus, the second example for calculating the factorial of 6 also could have been written as

 
  I = 6;
  Fact = 1;

  UNTIL I == 0 {
      Fact *= I;
      I -= 1;
  }

Back: 4.9.3 UNTIL loops Forward: 4.9.5 FOREVER loops   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.4 FOR loops

Before the start of a WHILE loop one usually has to initialize a loop variable and within the statement block one has to update it. In many cases (for example in both the examples for the WHILE loop above) it's much simpler to use a FOR loop instead, because setting the loop variable as well as updating it is automatically done in its condition part. Here's an example that does exactly the same as the first of the two examples for WHILE loops:

 
  Fact = 1;
  FOR I = 1 : 6 {
      Fact *= I;
  }

At the very start of the FOR loop the loop variable `I' is set to 1 and the loop body is run using this value. When the of the loops body is reached`I' is automatically incremented by 1 and then it's tested if it is still less or equal to 6. If this is TRUE the loop is repeated with the new value of `I'. Take care: You can change `I' also within the loop, but you only should do this if you really mean it and know what you're doing!

But you can also reproduce the second version of the factorial calculation using a FOR loop. Here it is:

 
  Fact = 1;
  FOR I = 6 : 1 : -1 {
      Fact *= I;
  }

Now `I' starts of with the value 6 and the third value in the FOR loop condition part is the value to be used for incrementing `I'. In this case it is -1, so `I' actually will be decremented until it is smaller than 1 (the second value in the FOR loop condition). As you see, FOR loop variables can not only be incremented by 1 but by any value (integer or floating point ones). And, of course, the loop variable doesn't have to be an integer!

Please note that after the end of a FOR loop the loop variable does not has the value it had in the last run through the loop but that it has been incremented (or decremented) one more time. I.e. after the end of the loop

 
  FOR I = 1 : 9 : 2 {
      do_something( );
  }

the loop variable I has the value 11 and not 9.

Please also note that the end and increment value os evaluated only at the start of the loop. Thus if you would have

 
End = 10;
Incr = 1;
FOR I = 1 : End : Incr {
   End = 20;
   Incr = 2;
}

the changes done to the variables End and Incr don't have any effect on when the loop ends or on how the loop variable is incremented, it will still stop when the loop variable I reaches 10 and I will continue to be incremented by 1. You will have to use a WHILE loop if you want to change the end of a loop or the increment from within a loop.


Back: 4.9.4 FOR loops Forward: 4.9.6 NEXT statement   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.5 FOREVER loops

There are situations where one wants to have the program running as long as the STOP button doesn't get pressed. While something like this can be realized by using i.e. a REPEAT loop with a huge number of repeats, this would take extremely long when testing the script before the EXPERIMENT is started. In these cases a FOREVER loop is more convenient because the content of the loop is only tested once, so the experiment can start much faster. For obvious reasons, a FOREVER loop doesn't have a loop condition and the loop block starts directly after the FOREVER keyword.

There is a disadvantage of using a FOREVER loop: because fsc2 can't determine in advance when the FOREVER loop is going to be terminated it is not possible to test the loop thoroughly in the test run, i.e. before the experiment is started. Instead, in the test run a FOREVER loop is just run once to do a plausibility check, but further tests are not feasible. Thus, it can not be guaranteed that the experiment will run without errors. Therefore the use of FOREVER loops should be restricted to preliminary experiments, e.g. when trying to figure out the optimum parameters for an experiment, unless you're quite sure you know what you are doing.


Back: 4.9.5 FOREVER loops Forward: 4.9.7 BREAK statement   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.6 NEXT statement

Sometimes under certain conditions one doesn't want to execute all remaining statements of a WHILE, UNTIL, REPEAT or FOR loop but to go back to the test of the loop condition immediately. Whenever the keyword NEXT is encountered in a loop all the remaining statements are skipped and the program jumps directly back to the test of the loop condition.


Back: 4.9.6 NEXT statement Forward: 4.9.8 IF-ELSE constructs   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.7 BREAK statement

There also may be situations where one doesn't want to continue with a loop until the loop condition becomes satisfied but where one has to exit the loop immediately. For this purpose the keyword BREAK is to be used. If it is found as the next statement to be executed in a loop the program immediately jumps to the first statement following the loops block.


Back: 4.9.7 BREAK statement Forward: 4.9.9 UNLESS-ELSE constructs   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.8 IF-ELSE constructs

Finally, there is the IF-ELSE construct, functioning as in most other programming languages. In the simplest case you just have the IF part to execute instructions only under certain conditions. In this case you start with the IF keyword, followed by the condition that has to be met in order to run the following code and then the set of statements to be enclosed in curly braces. Here's a simple example:

 
  IF x < 0 {
      x *= -1.0;
}

Here the variable x is multiplied by -1.0 only if x is negative, i.e. it basically just sets x to its absolute value (there's also the built-in function abs() for calculating the absolute value of variable which probably is a lot faster).

By using the ELSE statement you can specify an alternative with statements to be executed if the IF condition is not being met. Also the block of alternative statements must be enclosed in curly braces:

 
  IF x >= 0 {
      x = 1.0;
  } ELSE {
      x = 0.0;
  }

But things can also get more complex - you may follow the ELSE directly by another IF. Let's assume that you need to set x to 1 if it's larger than 1, to 0 if it belongs to the interval [0, 1] and to -1 if it's smaller than 0. Then you could use:

 
  IF x > 1.0 {
      x = 1.0;                 // x is larger than 1
  } ELSE IF x >= 0.0 {
      x = 0.0;                 // x must be element of [0, 1]
  } ELSE {
      x = -1.0;                // otherwise x is less than 0
  }

Back: 4.9.8 IF-ELSE constructs Forward: 4.10 Miscellaneous   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

4.9.9 UNLESS-ELSE constructs

UNLESS is identical to IF with the only exception that the condition is not tested for truth but for falsehood, i.e. while in an IF construct the following block of statements is executed when the condition is true, in UNLESS constructs the block is only executed when the condition test fails. Of course, also with the UNLESS an alternative can be specified with an ELSE block.

As already mentioned for FOREVER loops also IF-ELSE and UNLESS-ELSE constructs introduce some problems for testing an EDL script before the real experiment is done. This happens when the condition to be tested depends either on user input (e.g. tests if the user pressed a button etc.) or on the results of a measurement itself. In these cases the flow of control of the program can not be known in advance and thus a thorough test is impossible. Thus it can happen that the test run of the experiment succeeds but the actual experiment stops with an error that could not be anticipated.


Back: 4.9.8 IF-ELSE constructs Forward: 4.10 Miscellaneous   FastBack: 4. EDL Up: 4.9 Control structures FastForward: 5. Built-in Functions

This document was generated by Jens Thoms Toerring on September 6, 2017 using texi2html 1.82.