Eirik Berg Hanssen writes:
> Luke Palmer <[EMAIL PROTECTED]> writes:
> > You shouldn't parse the right hand side yourself.  That fixes the
> > issue.
> 
>   I was not aware of this option.  A6/E6 gave me the impression that
>   C<is parsed> would override the default parsing of the RHS, not
>   merely augment it.  Does the parsed-trait somehow interact with the
>   signature of the macro, to find out whether to extend or replace?

Hmm. 

For an ordinary list operator, we have a rule something like this:

    rule listop() {:w
        <listop_id>
        [ <parglist> | <arglist> ]
    }

I can imagine that, in the presence of C<is parsed>, it look more like:

    rule listop() {:w
        <listop_id>
        <{ $listop_id.parsed // /<parglist> | <arglist>/ }>
    }

This isn't a problem, as it's a rule tail-call.  

Now let's look at how operators might be done.  It's possible to store
precedence in a linked list of collections of operators, so:

    sub infix:+ ()                       {...}   # Default
    sub infix:* ()  is tighter(&infix:+) {...}
    sub infix:/ ()  is same(&infix:*)    {...}
    sub infix:** () is tighter(&infix:*) {...}
    sub infix:== () is looser(&infix:+)  {...}

Makes the list:

    /==/ -> /\+/ -> /* | \// -> /\*\*/

Associativity would be stored in the list frames, too.

If you're doing bottom up parsing, this is a terrible way to do things
for efficiency reasons.  But it's quite nice for top down.

    rule infixop($prec) {<{
        given $prec.assoc {
            when 'left' {    # Let's just pretend left recursion is possible
                /:w <infixop($prec)> <$prec.ops> <infixop($prec.next)> /
            }
            when 'right' {
                /:w <infixop($prec.next)> <$prec.ops> <infixop($prec)> /
            }
            when 'non' {
                /:w <infixop($prec.next)> <$prec.ops> <infixop($prec.next)> /
            }
        }
    } | <infixop($prec.next)>
    }

Among this list also lives the prefixes and postfixes, complicating
these rules somewhat.  We'll ignore these for now.

Now you can see that allowing an C<is parsed> rule on operators to grab
the rhs would screw up its precedence, unless the programmer could
explicitly call C<< <infixop($prec.next)> >>.  That can be done to some
extent with your speculatively_equiv property, but still one must take
great care to keep from making a mess of the parse tree.

>   That is, can I write prefix:-macros that do not take the default RHS
>   parameters, but only the ones generated by C<is parsed>?  Quotelike
>   operators come to mind:
> 
> macro prefix:qtex ($raw)
>       is parsed( /(<Perl6.delimited_balanced .*?>)/ ) { ... }
> 
>   Or would that be accomplished by another keyword, indicating what,
>   in the absence of C<is parsed>, would be 0-ary?  term:qtex, perhaps?

Yeah.  Or circumfix:, but that doesn't work for custom quoting
operators.  term: would be pretty nice for custom parsing rules,
actually.

>   I guess that depends upon what kind of consistency you are aiming
>   for.
> 
> 
> > Do you I<want> to give me a heart attack? :-/
> 
>   Nope.  I will try to restrain myself.
> 
> > This would be fine, I think:
> > 
> >     sub eqn ($n) { &String::strncmp.assuming(n => $n) }
> 
>   You mean it would be fine for using with the infix:[ macro, right?
> But then you could not get the precedence you want.  You would be
> stuck with whatever precedence infix:[ was given.

Yeah, that's true.  But note that you can't do that black magic you were
speaking of earlier:

    $a [ (cond ?? &infix:+ : &infix:*) but tighter(&infix:*) ] $b

Because we can't choose the precedence of an operator after we parse
it... unless we're doing bottom up, which we're not.  I do think that
the infix [] construct would have to have a fixed precedence.

Luke

Reply via email to