Statements
Conditional Execution
If Statement
The if statement executes a block of code if a specified condition evaluates to true. The various syntax permutations for the if statement are as follows.
<CodeBlock>
end
<CodeBlock1>
else
<CodeBlock2>
end
<CodeBlock1>
elseif <Condition2>
<CodeBlock2>
else
<CodeBlock3>
end
If the condition does not evaluate to true, then code execution branches to the next elseif or else conditional. If none of the conditionals evaluate to true, then the code branches to the code after the end of the if statement.
$myOtherVar = 1
elseif ($myVar < -20)
$myOtherVar = 0
else
$myOtherVar = -1
end
Switch Statement
The switch statement allows control to be transferred to one of various sections of code depending on the value of a given expression. The basic syntax of the switch statement is as follows.
case <Constant1>
<CodeBlock1>
case <Constant2>
<CodeBlock2>
case <Constant3>
<CodeBlock3>
...
default
<CodeBlockDefault>
end
If the value of the <Expression> matches the value of one of the case <Constant> values, then the statements under the matching case label will be executed. If the optional default label is specified, and the <Expression> does not match any of the specified case <Constant> values, then the statements under the default label will be executed.
The <Expression> must resolve to one of the following primitive data types:
- integer
- real
- axis
- enum
Each of the <Constant> values must be a constant value. A constant value is any value that can be determined at the time that the program is compiled. Constants include literals such as 3 or 2.5, as well as simple mathematical expressions containing only literals, such as (5 - 2), (0x1 << 3), or (2.5 + 3.0).
The data type of each <Constant> value must be the same data type as the <Expression>, or a data type that can be converted to the data type of the <Expression>. In addition, each of the <Constant> values must be unique. A constant value may appear in only one case within a switch statement.
An optional default label can be used to specify statements that should execute when the <Expression> does not equal any of the case <Constant> values.
An example of a switch statement is as follows.
case 0
$rglobal[0] = 0
case 1
$rglobal[0] = $myVar
default
$rglobal[0] = -$myVar
end
Each case or default label must have code specified to execute when the switch expression evaluates to the value of that label. For example, the following switch statement would cause a compilation error because the default label does not have any code specified.
case 0
$rglobal[0] = $myVar
default
// There is no code specified here
// This is an error
end
Unlike switch statements found in other programming languages, the switch statement in this language does not have the concept of fallthrough execution because the end of a code section specified for a case or default label is the next case or default label, or the end specified for the switch. Some other programming languages use the break keyword to denote the end of a block of code within a switch statement, but the break keyword does not have this effect in AeroScript.
However, multiple case labels may be specified to execute the same code within a switch statement. In the following example, $iglobal[0] will be set to 0 if the value of $myVar is either 0 or 1.
case 0
case 1
$iglobal[0] = 0
case 2
$iglobal[0] = 1
default
$iglobal[0] = 2
end
Iterative Execution
While Loop
The while loop executes a block of code while a specified condition is true. The syntax of a while loop is as follows.
<Condition>
end
The <Condition> is considered to be true if it evaluates as true (e.g., relational operators such as > and <= evaluate as true/false in a conditional) or if it has a nonzero value (e.g., 2.0).
If the specified condition evaluates as false when the while statement is first executed, the block of code in the body of the while statement is never executed.
$myVar[$iterations] = $rglobal[0]
$iterations++
end
For Loop
The for loop executes a block of code in an iterative fashion. The syntax of a for loop is as follows.
<CodeBlock>
end
for <CounterVariable> = <StartValue> to <EndValue> step <StepValue>
<CodeBlock>
end
The <CounterVariable> is set to the specified <StartValue>, and the loop will continue to iterate until the counter variable reaches the <EndValue>. The <CounterVariable> must be declared before it can be used in a for loop.
$rglobal[$myVar] = $myVar
end
The <StepValue> is an optional argument that can be used to determine how much the <CounterVariable> will increment/decrement with each loop iteration. If the <StepValue> is not specified, the <CounterVariable> will increment by 1 with each iteration of the loop.
for $myVar = 0 to 9 step 2
$rglobal[$myVar] = $myVar
end
If the <StartValue> is greater than the <EndValue> (or less than the <EndValue> if the <StepValue> is negative), then the loop will not be entered and code execution will immediately transfer to after the end keyword.
// This code is never executed
$rglobal[$myVar] = $myVar
end
ForEach Loop
The foreach loop executes a block of code for each element in a given array variable, in order from the lowest index to the highest index. The syntax of a foreach loop is as follows.
<CodeBlock>
end
The <ArrayVariable> is the variable that is iterated over within the loop. It must be a 1-dimensional, 2-dimensional, or 3-dimensional array variable. The <IterationVariable> is created to have the same data type as the <ArrayVariable> when the <ArrayVariable> is accessed with the array access operator ([]). For example, if the <ArrayVariable> is a 2-dimensional array of real values, then the <IterationVariable> will be declared as a 1-dimensional array of real values. The <IterationVariable> exists only within the foreach loop for which it was specified. The following is an example of using a foreach loop to iterate over each element of a 1-dimensional array variable.
// Perform the same actions for each axis in the array of axes
foreach var $axis in $axes
Enable($axis)
Home($axis)
AnalogOutputSet($axis, 0, 2.5)
end
The following example shows how a foreach loop can be used to iterate over a 2-dimensional array, which can be useful when performing motion over a predetermined set of positions. In the example, the $point iterator variable is unlike any variable that can be declared normally because it is able to access different arrays within the foreach loop.
var $positions[4][2] = [
[10.0, 20.0],
[20.0, 40.0],
[30.0, 60.0],
[40.0, 80.0]]
// Enable the axes
Enable($axes)
// Iterate over each sub-array in the 2-dimensional $positions[][] variable
foreach var $point in $positions
MoveLinear($axes, $point)
end
A foreach loop can be used to iterate over an array of any data type, including a user-defined struct.
struct Point $x as real $y as real end var $points[4] as Point = [ [10, 20], [4, 87], [-1, 3], [9, 41] ] var $xTotal as real = 0 var $yTotal as real = 0 foreach var $point in $points $xTotal += $point.x $yTotal += $point.y end
Repeat Loop
The repeat loop is used to execute a block of code a specified number of times. The syntax of a repeat loop is as follows.
<CodeBlock>
end
The <Count> expression specifies the number of times that the repeat loop will execute. This expression must be an integer expression or a real expression that evaluates to an integer value (for example, 3.0).
$rglobal[0] = $rglobal[0] * 2
end
The <Count> expression will only be evaluated the first time that the repeat loop is executed, and not each time that a loop iteration completes. This means that event if you modify the variable that was specified as the <Count> of a repeat loop within the <CodeBlock>, the number of iterations of the loop will not change.
repeat $myVar // This loop repeats 10 times
$myVar = $myVar + 1
end
If the <Count> expression is less than or equal to zero, code execution will never enter the loop and will immediately branch to the end specified for the repeat loop.
Conditional and Iterative Statement Nesting
Many control flow statements can be nested within each other to give more flexibility. For example, an if statement can be placed inside of a repeat statement, and vice versa.
if $myVar == 0
Enable(X)
else
Disable(X)
end
end
Labels
A label can be the target of a Goto Statement. Labels have the following syntax.
The <LabelName> must be a valid identifier (see Valid Identifier Format), and cannot be the same as any of the Reserved Keywords or an axis name.
A label can be specified on a line by itself.
RunProgram()
goto programStart
A label may also directly precede a statement.
In addition, multiple labels can be specified on the same line, but must precede any statements on that line.
Labels are case-sensitive. For example, myLabel and MYLABEL refer to different labels.
It is generally discouraged to use the goto statement, and therefore labels. Refer to the Goto Statement for more information.
Unconditional Branching
Goto Statement
A goto statement is used to unconditionally transfer program execution to a line of code with a given Labels. The following is the syntax for a goto statement.
A goto statement must be specified in the same functional region as the destination <Label> of the statement. A functional region includes the following:
-
A program block
-
A function body
-
The program global scope (if no program block is specified)
For more information about the program block, refer to the User-Defined Functions section.
A goto statement may be defined either before or after the <Label> to which it is referring. The following example shows a case where a label is defined before the goto statement that references it.
G1X10
Dwell(0.5)
goto myLabel
The example that follows shows a case where a label is defined after the goto statement that references it.
goto skipDwell
end
Dwell(0.5)
skipDwell:
G1X10
One instance where the goto statement can be useful is breaking out of deeply-nested loops.
var $num as integer = 0
for $i = 0 to 9
for $j = 0 to 9
for $k = 0 to 9
if ($rglobal[($i * 100) + ($j * 10) + $k] < 0.0)
goto found
else
$num++
end
end
end
end
found:
The goto statement cannot be used to transfer control into constructs that require initialization:
-
The body of a repeat loop
-
The body of a for loop
-
The body of a foreach loop
-
The body of a function
The reason that goto statements cannot be used to transfer control into the listed loops is because the initialization of the loops would not be performed, causing the program to behave incorrectly. For example, using a goto statement to transfer control to the body of a for loop would cause the for loop counter variable to be uninitialized.
As an example, the following usage of a goto statement will cause an error during compilation because the code execution would branch over the initialization of the repeat loop.
repeat 10
myLabel:
Dwell(0.01)
end
While the goto statement cannot be used to enter certain regions of code, it may still be used to exit those regions. For example, a goto statement may be used to exit a repeat loop.
In addition, the goto statement cannot be used to transfer control past the initialization of a variable because the value of a variable cannot be determined. As an example, the following usage of a goto statement will cause an error during compilation.
var $myVar as integer = 3
myLabel:
$myVar++
The use of the goto statement is generally discouraged as its use can make programs difficult to read or debug. In many cases, the use of a goto statement can be replaced with a proper while, for, or foreach loop.
Break Statement
Break statements allow for a control flow loop (while, for, foreach, or repeat) to be immediately terminated. The syntax for the break statement is as follows.
The break statement is used to break out of the nearest containing loop. The break statement cannot be used outside of a while, for, foreach, or repeat loop.
while ($cnt > 10)
$cnt--
if ($iVal == 0)
// Break out of the while loop
break
end
end
end
Continue Statement
The continue statement allows for control flow to jump to the beginning of a control flow loop (while, for, foreach, or repeat) to start executing its next iteration, skipping any code remaining in the loop for the current iteration. The syntax for the continue statement is as follows.
The continue statement is used to branch to the beginning of the nearest containing loop. The continue statement cannot be used outside of a while, for, foreach, or repeat loop.
for $index = 0 to 31
if ($index == $skipIndex)
// Skip setting the 10th index
continue
end
$rglobal[$index] = $index
end
Return Statement
The return statement allows for control flow to exit the current function, returning a value (if specified) to its caller. If the control of execution is within a program block, or is at the program global scope, then a return statement will cause the program to end.
The following are the various syntax permutations for the return statement.
return <Value>
The return syntax without a <Value> argument should be used to return early from a function that does not return a value.
if ($value < 0.0)
// Return from the function early to prevent the value from being
// Set if it is negative
return
end
$rglobal[0] = $value
end
A return statement without a return value can also be specified in a program block, or at the program global scope (if no program block was defined) in order to stop the execution of a program before execution reaches the end. A value cannot be specified to a return statement in these cases.
The return <Value> syntax should be used to return a value from a function that returns a value. The value returned from a function must match (or be convertible to) the data type of the function return value.
// This is valid because the function returns an integer
return 123
end
// This is not valid because the function does not return a value
return 123
end
// This is not valid because the function has a return with the integer
// data type, but a string is being returned
return "Hello"
end
Wait Statement
The wait statement is used to wait for a specified condition to evaluate as true before continuing program execution. The syntax for the wait statement is as follows.
<return> = wait(<Condition>, <Timeout>)
The program will wait on the wait statement program line forever until the specified <Condition> evaluates as true.
wait($iglobal[0] == 1)
An optional <Timeout> value, in milliseconds, may be specified. If the <Condition> continues to evaluate as false for longer than the <Timeout> duration, then the wait statement will return a value of 1. If the <Condition> evaluates as true before the <Timeout> duration, then the wait statement will return a value of 0. The return value may be ignored.
// more than 2 seconds (2000 milliseconds)
$timedOut = wait($signalVar == 1, 2000)
// The return value of a wait statement may be ignored if the timeout
// status is not useful
wait($signalVar == 0, 150)
// Specifying a value of "false" for the conditional allows a wait
// statement to be used to delay program execution for the specified
// timeout
wait(false, 1000)
The wait statement is syntactic sugar, or syntax that makes it easier to express an idea using the language. The following two examples have the same behavior, but the wait statement allows for the code to be expressed more concisely.
var $timedOut as integer = false
CriticalSectionStart()
$timeout = 100
while (StatusGetAxisItem(X, AxisStatusItem.VelocityCommand) != 0.0)
$timeout--
if ($timeout == 0)
$timedOut = true
break
end
Dwell(0.001)
end
CriticalSectionEnd()
if ($timedOut == 1)
AppMessageDisplay("A timeout occurred.")
end
$timedOut = wait(StatusGetAxisItem(X, AxisStatusItem.VelocityCommand) == 0, 100)
if ($timedOut == 1)
AppMessageDisplay("A timeout occurred.")
end
OnError Statement
The onerror statement causes the specified function to be executed when a task error occurs during program execution. The syntax of an onerror statement that sets an error handling function is as follows.
An onerror statement can be specified without a function to clear any active onerror handler. The syntax for clearing an onerror handler is as follows.
If an onerror handler is active and a task error occurs while a program is active (in either the running, paused, or feedheld states), program execution will immediately branch to the function specified by the <FunctionName> when the onerror statement was specified. The function specified by the <FunctionName> must not accept any arguments, nor may it return a value.
// Configure the onerror handler to call the ErrorHandler() function if
// an error occurs
onerror(ErrorHandler())
// Any errors that occur here will cause the ErrorHandler() function to
// be executed automatically
Enable([X, Y, Z])
Home([X, Y, Z])
MoveLinear([X, Y], [10, 20])
// Disable the active onerror handler
onerror()
end
function ErrorHandler()
// Clear errors and start the program again
AcknowledgeAll()
ProgramRestart()
end
Errors can be handled within the called function and then the programmer can decide whether to restart program execution or end the program. If the error condition is not cleared within the function, or a new error condition occurs within the function, then the program will terminate.
Next Topic: Functions