Conditional Statements

There are two kinds of conditional statement in Rox, the if statement and the match statement.

The if statement

Consider this example.

if val < 16 {
    .a = 12;
} else if some_condition {
    // x is local to the some_condition block
    x = 12;
    .a = x + 3;
} else {
    .a = 15;
}
// a can be used here.
b = a;

The condition expressions val < 16 and some_condition must be of type bit. In the case of val < 16 we know that this constraint is satisfied, as all relational operators yield a bit result.

To set a outside the conditional statement, we write .a inside the conditional statement. If we do not use the . symbol, the value will not be propagated out of the conditional block. In the example above, x is local to the some_condition block as it is not preceded by the . symbol.

If we set an external value like .a in one of the branches, we must set it in all of the possible branches. This means that we need to include a final else block which is guaranteed to take effect if none of the if conditions are true.

The match statement

Consider this example.

match sel {
    0 => { .a = 1; }
    1, 3 => { .a = 2; }
    2 => { .a = 4; }
} else {
    .a = 0;
}

The selector sel is matched against the possible values inside the block. Multiple comma-separated values can be used for a branch; in the second branch above, two values 1 and 3 are matched against sel. Like if statements, any external value must be set in all possible branches, and an else block is required to handle the case when no matches are found.

When the matches are exhaustive, that is, all the possible values of the selector are listed inside the match statement, the else block is not required. In the example below, the else block is not required.

// u can be 0, 1, 2 or 3 only.
u = i as unsigned(2);
match u {
    0 => { .a = 1; }
    1 => { .a = 9; }
    2 => { .a = 81; }
    3 => { .a = 243; }
}
// no else required

Mixing if and match

The if and match statements can be mixed together in one statement.

if some_value < 4 {
    .a = 0;
} else match sel {
    4 => { .a = 1; }
    5 => { .a = 3; }
    6 => { .a = 12; }
} else if sel < 16 {
    .a = 20;
} else {
    .a = 30;
}

The exhausitve match check is performed across different match blocks, so that an else block is not required here:

// u can be 0, 1, 2 or 3 only.
u = i as unsigned(2);
match u {
    0 => { .a = 1; }
    1 => { .a = 9; }
} else if some_condition {
    .a = 0;
} else match u {
    2 => { .a = 81; }
    3 => { .a = 243; }
}
// no else required