Control flow decides which code runs and how many times it runs.
Expr supports:
Control-flow blocks are useful in calculations, probing logic, ATC scripts, custom dialogs, G-code-callable scripts, and automation workflows.
A block is a group of statements inside braces.
{ a = 10; b = 20; a + b; };
The final value of this block is `30`.
Blocks are commonly used with `if`, `loop`, `while`, and `for`.
Use `if` to run code only when a condition is true.
toolLoaded = true; if(toolLoaded) { 'Tool is loaded'; };
The condition must be inside parentheses.
if(condition) { // code here };
The semicolon after the block is important when the `if` is used as a statement.
Use `else` when you need one result if the condition is true and another result if it is false.
probeReady = false; if(probeReady) { 'Ready'; } else { 'Not ready'; };
The final value is `'Not ready'`.
Use `else if` when you need to test several conditions in order.
probeError = 0.03; probeStatus = if(probeError <= 0.01) { 'excellent'; } else if(probeError <= 0.05) { 'acceptable'; } else if(probeError <= 0.10) { 'warning'; } else { 'failed'; }; probeStatus;
The final value is `'acceptable'`.
Expr does not need a separate `elseif` keyword. This is an `else` branch that contains another `if`.
The conditions are checked from top to bottom. The first matching block runs, and the rest are skipped. In this example, once `probeError ⇐ 0.05` is true, the later checks are not evaluated.
Use `else if` for short decision chains where each condition is easy to read. For larger logic, consider using functions or clearer separate checks.
An `if` block can produce a value and that value can be assigned to a variable.
toolLoaded = true; message = if(toolLoaded) { 'Tool loaded'; } else { 'No tool'; }; message;
The final value is `'Tool loaded'`.
This is useful when you want to choose a value based on a condition.
If an `if` condition is false and there is no `else`, the result is `none()`.
a = if(false) { 10; };
In this case the `if` produces `none()`.
Be careful when using an `if` without `else` inside a larger expression.
value = 5 + if(false) { 10; };
This fails because `none()` cannot be added to a number.
When you need a value, provide an `else` branch.
value = 5 + if(false) { 10; } else { 0; };
The final value of `value` is `5`.
You can put one `if` inside another.
toolLoaded = true; probeReady = false; if(toolLoaded) { if(probeReady) { 'Ready to probe'; } else { 'Probe not ready'; }; } else { 'Load tool first'; };
Nested logic can become hard to read. If the condition is simple, logical operators may be clearer.
canProbe = toolLoaded && probeReady;
Use `loop` when you want to repeat code a fixed number of times.
count = 0; loop(5) { count += 1; }; count;
The final value is `5`.
The loop count is evaluated once before the loop starts.
repeats = 3; count = 0; loop(repeats) { count += 1; }; count;
The final value is `3`.
If the count is zero or negative, the loop body does not run.
Use `while` when you want to repeat code while a condition remains true.
a = 1; while(a < 10) { a = a * 2; }; a;
The final value is `16`.
The condition is checked before each iteration.
A `while` loop must eventually make its condition false. Otherwise, the script would run forever. Expr has safety limits, but your script should still be written so the loop can finish normally.
Use `for` for counter-style loops.
sum = 0; for(i = 0; i < 5; i += 1) { sum += i; }; sum;
The final value is `10` because the loop adds:
0 + 1 + 2 + 3 + 4
A `for` loop has three parts:
for(initialization; condition; iteration) { // code here };
Use `break` to exit the nearest loop.
count = 0; while(true) { count += 1; if(count >= 3) { break; }; }; count;
The final value is `3`.
`break` is useful when a loop should stop as soon as a condition is reached.
Use `continue` to skip the rest of the current loop iteration and move to the next one.
sum = 0; for(i = 0; i < 5; i += 1) { if(i == 2) { continue; }; sum += i; }; sum;
The final value is `8` because the loop adds:
0 + 1 + 3 + 4
The value `2` is skipped.
In a `for` loop, the iteration expression still runs after `continue`.
Use `loop` when the number of repetitions is known:
loop(10) { count += 1; };
Use `while` when the loop depends on a condition:
while(inputReady) { // wait or process };
Use `for` when you need a counter:
for(i = 0; i < 10; i += 1) { // use i };
Control-flow statements normally end with a semicolon.
if(a > 0) { 'positive'; };
This is especially important when another statement follows.
This loop does not change `a`, so it cannot finish normally:
a = 0; while(a < 10) { // a never changes };
Write loops so their condition can become false.
An `if` without `else` can produce `none()`.
a = 5 + if(false) { 1; };
Use an `else` branch when a numeric result is required.
Read this script and predict the final value:
result = 0; for(i = 1; i <= 5; i += 1) { if(i == 3) { continue; }; result += i; }; result;
The final value is `12` because the script adds `1 + 2 + 4 + 5`.
Next: Functions and methods