10. Obsolete syntax error messages, part 2

Today, we continue exploring the error messages that Rakudo developers embedded to detect old Perl 5 constructions in the Perl 6 code.

The obs method

But first, let’s make a small experiment and add a call to the obs method in the rule parsing the for keyword.

rule statement_control:sym<for> {
    <sym><.kok> {}
    [ <?before 'my'? '$'\w+\s+'(' >
        <.obs('Hello', 'World!')> <.typed_panic: 'X::Syntax::P5'> ]?
    [ <?before '(' <.EXPR>? ';' <.EXPR>? ';' <.EXPR>? ')' >
        <.obs('C-style "for (;;)" loop', '"loop (;;)"')> ]?
    <xblock(1)>
}

The dot before the name of the method prevents creating a named element in the Match object. Actually, that is not that important as soon as the obs call generates an exception. In many other cases, the dot is very useful, of course.

Compile Rakudo and feed it with the erroneous Perl 6 code:

$ ./perl6 -e'for my $x (@a) {}'
===SORRY!=== Error while compiling -e
Unsupported use of Hello; in Perl 6 please use World!
at -e:1
------> for ⏏my $x (@a) {}

As you see, we’ve generated some rubbish message but the X::Syntax::P5 exception did not have a chance to appear, as the parsing stopped at the place the obs method was called.

No foreach anymore

Another error message appears when you try using the foreach keyword:

$ ./perl6 -e'foreach @a {}'
===SORRY!=== Error while compiling -e
Unsupported use of 'foreach'; in Perl 6 please use 'for'
at -e:1
------> foreach⏏ @a {}

Notice that the compiler stopped even before figuring out that the @a variable is not defined.

Here is the rule that finds the outdated keyword:

rule statement_control:sym<foreach> {
    <sym><.end_keyword> <.obs("'foreach'", "'for'")>
}

The end_keyword method is a token that matches the right edge of the keyword; this is not a method to report about the end of support of the keyword 🙂 You can see this method in many other rules in the grammar.

token end_keyword {
    » <!before <.[ \( \\ ' \- ]> || \h* '=>'>
}

No do anymore

Another potential mistake is creating the do blocks instead of the new repeat/while or repeat/until.

$ ./perl6 -e'do {} while 1'
===SORRY!=== Error while compiling -e
Unsupported use of do...while;
in Perl 6 please use repeat...while or repeat...until
at -e:1

This time, the logic for detecting the error is hidden deeply inside the statement token:

token statement($*LABEL = '') {
    . . .
    my $sp := $<EXPR><statement_prefix>;
    if $sp && $sp<sym> eq 'do' {
         my $s := $<statement_mod_loop><sym>;
         $/.obs("do..." ~ $s, "repeat...while or repeat...until");
    }
    . . .
}

The second symbol is taken from the $<statement_mod_loop><sym> value, so the error message contains the proper instruction for both do {} until and do {} for blocks.

Let’s stop here for today. We’ll examine more obsolete syntax in the next year. Meanwhile, I wish you all the best and success with using Perl 6 in 2018!