159 lines
3.5 KiB
Markdown
159 lines
3.5 KiB
Markdown
---
|
|
Title: YREA SLS | 6 Control Flow
|
|
Prev: Functions
|
|
Next: Data Structures
|
|
---
|
|
|
|
## 6. Control Flow
|
|
|
|
### 6.1 Conditionals
|
|
|
|
**Syntax**: `condition { then-block } { else-block } if`
|
|
|
|
The condition is evaluated first, then both code blocks are provided, followed by the `if` operator which chooses which block to execute.
|
|
|
|
**Examples**:
|
|
```
|
|
// if-then (else block is empty)
|
|
x 0 > { "positive" print } { } if
|
|
|
|
// if-then-else
|
|
x 0 >
|
|
{ "positive" print }
|
|
{ "non-positive" print }
|
|
if
|
|
|
|
// Returning values
|
|
a b >
|
|
{ a }
|
|
{ b }
|
|
if // Pushes the maximum of a and b
|
|
|
|
// Nested conditionals
|
|
x 0 >
|
|
{
|
|
y 0 >
|
|
{ "both positive" print }
|
|
{ "x positive, y not" print }
|
|
if
|
|
}
|
|
{ "x not positive" print }
|
|
if
|
|
```
|
|
|
|
**Important**: The `if` operator parses both TokenStrings as code blocks. The condition must produce a boolean value (or truthy value) before the `if` operator.
|
|
|
|
### 6.2 While Loops
|
|
|
|
**Syntax**: `{ condition-block } { body-block } while`
|
|
|
|
The while loop repeatedly evaluates the condition block and executes the body block as long as the condition is truthy.
|
|
|
|
**Examples**:
|
|
```
|
|
// Sum 1 to 10
|
|
0 1 // sum counter
|
|
{ dup 10 <= } // condition block
|
|
{ // body block
|
|
over over + // Add counter to sum
|
|
swap 1 + swap // Increment counter
|
|
}
|
|
while
|
|
drop // Drop counter, leave sum
|
|
|
|
// Infinite loop with break
|
|
{ true } {
|
|
// body
|
|
condition { break } { } if
|
|
} while
|
|
```
|
|
|
|
**Condition Evaluation**: The condition block is re-evaluated before each iteration. It should leave a boolean (or truthy) value on the stack.
|
|
|
|
### 6.3 For Loops
|
|
|
|
**Syntax**: `start end { body-with-counter } for`
|
|
|
|
The for loop iterates from `start` to `end` (inclusive), pushing the loop counter onto the stack for each iteration before executing the body.
|
|
|
|
**Examples**:
|
|
```
|
|
// Print 1 to 10
|
|
1 10 {
|
|
// Stack has loop counter on top
|
|
dup print
|
|
} for
|
|
|
|
// FizzBuzz
|
|
1 100 {
|
|
dup fizzbuzz
|
|
} for
|
|
|
|
// Accumulation
|
|
0 // accumulator
|
|
1 10 {
|
|
+ // add counter to accumulator
|
|
} for
|
|
// Result: 55 (sum of 1 to 10)
|
|
```
|
|
|
|
**Loop Counter**: The loop counter is automatically pushed onto the stack before each iteration. Your body block should consume it or clean it up.
|
|
|
|
### 6.4 Loop Control
|
|
|
|
```
|
|
break // Exit the current loop immediately
|
|
continue // Skip to the next iteration of the current loop
|
|
```
|
|
|
|
**Examples**:
|
|
```
|
|
// Break example
|
|
1 100 {
|
|
dup 50 ==
|
|
{ break }
|
|
{ dup print }
|
|
if
|
|
} for // Prints 1-49, stops at 50
|
|
|
|
// Continue example
|
|
1 10 {
|
|
dup 2 % 0 ==
|
|
{ continue }
|
|
{ dup print }
|
|
if
|
|
} for // Prints only odd numbers: 1 3 5 7 9
|
|
```
|
|
|
|
### 6.5 Pattern Matching
|
|
|
|
**Syntax**: `value { pattern => block ... } match`
|
|
|
|
Pattern matching allows you to test a value against multiple patterns and execute the corresponding block.
|
|
|
|
**Examples**:
|
|
```
|
|
// Option matching
|
|
opt_value {
|
|
Some(x) => { x print }
|
|
None => { "Nothing" print }
|
|
} match
|
|
|
|
// Multiple patterns
|
|
status {
|
|
Pending => { "Waiting" print }
|
|
Active => { "Running" print }
|
|
Complete => { "Done" print }
|
|
} match
|
|
|
|
// Result matching
|
|
result {
|
|
Ok(val) => { val process }
|
|
Err(e) => { e "Error: " swap concat print }
|
|
} match
|
|
```
|
|
|
|
**Pattern Syntax**: Patterns can match enum variants, union variants, or literal values. The matched value (if any) is bound and available in the corresponding block.
|
|
|
|
---
|