See below for the S06 section I'm referring to.

I'm wondering how we should be reading the description of user-defined
operators. For example, "sub infix:<(c)>" doesn't describe
the precedence level of this new op, so how is it parsed? Is there a
default?

Right now, this doesn't work as I'd expect in Rakudo for all categories. For
example:

$ ./perl6 -e 'sub infix:<i> ($a,$b) { return $a+($b*1i); } ; say 3 i 2'
3 + 2i

Correct.

$ ./perl6 -e 'sub term:<i> () { return 1i; } ; say i'
error:imcc:syntax error, unexpected '\n'
in file 'EVAL_1' line 105914178

Eh? What newline? And line 105914178?

OK, so that's a bug, but the question is, should I expect it to work?

Things get a bit more strange when I try to wrap my head around macros. From
the example:

    macro circumfix:«<!-- -->» ($text) is parsed / .*? / { "" }
OK, so when a circumfix would be allowed (any expression?) we accept <<!--
-->> and the result is an empty string which is... now, follow me here,
'cause I get lost myself... re-parsed within the context of what we've
already parsed, and its resulting AST is then returned as if via "make".

But doesn't that mean that in order to chain two comments, I would need
something to join the new null expressions, e.g.:

  <!-- --> ; <!-- -->

In a way, I'd find that comforting. It's not as useful for creating comments
as I'd have wanted, but at least it behaves like any other circumfix:
category operator.

Along the lines of macros, am I correct in my assumption that a macro will
either exist within a grammatical category that it names, or will be
evaluated as an expression, just like a subroutine invocation? That is,
there will be no way to do something like:

 macro endofline() { ";" }

since there's no way to change the state of the parser that invoked the
macro, other than to return an AST.

I think there's also a bug in the examples when it comes to ±. That can be a
method, sure, that makes sense, but in which case I don't think it should be
taking a parameter. Wouldn't that be:

    method prefix:<±> (--> Num) { return +self.myintvalue | -self.myintvalue
}

So that it would be used like so:

  my $x = MyInt.new(:myintvalue(5));
  say ±$x;

which I would expect to yield:

  any(5, -5)


>From S06:

------------

Operators are just subroutines with special names and scoping. An operator
name consists of a grammatical category name followed by a single colon
followed by an operator name specified as if it were a one or more strings.
So any of these indicates the same binary addition operator:

    infix:<+>
    infix:«+»
    infix:<<+>>
    infix:['+']
    infix:["+"]

This seems to imply that we can define our own operators.

Use the & sigil just as you would on ordinary subs.

Unary operators are defined as prefix or postfix:

    sub prefix:<OPNAME>  ($operand) {...}
    sub postfix:<OPNAME> ($operand) {...}

 Binary operators are defined as infix:

    sub infix:<OPNAME> ($leftop, $rightop) {...}

   Bracketing operators are defined as circumfix where a term is expected or
postcircumfix where a postfix is expected. A two-element slice containing
the leading and trailing delimiters is the name of the operator.

    sub circumfix:<LEFTDELIM RIGHTDELIM> ($contents) {...}
    sub circumfix:['LEFTDELIM','RIGHTDELIM'] ($contents) {...}

      Contrary to Apocalypse 6, there is no longer any rule about splitting
an even number of characters. You must use a two-element slice. Such names
are canonicalized to a single form within the symbol table, so you must use
the canonical name if you wish to subscript the symbol table directly (as in
PKG::{'infix:<+>'}). Otherwise any form will do. (Symbolic references do not
count as direct subscripts since they go through a parsing process.) The
canonical form always uses angle brackets and a single space between slice
elements. The elements are escaped on brackets, so
PKG::circumfix:['<','>']is canonicalized to PKG::{'circumfix:<\<
\>>'}, and decanonicalizing may always be done left-to-right.

Operator names can be any sequence of non-whitespace characters including
Unicode characters. For example:

    sub infix:<(c)> ($text, $owner) { return $text but Copyright($owner) }
    method prefix:<±> (Num $x --> Num) { return +$x | -$x }
    multi sub postfix:<!> (Int $n) { $n < 2 ?? 1 !! $n*($n-1)! }
    macro circumfix:«<!-- -->» ($text) is parsed / .*? / { "" }

     my $document = $text (c) $me;

     my $tolerance = ±7!;

     <!-- This is now a comment -->

  Whitespace may never be part of the name (except as separator within a
<...> or «...» slice subscript, as in the example above).

A null operator name does not define a null or whitespace operator, but a
default matching subrule for that syntactic category, which is useful when
there is no fixed string that can be recognized, such as tokens beginning
with digits. Such an operator *must* supply an is parsed trait. The Perl
grammar uses a default subrule for the :1st, :2nd, :3rd, etc. regex
modifiers, something like this:

    sub regex_mod_external:<> ($x) is parsed(token { \d+[st|nd|rd|th] }) {...}

  Such default rules are attempted in the order declared. (They always
follow any rules with a known prefix, by the longest-token-first rule.)

Although the name of an operator can be installed into any package or
lexical namespace, the syntactic effects of an operator declaration are
always lexically scoped. Operators other than the standard ones should not
be installed into the * namespace. Always use exportation to make
non-standard syntax available to other scopes.

-- 
Aaron Sherman
Email or GTalk: a...@ajs.com
http://www.ajs.com/~ajs

Reply via email to