Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
First cut at zip and cross operators and metaoperators.
  • Loading branch information
pmichaud committed Jul 1, 2011
1 parent e366355 commit 457b5e7
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 4 deletions.
15 changes: 14 additions & 1 deletion src/Perl6/Actions.pm
Expand Up @@ -2111,7 +2111,20 @@ class Perl6::Actions is HLL::Actions {
make $past;
}

method semiarglist($/) { make $<arglist>.ast; }
method semiarglist($/) {
if +$<arglist> == 1 {
make $<arglist>[0].ast;
}
else {
my $past := PAST::Op.new( :pasttype('call'), :node($/) );
for $<arglist> {
my $ast := $_.ast;
$ast.name('&infix:<,>');
$past.push($ast);
}
make $past;
}
}

method arglist($/) {
# Build up argument list, hanlding nameds and flattens
Expand Down
3 changes: 2 additions & 1 deletion src/Perl6/Grammar.pm
Expand Up @@ -1449,7 +1449,8 @@ grammar Perl6::Grammar is HLL::Grammar {
}

token semiarglist {
<arglist>
<arglist> ** ';'
<.ws>
}

token arglist {
Expand Down
74 changes: 74 additions & 0 deletions src/core/LoL.pm
@@ -0,0 +1,74 @@
class LoL {
# declared in BOOTSTRAP:
# is List; # parent class

method new(|$) {
my Mu $args := pir::perl6_current_args_rpa__P();
nqp::shift($args);
nqp::p6list($args, self.WHAT, Mu);
}

method at_pos($pos is copy) {
$pos = $pos.Int;
self.exists($pos)
?? pir::find_method__PPs(List, 'at_pos')(self, $pos)
!! pir::setattribute__0PPsP(my $v, Scalar, '$!whence',
-> { pir::find_method__PPs(List, 'STORE_AT_POS')(self, $pos, $v) } )
}

multi method perl(LoL:D \$self:) {
self.WHAT.perl ~ '.new(' ~ self.map({.perl}).join(', ') ~ ')'
~ ('.item' if nqp::iscont($self));
}

method REIFY(Parcel \$parcel) {
my Mu $rpa := nqp::getattr($parcel, Parcel, '$!storage');
my Mu $iter := nqp::iterator($rpa);
my $i = 0;
while $iter {
nqp::bindpos($rpa, nqp::unbox_i($i++), my $v = nqp::shift($iter));
}
pir::find_method__PPs(List, 'REIFY')(self, $parcel)
}

method STORE_AT_POS(\$pos, Mu $v is copy) {
pir::find_method__PPs(List, 'STORE_AT_POS')(self, $pos, $v);
}

}


sub infix:<X>(**@lol) {
my @l;
my @v;
@l[0] = (@lol[0].flat,).list;
my $i = 0;
my $n = @lol.elems - 1;
gather {
while $i >= 0 {
if @l[$i] {
@v[$i] = @l[$i].shift;
if $i >= $n { my @x = @v; take @x.Parcel }
else {
$i++;
@l[$i] = (@lol[$i].flat,).list;
}
}
else { $i--; }
}
}
};

sub infix:<Z>(**@lol) {
my @l = @lol.map({ (.flat,).list.item });
gather {
my $loop = 1;
while $loop {
my $p := @l.map({ $loop = 0 unless $_; .shift }).eager.Parcel;
take $p if $loop;
}
}
}

my &zip := &infix:<Z>;

4 changes: 4 additions & 0 deletions src/core/Parcel.pm
Expand Up @@ -16,6 +16,10 @@ my class Parcel does Positional {
nqp::p6list(nqp::clone($!storage), List, Mu)
}

method lol() {
nqp::p6list(nqp::clone($!storage), LoL, Mu)
}

method at_pos(Parcel:D: \$x) { self.flat.at_pos($x); }

multi method postcircumfix:<[ ]>(Parcel:D: \$x) { self.flat.[$x] }
Expand Down
34 changes: 32 additions & 2 deletions src/core/metaops.pm
Expand Up @@ -12,11 +12,41 @@ sub METAOP_REVERSE(\$op) {
}

sub METAOP_CROSS(\$op) {
fail "X metaoperator NYI";
-> **@lol {
my $rop = METAOP_REDUCE($op);
my @l;
my @v;
@l[0] = (@lol[0].flat,).list;
my $i = 0;
my $n = @lol.elems - 1;
gather {
while $i >= 0 {
if @l[$i] {
@v[$i] = @l[$i].shift;
if $i >= $n { my @x = @v; take $rop(|@x); }
else {
$i++;
@l[$i] = (@lol[$i].flat,).list;
}
}
else { $i--; }
}
}
}
}

sub METAOP_ZIP(\$op) {
fail "Z metaoperator NYI";
-> **@lol {
my $rop = METAOP_REDUCE($op);
my @l = @lol.map({ (.flat,).list.item });
gather {
my $loop = 1;
while $loop {
my @z = @l.map({ $loop = 0 unless $_; .shift });
take $rop(|@z) if $loop;
}
}
}
}

sub METAOP_REDUCE(\$op, :$triangle) {
Expand Down
1 change: 1 addition & 0 deletions tools/build/Makefile.in
Expand Up @@ -145,6 +145,7 @@ CORE_SOURCES = \
src/core/MapIter.pm \
src/core/GatherIter.pm \
src/core/List.pm \
src/core/LoL.pm \
src/core/Array.pm \
src/core/Range.pm \
src/core/Enum.pm \
Expand Down

0 comments on commit 457b5e7

Please sign in to comment.