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> }