Raku Books / Creating a Compiler in Raku / Control Flow

Conditional operators

So far, the if test can only check if the value is zero or not. Let us make it more powerful and allow conditional and Boolean operators:

|  &  <  <=  >  >=  ==  !=

We are not going to introduce a Boolean data type, but instead we will add the operators to existing expressions. It makes 3 + n and x < y are both valid expressions, and they both can be used as a condition of the if test.

The above listed operators are binary operators and have precedence lower than arithmetic operators + and -. Among themselves, & has higher precedence. So, we have to update the op tokens in the grammar and add the new operators:

multi token op(1) {
    | '|'
    | '<' | '>'
    | '<=' | '>='
    | '==' | '!='
}

multi token op(2) {
    '&'
}

We also have to update the rest to explicitly give the precedence:

multi token op(3) {
    '+' | '-'
}

multi token op(4) {
    '*' | '/'
}

multi token op(5) {
    '**'
}

multi rule expr(6) {
    | <number>
    | <variable-name> <index>?
    | '(' <expression> ')'
}

Add the functions to the AST::MathOperations class:

multi sub operation('|', $a, $b) {
    $a || $b
}

multi sub operation('&', $a, $b) {
    $a && $b
}

multi sub operation('<', $a, $b) {
    $a < $b
}

multi sub operation('<=', $a, $b) {
    $a <= $b
}

multi sub operation('>', $a, $b) {
    $a > $b
}

multi sub operation('>=', $a, $b) {
    $a >= $b
}

multi sub operation('!=', $a, $b) {
    $a != $b
}

multi sub operation('==', $a, $b) {
    $a == $b
}

We rely on Raku’s operators here. Another alternative would be to only generate 1 or 0, for example:

multi sub operation('<', $a, $b) {
    $a < $b ?? 1 !! 0
}

In the test, try different operators and their combinations:

my x = 10;
my y = 20;

if x > y say ">" else say "<"; ## <
if x < y say ">" else say "<"; ## >

if x != y say "!=" else say "=="; ## !=
if x != x say "!=" else say "=="; ## ==

if x == y say "==" else say "!="; ## !=
if x == x say "==" else say "!="; ## ==

if 5 <= 5 say "5 <= 5"; ## 5 <= 5
if 5 <= 6 say "5 <= 6"; ## 5 <= 6

if 5 >= 5 say "5 >= 5"; ## 5 >= 5
if 6 >= 5 say "6 >= 5"; ## 6 >= 5

if (10 > 1) & (5 < 50) say "OK 1"; ## OK 1
if (10 < 1) | (5 < 50) say "OK 2"; ## OK 2

Course navigation

A real-life test   |   Implementing while