Permalink
Browse files

Implement (hidden) :SINK attribute on slices

The idea being that te optimizer will add this when it sees a :delete being done
in sink context.
  • Loading branch information...
1 parent 0bf3de5 commit 02af63a3110f893fe57e85754bc807d3d67176d6 @lizmat lizmat committed Dec 12, 2013
Showing with 42 additions and 5 deletions.
  1. +12 −5 src/core/Any.pm
  2. +18 −0 src/core/array_slice.pm
  3. +12 −0 src/core/hash_slice.pm
View
@@ -420,11 +420,13 @@ sub SLICE_ONE ( \SELF, $one, $array, *%adv ) is hidden_from_backtrace {
my %a = %adv.clone;
my @nogo;
+ my $SINK = %a.delete_key('SINK');
my $return = do {
+
if %a.delete_key('delete') { # :delete:*
my $de = SELF.can( $array ?? 'delete_pos' !! 'delete_key' )[0];
- if !%a { # :delete
+ if !%a { # :delete / :delete:SINK
$de(SELF,$one);
}
elsif %a.exists_key('exists') { # :delete:exists(0|1):*
@@ -592,7 +594,7 @@ sub SLICE_ONE ( \SELF, $one, $array, *%adv ) is hidden_from_backtrace {
@nogo || %a
?? SLICE_HUH( SELF, @nogo, %a, %adv )
- !! $return;
+ !! ($SINK ?? Nil !! $return);
} #SLICE_ONE
# internal >1 element hash/array access with adverbs
@@ -602,11 +604,16 @@ sub SLICE_MORE ( \SELF, $more, $array, *%adv ) is hidden_from_backtrace {
my $at = SELF.can( $array ?? 'at_pos' !! 'at_key' )[0];
my $ex = SELF.can( $array ?? 'exists_pos' !! 'exists_key' )[0];
+ my $SINK = %a.delete_key('SINK');
+
+ my $return = do {
- my $return = do {
if %a.delete_key('delete') { # :delete:*
my $de = SELF.can( $array ?? 'delete_pos' !! 'delete_key' )[0];
- if !%a { # :delete
+ if $SINK { # :delete:SINK
+ $de(SELF,$_) for $more;
+ }
+ elsif !%a { # :delete
$more.list.map( { $de(SELF,$_) } ).eager.Parcel;
}
elsif %a.exists_key('exists') { # :delete:exists(0|1):*
@@ -816,5 +823,5 @@ sub SLICE_MORE ( \SELF, $more, $array, *%adv ) is hidden_from_backtrace {
@nogo || %a
?? SLICE_HUH( SELF, @nogo, %a, %adv )
- !! $return;
+ !! ($SINK ?? Nil !! $return);
} #SLICE_MORE
View
@@ -25,6 +25,9 @@ multi sub postcircumfix:<[ ]>(\SELF, int $pos, Mu :$BIND! is parcel) is rw {
fail "Cannot use negative index $pos on {SELF.WHAT.perl}" if $pos < 0;
SELF.bind_pos($pos, $BIND);
}
+multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$SINK!, *%other ) is rw {
+ SLICE_ONE( SELF, $pos, True, :$SINK, |%other );
+}
multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$delete!, *%other ) is rw {
SLICE_ONE( SELF, $pos, True, :$delete, |%other );
}
@@ -53,6 +56,9 @@ multi sub postcircumfix:<[ ]>(\SELF, $pos, Mu :$BIND! is parcel) is rw {
fail "Cannot use negative index $pos on {SELF.WHAT.perl}" if $pos < 0;
SELF.bind_pos($pos, $BIND);
}
+multi sub postcircumfix:<[ ]>( \SELF, $pos, :$SINK!, *%other ) is rw {
+ SLICE_ONE( SELF, $pos, True, :$SINK, |%other );
+}
multi sub postcircumfix:<[ ]>( \SELF, $pos, :$delete!, *%other ) is rw {
SLICE_ONE( SELF, $pos, True, :$delete, |%other );
}
@@ -85,6 +91,9 @@ multi sub postcircumfix:<[ ]>( \SELF, Positional \pos ) is rw {
multi sub postcircumfix:<[ ]>(\SELF, Positional \pos, :$BIND!) is rw {
X::Bind::Slice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<[ ]>(\SELF, Positional \pos, :$SINK!, *%other) is rw {
+ SLICE_MORE( SELF, POSITIONS(SELF,pos), True, :$SINK, |%other );
+}
multi sub postcircumfix:<[ ]>(\SELF,Positional \pos,:$delete!,*%other) is rw {
SLICE_MORE( SELF, POSITIONS(SELF,pos), True, :$delete, |%other );
}
@@ -111,6 +120,9 @@ multi sub postcircumfix:<[ ]>( \SELF, Callable $block ) is rw {
multi sub postcircumfix:<[ ]>(\SELF, Callable $block, :$BIND!) is rw {
X::Bind::Slice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<[ ]>(\SELF, Callable $block, :$SINK!, *%other) is rw {
+ SLICE_MORE( SELF, POSITIONS(SELF,$block), True, :$SINK, |%other );
+}
multi sub postcircumfix:<[ ]>(\SELF,Callable $block,:$delete!,*%other) is rw {
SLICE_MORE( SELF, POSITIONS(SELF,$block), True, :$delete, |%other );
}
@@ -137,6 +149,9 @@ multi sub postcircumfix:<[ ]>( \SELF, Whatever ) is rw {
multi sub postcircumfix:<[ ]>(\SELF, Whatever, :$BIND!) is rw {
X::Bind::Slice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<[ ]>(\SELF, Whatever, :$SINK!, *%other) is rw {
+ SLICE_MORE( SELF, SELF.keys, True, :$SINK, |%other );
+}
multi sub postcircumfix:<[ ]>(\SELF, Whatever, :$delete!, *%other) is rw {
SLICE_MORE( SELF, SELF.keys, True, :$delete, |%other );
}
@@ -163,6 +178,9 @@ multi sub postcircumfix:<[ ]>( \SELF ) is rw {
multi sub postcircumfix:<[ ]>(\SELF, :$BIND!) is rw {
X::Bind::ZenSlice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<[ ]>(\SELF, :$SINK!, *%other) is rw {
+ SLICE_MORE( SELF, SELF.keys, True, :$SINK, |%other );
+}
multi sub postcircumfix:<[ ]>(\SELF, :$delete!, *%other) is rw {
SLICE_MORE( SELF, SELF.keys, True, :$delete, |%other );
}
View
@@ -9,6 +9,9 @@ multi sub postcircumfix:<{ }>( \SELF, $key ) is rw {
multi sub postcircumfix:<{ }>(\SELF, $key, Mu :$BIND! is parcel) is rw {
SELF.bind_key($key, $BIND);
}
+multi sub postcircumfix:<{ }>( \SELF, $key, :$SINK!, *%other ) is rw {
+ SLICE_ONE( SELF, $key, False, :$SINK, |%other );
+}
multi sub postcircumfix:<{ }>( \SELF, $key, :$delete!, *%other ) is rw {
SLICE_ONE( SELF, $key, False, :$delete, |%other );
}
@@ -37,6 +40,9 @@ multi sub postcircumfix:<{ }>( \SELF, Positional \key ) is rw {
multi sub postcircumfix:<{ }>(\SELF, Positional \key, :$BIND!) is rw {
X::Bind::Slice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<{ }>(\SELF,Positional \key,:$SINK!,*%other) is rw {
+ SLICE_MORE( SELF, \key, False, :$SINK, |%other );
+}
multi sub postcircumfix:<{ }>(\SELF,Positional \key,:$delete!,*%other) is rw {
SLICE_MORE( SELF, \key, False, :$delete, |%other );
}
@@ -63,6 +69,9 @@ multi sub postcircumfix:<{ }>( \SELF, Whatever ) is rw {
multi sub postcircumfix:<{ }>(\SELF, Whatever, :$BIND!) is rw {
X::Bind::Slice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<{ }>(\SELF, Whatever, :$SINK!, *%other) is rw {
+ SLICE_MORE( SELF, SELF.keys, False, :$SINK, |%other );
+}
multi sub postcircumfix:<{ }>(\SELF, Whatever, :$delete!, *%other) is rw {
SLICE_MORE( SELF, SELF.keys, False, :$delete, |%other );
}
@@ -89,6 +98,9 @@ multi sub postcircumfix:<{ }>( \SELF ) is rw {
multi sub postcircumfix:<{ }>(\SELF, :$BIND!) is rw {
X::Bind::ZenSlice.new(type => SELF.WHAT).throw;
}
+multi sub postcircumfix:<{ }>(\SELF, :$SINK!, *%other) is rw {
+ SLICE_MORE( SELF, SELF.keys, False, :$SINK, |%other );
+}
multi sub postcircumfix:<{ }>(\SELF, :$delete!, *%other) is rw {
SLICE_MORE( SELF, SELF.keys, False, :$delete, |%other );
}

0 comments on commit 02af63a

Please sign in to comment.