🔬22. The infix nature of the ternary operator in Perl 6

The ternary operator ?? !! takes three operands, obviously. Although, it is said in the documentation that the operator is an infix. Let us figure out why.

Here is the fragment from the Grammar that handles the ternary operator:

token infix:sym<?? !!> {
    :my $*GOAL := '!!';
    $<sym>='??'
    <.ws>
    <EXPR('i=')>
    [ '!!'
    || <?before '::' <.-[=]>> { self.typed_panic: "X::Syntax::ConditionalOperator::SecondPartInvalid", second-part => "::" }
    || <?before ':' <.-[=\w]>> { self.typed_panic: "X::Syntax::ConditionalOperator::SecondPartInvalid", second-part => ":" }
    || <infixish> { self.typed_panic: "X::Syntax::ConditionalOperator::PrecedenceTooLoose", operator => ~$<infixish> }
    || <?{ ~$<EXPR> ~~ / '!!' / }> { self.typed_panic: "X::Syntax::ConditionalOperator::SecondPartGobbled" }
    || <?before \N*? [\n\N*?]? '!!'> { self.typed_panic: "X::Syntax::Confused", reason => "Confused: Bogus code found before the !! of conditional operator" }
    || { self.typed_panic: "X::Syntax::Confused", reason => "Confused: Found ?? but no !!" }
    ]
    <O(|%conditional, :reducecheck<ternary>, :pasttype<if>)>
}

The most of the body is filled with different error reporting additions that pop up when something is wrong with the second part of the operator. Let us reduce the noise and implement the simplest form of our own artificial operator ¿¿ ¡¡ that does no such error checking:

token infix:sym<¿¿ ¡¡> {
    '¿¿'
    <.ws>
    <EXPR('i=')>
    '¡¡'
    <O(|%conditional, :reducecheck<ternary>, :pasttype<if>)>
}

Now you can clearly see the structure of the token. It matches the following components: a literal string '¿¿', an expression, and another string '¡¡'. We’ve already seen the use of the O token when we were talking about precedence.

If you consider ¿¿ ¡¡ as an infix operator  ($left ¿¿ $mid ¡¡ $right), then the first and the third operands of the ternary operator are, respectively, the left and the right operands of the combined operator. The code between ¿¿ and ¡¡ is caught by the <EXPR> rule.

Before wrapping up for today, let us print what the Grammar finds at that position:

token infix:sym<¿¿ ¡¡> {
    '¿¿'
    <.ws>
    <EXPR('i=')> {
        nqp::say('Inside we see: ' ~ $<EXPR>)
    }
    '¡¡'
    <O(|%conditional, :reducecheck<ternary>, :pasttype<if>)>
}

Compile and run:

$ ./perl6 -e'say 3 ¿¿ 4 ¡¡ 5'
Inside we see: 4 
4

It is quite difficult, though, to find the place where the actual logic of the ternary operator is defined. I would not even recommend doing that as homework 🙂 Nevertheless, come back tomorrow to see more details of the internals of the ternary operators.

One thought on “🔬22. The infix nature of the ternary operator in Perl 6

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s