Welcome to the 50th post in this series!
Today, we’ll talk about a small syntax construction, which is nevertheless is quite complicated in terms of Grammar. Let us look at the whole colonpair token first:
token colonpair { :my $*key; :my $*value; ':' :dba('colon pair') [ | '!' [ <identifier> || <.panic: "Malformed False pair; expected identifier"> ] [ <[ \[ \( \< \{ ]> { $/.typed_panic('X::Syntax::NegatedPair', key => ~$<identifier>) } ]? { $*key := $<identifier>.Str; $*value := 0 } | $<num> = [\d+] <identifier> [ <?before <.[ \[ \( \< \{ ]>> {} <.sorry("Extra argument not allowed; pair already has argument of " ~ $<num>.Str)> <.circumfix> ]? <?{ . . . # Some NQP things happen here, refer to the code if needed }> { $*key := $<identifier>.Str; $*value := nqp::radix_I(10, $<num>, 0, 0, $*W.find_symbol(['Int']))[0]; } | <identifier> { $*key := $<identifier>.Str; } [ || <.unsp>? :dba('pair value') <coloncircumfix($*key)> { $*value := $<coloncircumfix>; } || { $*value := 1; } ] | :dba('signature') '(' ~ ')' <fakesignature> | <coloncircumfix('')> { $*key := ""; $*value := $<coloncircumfix>; } | <var=.colonpair_variable> { $*key := $<var><desigilname>.Str; $*value := $<var>; self.check_variable($*value); } ] }
The token always starts matching from a colon. Then, there are six main alternatives. Let us briefly come through the first half of them.
Each branch ends with assignments to the two dynamic variables: $*key and $*value.
1
The first variant is used when you want to pass a False value as a named parameter, for example:
sub f($x, :$print = 1) { say $x if $print; } f(3); # 3 f(4, :!print); # nothing
This function prints its first parameter if you do not set the :$print named argument to a False value. In Perl 6, this can be done using the shortcut :!print. Thus, in the second call, the function prints nothing.
2
The second branch of the token is for a special form of passing numeric values. Examine the following code snippet:
sub g(:$value) { say $value; } g(:10value); # 10
A function takes a named argument, and you can pass its value in a bit weird format: :10value, which means make the value of :$value equals 10.
3
The third option is probably the most common way to use colon syntax. This branch is triggered in the following example:
sub g(:$value) { say $value; } g(:value(10)); # 10
Here is the same function as in the previous section, but the value is passed differently.
This option is also used when you need somewhat opposite to the first one. In this case, you use the named argument as a Boolean flag and set its value to True. The next example demonstrates that:
sub h(:$value) { say $value; } h(:value); # True
Notice that this is False if you negate it with an exclamation mark (in that case, the first branch of the token works):
h(:!value); # False
2 thoughts on “🔬50. Colonpair in Perl 6’s Grammar, part 1”