I want to reuse the token parameter
from Perl6::Grammar in my custom slang to add a "custom-param" parameter without cargo culting.
What I mean:
my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');
role Nogil::NogilGrammar {
token parameter { # the new one
"custom-param" || < here the token stolen from $main-grammar.^find_method('parameter'); >
}
my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
my $actions = $main-actions.^mixin(Nogil::NogilActions);
$*LANG.define_slang('MAIN', $grammar, $actions);
Not sure it is clear: it is like calling the parent token in a token of a role. I know the role will overwrite it so I kept a backup of pristine object in $grammar
.
Already tested:
P6opaque: no such attribute '$!pos' on type NQPMatch in a Scalar when trying to get a value
Attempt to return outside of immediately-enclosing Routine (i.e. `return` execution is outside the dynamic scope of the Routine where `return` was used)
Intro: After many similar errors with nqp, I figured out:
Brief: nqp
+ Scalar
in error message -> replace =
by :=
Explain: Use the bind operator := and not assignment = which autobox in a Scalar hence the error message with Scalar.
Demo: A fully working example (use in BEGIN phaser). Trying "my" €
sigil and "their" (compile in the language) in case mine fails.
my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');
role Nogil::NogilGrammar {
method sigil {
# Bind
my $sigil-they := $main-grammar.^find_method('sigil');
my $sigil-me := self.sigil-eu;
# Check My
return $sigil-me if $sigil-me;
# Return Their
return $sigil-they(self);
}
token sigil-eu { '€' }
}
my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
$*LANG.define_slang('MAIN', $grammar, $main-actions);
Note1: I removed some say
essential for the demo. Just add .Str
to those exoteric objects (NQPMatches).
Note2: If you want to create temporary variables (like $res
), keep binding (:=
).