Raku Books / Creating a Compiler in Raku / A Better Translator

Sophisticated expressions

The next step we can easily do is to merge the Calculator grammar into the language definition. Let’s rename an existing value method to number, and the language grammar will use the value that was defined in Calculator.

grammar Lingua {
    . . .

    rule value {
        | <number>
        | '(' <expression> ')'
    }

    rule expression {
        <term>* %% <op1>
    }

    token number {
        <sign>? [
            | <integer>
            | <floating-point>
        ] <exponent>?
    }

   . . .
}

The expression rule here is the former TOP rule of the Calculator grammar. Update the actions class symmetrically:

class LinguaActions {
    . . .

    method value($/) {
        $/.make($<number> ??
            $<number>.made !! $<exression>.made);
    }

    method expression($/) {
        $/.make(process($<term>, $<op1>));
    }

    method number($/) {
        $/.make(+$/);
    }
}

After this, any number in the program can be presented by an expression of arbitrary complexity. The only place in our current grammar where a number was used is assignment. We can replace the right-hand side of it to the expression.

In the grammar:

rule assignment {
    <variable-name> '=' <expression>
}

In the actions class:

method assignment($/) {
    %var{~$<variable-name>} = $<expression>.made;
}

method value($/) {
    $/.make($<number> ??
        $<number>.made !! $<expression>.made);
}

Change the test program and include a few expressions there. Here is my example:

my pi;
pi = 22/7 - 0.001265; # very rough approximation
say pi;

my x;
x = 2 * (3 + 4);
say x; # prints 14

Don’t forget that we can also use comments in the code!

Course navigation

Sophisticated numbers   |   Using variables