Author: lwall
Date: 2009-01-27 18:43:18 +0100 (Tue, 27 Jan 2009)
New Revision: 25060

Modified:
   docs/Perl6/Spec/S03-operators.pod
   src/perl6/STD.pm
Log:
[STD] more operator hacking inspired by mtnviewmark++
[S03] added comparison-reversion metaoperator


Modified: docs/Perl6/Spec/S03-operators.pod
===================================================================
--- docs/Perl6/Spec/S03-operators.pod   2009-01-27 10:11:54 UTC (rev 25059)
+++ docs/Perl6/Spec/S03-operators.pod   2009-01-27 17:43:18 UTC (rev 25060)
@@ -12,9 +12,9 @@
 
   Maintainer: Larry Wall <la...@wall.org>
   Date: 8 Mar 2004
-  Last Modified: 24 Jan 2009
+  Last Modified: 27 Jan 2009
   Number: 3
-  Version: 149
+  Version: 150
 
 =head1 Overview
 
@@ -1472,7 +1472,7 @@
     $a < 1 && $b == 2 :carefully
 
 does the C<&&> carefully because C<&&> is of
-tighter precedence than "loose unary".  Use
+tighter precedence than "comma".  Use
 
     $a < 1 && ($b == 2 :carefully)
 
@@ -3400,7 +3400,7 @@
 operators yourself.  Similarly, the carets that exclude the endpoints
 on ranges are there by convention only.
 
-In contrast to that, Perl 6 has five standard metaoperators for
+In contrast to that, Perl 6 has six standard metaoperators for
 turning a given existing operator into a related operator that is
 more powerful (or at least differently powerful).  These differ from a
 mere naming convention in that Perl automatically generates these new
@@ -3483,8 +3483,9 @@
 
 =head2 Negated relational operators
 
-Any infix relational operator may be transformed into its negative
-by prefixing with C<!>.  A couple of these have traditional shortcuts:
+Any infix relational operator returning type C<Bool> may be transformed
+into its negative by prefixing with C<!>.  A couple of these have
+traditional shortcuts:
 
     Full form   Shortcut
     ---------   --------
@@ -3506,6 +3507,23 @@
 
 The precedence of any negated operator is the same as the base operator.
 
+Note that logical operators such as C<||> and C<^^> do not return a Bool,
+but rather one of the operands.
+
+=head2 Reversed comparison operators
+
+Any infix comparison operator returning type C<Order> may be transformed into 
its reversed sense
+by prefixing with C<->.
+
+    -cmp
+    -leg
+    -<=>
+
+To avoid confusion with the C<-=> operator, you may not modify
+any operator already beginning with C<=>.
+
+The precedence of any reversed operator is the same as the base operator.
+
 =head2 Hyper operators
 
 The Unicode characters C<»> (C<\x[BB]>) and C<«> (C<\x[AB]>) and

Modified: src/perl6/STD.pm
===================================================================
--- src/perl6/STD.pm    2009-01-27 10:11:54 UTC (rev 25059)
+++ src/perl6/STD.pm    2009-01-27 17:43:18 UTC (rev 25060)
@@ -150,7 +150,7 @@
     chars graphs codes bytes
 
     say print open close printf sprintf slurp unlink link symlink
-    elems grep map first reduce sort uniq push reverse take splice
+    elems grep map first reduce sort min max uniq push reverse take splice
     lines getc
 
     zip each roundrobin caller
@@ -233,7 +233,7 @@
 constant %junctive_or     = (:dba('junctive_or')     , :prec<p=>, 
:assoc<list>,  :assign);
 constant %named_unary     = (:dba('named_unary')     , :prec<o=>, 
:assoc<unary>, :uassoc<left>);
 constant %nonchaining     = (:dba('nonchaining')     , :prec<n=>, :assoc<non>);
-constant %chaining        = (:dba('chaining')        , :prec<m=>, 
:assoc<chain>, :bool);
+constant %chaining        = (:dba('chaining')        , :prec<m=>, 
:assoc<chain>, :returns<Bool>); # XXX Bool string, not type
 constant %tight_and       = (:dba('tight_and')       , :prec<l=>, 
:assoc<list>,  :assign);
 constant %tight_or        = (:dba('tight_or')        , :prec<k=>, 
:assoc<list>,  :assign);
 constant %conditional     = (:dba('conditional')     , :prec<j=>, 
:assoc<right>);
@@ -272,7 +272,7 @@
 
 } # end role
 
