Chapter 5. Control Flow

Table of Contents

5.1. Statements
5.1.1. Conditionals
5.1.2. Loops
5.1.3. Goto, Break, Continue, Return
5.2. Function Calls
5.3. Event Handling
5.3.1. Interprocess Communication Message Events
5.3.2. Timers
5.3.3. Symbol Value Events (Active Values)
5.3.4. Cascade DataHub Point Events (Exception Handlers)
5.3.5. Windowing System Events
5.3.6. Signals
5.4. Error Handling
5.4.1. Situations that might cause Gamma to crash

Gamma provides a variety of mechanisms for control flow. These generally fall into the categories of statements, function calls, event handlers and error handlers. Many of these are dealt with in more detail in other sections of this document. All functions have a detailed entry in the Reference Manual.

5.1. Statements

A statement in Gamma is any syntactically complete piece of code that can be independently evaluated, written in statement syntax. There are two kinds of statement syntax, as follows:

A semi-colon at the end of an expression is used to denote a single, one-line statement.

{ }  Curly brackets surrounding zero or more expressions or statements create a single statement from them. Multiple statements within the curly brackets can be grouped in any combination, and nested in any number of levels. This statement syntax is also referred to as a compound statement or code block. Each expression or statement is evaluated in order, and the result is the result of the last statement or expression. A code block in Gamma does not create a local scope.

Gamma has a number of built-in statements, several of which are explained below. For a complete list of built-in Gamma statements, see Statements in the Reference Manual.

5.1.1. Conditionals

Gamma contains a single conditional statement: if. The if function evaluates its condition, and if the condition is non-nil, then the first statement after the if is performed. If the condition is nil, the else clause of the statement is executed. It is not mandatory that an if statement have an else clause. In the case of nested if statements, an else clause will always bind with the nearest if statement.

For example:

...
if (var == 1)
    count1 ++;
else if (var == 2)
    count2 ++;
else if (var == 3)
    count3 ++;
...

The if statement accepts only a single statement for its true and false clauses. Using the code block statement syntax, it is possible to perform more than one action inside an if.

Example:

...
if (var == "string")
{   
     count++;
     princ("The number is ", count, "\n");
}
...
		

5.1.2. Loops

Gamma supports three looping statements: for, while and with. The for loop looks exactly like a for loop in C:

...
local i;
for (i = 1; i < N; i++)
 {
   body_statements
 }
...
		  

A while loop is also exactly like the C while loop, though the do/while variant available in C is not supported in Gamma.

Gamma adds the with loop, which walks a list or an array and executes a body statement once for each element in the list or array. The with loop may be instructed to collect the results of the body statement for each iteration, and return the accumulated results as a new list or array. The iteration variable in a with loop is defined only within the body of the loop. For an example, see the Lists and Arrays section in the Basic Data Types and Mechanisms chapter.

5.1.3. Goto, Break, Continue, Return

Gamma does not contain facilities for non-linear local jumps. Many languages provide one or more wrappers on the goto function, such as break (go to the end of the expression), continue (go to the beginning of the expression) and return (go to the end of the function). These facilities can be used on occasion for clarity, but can commonly act to confuse both the programmer and the reader.

In Gamma, such a facility would be very confusing, as it is not always clear which expression constitutes the scope of a break, continue or return. In addition, the execution speed penalty associated with supporting local jumps in a functional language generally outweighs the benefit in the few cases where a local jump would be convenient. Further, because Gamma is dynamically scoped, a local jump would be defined as a jump that does not cross a scope boundary rather than the more common C definition of a jump that does not cross a function boundary. This distinction greatly reduces the value of, and the need for, a local jump capability.

The most common local jump instruction in procedural languages is return. This instruction moves the execution to the bottom of the function and supplies a return value for the function. In Gamma, all functions implicitly return a value which is the result of the last expression to be evaluated within the function body. If no expression is evaluated, then the function returns nil. If the programmer wishes to return the value of a symbol, he or she can simply write that symbol, followed by a semicolon, as the last statement to be evaluated in the function.