From 2f19219e06a3d22a8a2939cac3ee7230ae798f27 Mon Sep 17 00:00:00 2001 From: Solomon Foster Date: Mon, 15 Mar 2010 21:17:10 -0400 Subject: [PATCH] Rough but working implementations of Xop and Zop. (Had to disable X and Z to make this work, alas, but I'm sure we'll work around that shortly.) --- src/Perl6/Actions.pm | 41 +++++++++++++++++++++++++++-------------- src/Perl6/Grammar.pm | 8 ++++---- src/core/metaops.pm | 22 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 src/core/metaops.pm diff --git a/src/Perl6/Actions.pm b/src/Perl6/Actions.pm index f76b6d359f3..3c05f69ad88 100644 --- a/src/Perl6/Actions.pm +++ b/src/Perl6/Actions.pm @@ -1917,23 +1917,36 @@ method infixish($/) { my $metaop := ~$; my $sym := ~$; my $opsub := "&infix:<$metaop$sym>"; - unless %*METAOPGEN{$opsub} { - if $metaop eq '!' { - @BLOCK[0].loadinit.push( - PAST::Op.new( :name('!gen_not_metaop'), $sym, - :pasttype('call') ) - ); + my $base_opsub := "&infix:<$sym>"; + if $metaop eq '!' || $metaop eq 'R' || $metaop eq 'S' { + unless %*METAOPGEN{$opsub} { + if $metaop eq '!' { + @BLOCK[0].loadinit.push( + PAST::Op.new( :name('!gen_not_metaop'), $sym, + :pasttype('call') ) + ); + } + if $metaop eq 'R' { + @BLOCK[0].loadinit.push( + PAST::Op.new( :name('!gen_reverse_metaop'), $sym, + :pasttype('call') ) + ); + } + + %*METAOPGEN{$opsub} := 1; } - if $metaop eq 'R' { - @BLOCK[0].loadinit.push( - PAST::Op.new( :name('!gen_reverse_metaop'), $sym, - :pasttype('call') ) - ); + make PAST::Op.new( :name($opsub), :pasttype('call') ); + } + else { + if $metaop eq 'X' { + make PAST::Op.new( :name("&crosswith"), :pasttype('call'), + PAST::Var.new( :name($base_opsub), :scope('package') ) ); + } + if $metaop eq 'Z' { + make PAST::Op.new( :name("&zipwith"), :pasttype('call'), + PAST::Var.new( :name($base_opsub), :scope('package') ) ); } - - %*METAOPGEN{$opsub} := 1; } - make PAST::Op.new( :name($opsub), :pasttype('call') ); } } diff --git a/src/Perl6/Grammar.pm b/src/Perl6/Grammar.pm index 241b8a45739..2492e2476db 100644 --- a/src/Perl6/Grammar.pm +++ b/src/Perl6/Grammar.pm @@ -1223,8 +1223,8 @@ token infix:sym { token infix_prefix_meta_operator:sym { } token infix_prefix_meta_operator:sym { } token infix_prefix_meta_operator:sym { } -token infix_prefix_meta_operator:sym { } -token infix_prefix_meta_operator:sym { } +token infix_prefix_meta_operator:sym { } +token infix_prefix_meta_operator:sym { } token infix:sym<:=> { ')> @@ -1255,8 +1255,8 @@ token prefix:sym { >> } token infix:sym<,> { } -token infix:sym { } -token infix:sym { } +# token infix:sym { } +# token infix:sym { } token infix:sym<...> { } # token term:sym<...> { ? } diff --git a/src/core/metaops.pm b/src/core/metaops.pm new file mode 100644 index 00000000000..9cb7ca46d66 --- /dev/null +++ b/src/core/metaops.pm @@ -0,0 +1,22 @@ +our multi sub zipwith(&op, Iterable $a-iterable, Iterable $b-iterable) { + my $ai = $a-iterable.iterator; + my $bi = $b-iterable.iterator; + gather loop { + my $a = $ai.get; + my $b = $bi.get; + last if ($a ~~ EMPTY) || ($b ~~ EMPTY); + take &op($a, $b); + } +} + +our multi sub crosswith(&op, Iterable $a-iterable, Iterable $b-iterable) { + my $ai = $a-iterable.iterator; + my @b = $b-iterable.Seq; + gather loop { + my $a = $ai.get; + last if ($a ~~ EMPTY); + for @b -> $b { + take &op($a, $b); + } + } +} \ No newline at end of file