-class Hyper does PrecOp {
+class Transparent does PrecOp {
  our %o = (:transparent);
 } # end class
 
@@ -1031,6 +1031,7 @@
 }
 
 token infixish {
+    :my $infix;
     <!stdstopper>
     <!infixstopper>
     :dba('infix or meta-infix')
@@ -1050,7 +1051,7 @@
     | <infix_circumfix_meta_operator>
         { $<O> = $<infix_circumfix_meta_operator><O>;
           $<sym> = $<infix_circumfix_meta_operator><sym>; }
-    | <infix> <?before '='> <infix_postfix_meta_operator($<infix>)>
+    | <infix> <?before '='> <?{ $infix = $<infix>; }> 
<infix_postfix_meta_operator($infix)>
            { $<O> = $<infix_postfix_meta_operator>.<O>; $<sym> = 
$<infix_postfix_meta_operator>.<sym>; }
     ]
 }
@@ -1129,20 +1130,32 @@
 
 token postfix_prefix_meta_operator:sym< » >    { <sym> | '>>' }
 
-token infix_prefix_meta_operator:sym<!> ( --> Chaining) {
+token infix_prefix_meta_operator:sym<!> ( --> Transparent) {
     <sym> <!before '!'> <infix>
 
     <!!{ $<O> = $<infix><O>; }>
     <!!lex1: 'negation'>
 
     [
-    || <!!{ $<O><assoc> eq 'chain'}>
-    || <!!{ $<O><assoc> and $<O><bool> }>
-    || <.panic: "Only boolean infix operators may be negated">
+    || <!!{ ($<O><returns> // '') eq 'Bool' }>
+    || <.worry: "Only boolean infix operators may be negated"> <!>
     ]
 
     <!{ $<O><hyper> and $¢.panic("Negation of hyper operator not allowed") }>
+}
 
+token infix_prefix_meta_operator:sym<-> ( --> Transparent) {
+    <sym> <!before '='> <infix>
+
+    <!!{ $<O> = $<infix><O>; }>
+    <!!lex1: 'negation'>
+
+    [
+    || <!!{ ($<O><returns> // '') eq 'Order' }>
+    || <.worry: "Only comparison infix operators may be negated"> <!>
+    ]
+
+    <!{ $<O><hyper> and $¢.panic("Negation of hyper operator not allowed") }>
 }
 
 method lex1 (Str $s) {
@@ -1160,7 +1173,7 @@
     <!!lex1: 'cross'>
 }
 
-token infix_circumfix_meta_operator:sym<« »> ( --> Hyper) {
+token infix_circumfix_meta_operator:sym<« »> ( --> Transparent) {
     [
     | '«' <infix> [ '«' | '»' ]
     | '»' <infix> [ '«' | '»' ]
@@ -1176,8 +1189,9 @@
     { $<O> = $op<O>; }
     <?lex1: 'assignment'>
 
-    [ <?{ ($<O><assoc> // '') eq 'chain' }> <.panic: "Can't make assignment op 
of boolean operator"> ]?
+    [ <?{ ($<O><returns> // '') eq 'Bool' }> <.panic: "Can't make assignment 
op of boolean operator"> ]?
     [ <?{ ($<O><assoc> // '') eq 'non'   }> <.panic: "Can't make assignment op 
of non-associative operator"> ]?
+    [ <!{ $<O><assign> }> <.panic("Can't make assignment of " ~ $<O><dba> ~ " 
operator")> ]?
 }
 
 token postcircumfix:sym<( )> ( --> Methodcall)
@@ -3082,13 +3096,13 @@
 
 ## nonchaining binary
 token infix:sym« <=> » ( --> Nonchaining)
-    { <sym> }
+    { <sym> { $<O><returns> = "Order"; } }
 
 token infix:cmp ( --> Nonchaining)
-    { <sym> }
+    { <sym> { $<O><returns> = "Order"; } }
 
 token infix:leg ( --> Nonchaining)
-    { <sym> }
+    { <sym> { $<O><returns> = "Order"; } }
 
 token infix:but ( --> Nonchaining)
     { <sym> }

Reply via email to