Mercurial > hg > Others > Rakudo
view src/core.c/Mixy.pm6 @ 0:c341f82e7ad7 default tip
Rakudo branch in cr.ie.u-ryukyu.ac.jp
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 26 Dec 2019 16:50:27 +0900 |
parents | |
children |
line wrap: on
line source
my role Mixy does Baggy { method of() { Real } multi method hash(Mixy:D: --> Hash:D) { self!HASHIFY(Real) } multi method Hash(Mixy:D: --> Hash:D) { self!HASHIFY(Any) } multi method kxxv(Mixy:D:) { Failure.new(".kxxv is not supported on a {self.^name}") } multi method grab(Mixy:D: $count?) { Failure.new(".grab is not supported on a {self.^name}") } multi method pick(Mixy:D: $count?) { Failure.new(".pick is not supported on a {self.^name}, maybe use .roll instead?") } multi method roll(Mixy:D:) { nqp::if( (my \raw := self.RAW-HASH) && (my \total := self!total-positive), nqp::getattr( nqp::iterval(Rakudo::QuantHash.MIX-ROLL(raw,total)),Pair,'$!key' ), Nil ) } multi method roll(Mixy:D: Whatever) { Seq.new(nqp::if( (my \raw := self.RAW-HASH) && (my \total := self!total-positive), Rakudo::Iterator.Callable( { nqp::getattr( nqp::iterval(Rakudo::QuantHash.MIX-ROLL(raw,total)),Pair,'$!key' ) }, True ), Rakudo::Iterator.Empty )) } multi method roll(Mixy:D: Callable:D $calculate) { nqp::if( (my $total := self!total-positive), self.roll($calculate($total)), Seq.new(Rakudo::Iterator.Empty) ) } multi method roll(Mixy:D: $count) { nqp::if( $count == Inf, self.roll(*), # let Whatever handle it Seq.new(nqp::if( # something else as count (my $todo = $count.Int) < 1, # also handles NaN Rakudo::Iterator.Empty, # nothing to do nqp::if( (my \raw := self.RAW-HASH) && (my \total := self!total-positive) && ++$todo, Rakudo::Iterator.Callable( { # need to do a number of times nqp::if( --$todo, nqp::getattr( nqp::iterval(Rakudo::QuantHash.MIX-ROLL(raw,total)), Pair, '$!key' ), IterationEnd ) }), Rakudo::Iterator.Empty # nothing to roll for ) )) ) } #--- object creation methods method new-from-pairs(Mixy:_: *@pairs --> Mixy:D) { nqp::if( (my \iterator := @pairs.iterator).is-lazy, Failure.new(X::Cannot::Lazy.new(:action<coerce>,:what(self.^name))), nqp::create(self).SET-SELF( Rakudo::QuantHash.ADD-PAIRS-TO-MIX( nqp::create(Rakudo::Internals::IterationSet),iterator,self.keyof ) ) ) } #--- coercion methods sub SETIFY(\mixy, \type) { nqp::if( (my \raw := mixy.RAW-HASH) && nqp::elems(raw), nqp::stmts( (my \elems := nqp::clone(raw)), (my \iter := nqp::iterator(elems)), nqp::while( iter, nqp::if( nqp::getattr(nqp::iterval(nqp::shift(iter)),Pair,'$!value') < 0, nqp::deletekey(elems,nqp::iterkey_s(iter)), nqp::bindkey( elems, nqp::iterkey_s(iter), nqp::getattr(nqp::iterval(iter),Pair,'$!key') ) ) ), nqp::create(type).SET-SELF(elems) ), nqp::if( nqp::eqaddr(type,Set), set(), nqp::create(type) ) ) } multi method Set(Mixy:D:) { SETIFY(self,Set) } multi method SetHash(Mixy:D:) { SETIFY(self,SetHash) } sub BAGGIFY(\mixy, \type) { nqp::if( (my \raw := mixy.RAW-HASH) && nqp::elems(raw), nqp::stmts( # something to coerce (my \elems := nqp::clone(raw)), (my \iter := nqp::iterator(elems)), nqp::while( iter, nqp::if( (my \value := nqp::getattr( nqp::iterval(nqp::shift(iter)),Pair,'$!value' ).Int) > 0, # .Int also deconts nqp::bindkey( # ok to keep value.Int elems, nqp::iterkey_s(iter), nqp::p6bindattrinvres( nqp::iterval(iter),Pair,'$!value',value) ), nqp::deletekey(elems,nqp::iterkey_s(iter)) ) ), nqp::create(type).SET-SELF(elems), ), nqp::if( # nothing to coerce nqp::istype(type,Bag), bag(), nqp::create(BagHash) ) ) } multi method Bag(Baggy:D:) { BAGGIFY(self, Bag) } multi method BagHash(Baggy:D:) { BAGGIFY(self, BagHash) } } # vim: ft=perl6 expandtab sw=4