Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Initial implementation of Mixy / Mix / MixHash, as per spec (almost)
  • Loading branch information
lizmat committed Oct 3, 2013
1 parent 147c1e0 commit 61580f2
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/core/Any.pm
Expand Up @@ -242,6 +242,8 @@ my class Any { # declared in BOOTSTRAP
method SetHash() { SetHash.new-fp(self.list) }
method Bag() { Bag.new-fp(self.list) }
method BagHash() { BagHash.new-fp(self.list) }
method Mix() { Mix.new-fp(self.list) }
method MixHash() { MixHash.new-fp(self.list) }
}
Metamodel::ClassHOW.exclude_parent(Any);

Expand Down
22 changes: 22 additions & 0 deletions src/core/Mix.pm
@@ -0,0 +1,22 @@
my class Mix does Mixy {
has $!WHICH;

method at_key($k --> Real) {
my $elems := nqp::getattr(self, Mix, '%!elems');
my $key := $k.WHICH;
$elems.exists_key($key)
?? $elems{$key}.value
!! 0;
}

method delete ($a --> Real) { # is DEPRECATED doesn't work in settings
once DEPRECATED("Method 'Mix.delete'","the :delete adverb");
self.delete_key($a);
}
method delete_key($a --> Real) is hidden_from_backtrace {
X::Immutable.new( method => 'delete', typename => self.^name ).throw;
}

method Mix { self }
method MixHash { MixHash.new-fp(nqp::getattr(self, Mix, '%!elems').values) }
}
51 changes: 51 additions & 0 deletions src/core/MixHash.pm
@@ -0,0 +1,51 @@
my class MixHash does Mixy {

method at_key($k) {
Proxy.new(
FETCH => {
my $key := $k.WHICH;
my $elems := nqp::getattr(self, MixHash, '%!elems');
$elems.exists_key($key) ?? $elems{$key}.value !! 0;
},
STORE => -> $, $value {
if $value != 0 {
(nqp::getattr(self, MixHash, '%!elems'){$k.WHICH}
//= ($k => 0)).value = $value;
}
else {
self.delete_key($k);
}
$value;
}
);
}

method delete($k) { # is DEPRECATED doesn't work in settings
once DEPRECATED("Method 'MixHash.delete'","the :delete adverb");
self.delete_key($k);
}
method delete_key($k) {
my $key := $k.WHICH;
my $elems := nqp::getattr(self, MixHash, '%!elems');
if $elems.exists_key($key) {
my $value = $elems{$key}.value;
$elems.delete_key($key);
$value;
}
else {
0;
}
}

method Mix (:$view) {
if $view {
my $mix := nqp::create(Mix);
$mix.BUILD( :elems(nqp::getattr(self, MixHash, '%!elems')) );
$mix;
}
else {
Mix.new-fp(nqp::getattr(self, MixHash, '%!elems').values);
}
}
method MixHash { self }
}
40 changes: 40 additions & 0 deletions src/core/Mixy.pm
@@ -0,0 +1,40 @@
my role Mixy does Baggy { # should really be QuantHash, but that's for later

method default(--> Real) { 0 }
method total(--> Real) { [+] self.values }

multi method gist(Mixy:D $ : --> Str) {
my $name := self.^name;
( $name eq 'Mix' ?? 'mix' !! "$name.new" )
~ '('
# ~ %!elems.values.map( { "{.key.gist}({.value})" } ).join(', ')
~ self.pairs.map( {
.value == 1 ?? .key.gist !! "{.key.gist}({.value})"
} ).join(', ')
~ ')';
}

method pick ($count = 1) {
fail ".pick is not supported on a {.self.^name}";
}

method roll ($count = 1) {
my $total = self.total;
my $rolls = $count ~~ Num ?? $total min $count !! $count;
# my @pairs := %!elems.values;
my @pairs := self.pairs;

map {
my $rand = $total.rand;
my $seen = 0;
my $roll;
for @pairs -> $pair {
next if ( $seen += $pair.value ) <= $rand;

$roll = $pair.key;
last;
}
$roll;
}, 1 .. $rolls;
}
}
1 change: 1 addition & 0 deletions src/core/set_operators.pm
Expand Up @@ -251,5 +251,6 @@ only sub infix:<<"\x227D">>($a, $b --> Bool) {

sub set(*@args --> Set) { Set.new(@args) }
sub bag(*@args --> Bag) { Bag.new(|@args) }
sub mix(*@args --> Mix) { Mix.new(|@args) }
# U+2205 EMPTY SET
#constant term:<<"\x2205">> = set(); #Cannot call ACCEPTS; no signatures match
5 changes: 4 additions & 1 deletion src/core/stubs.pm
Expand Up @@ -19,6 +19,10 @@ my role Baggy { ... }
my class Bag { ... }
my class BagHash { ... }

my role Mixy { ... }
my class Mix { ... }
my class MixHash { ... }

sub DYNAMIC(\name) is rw {
my Mu $x := nqp::getlexdyn(nqp::unbox_s(name));
if nqp::isnull($x) {
Expand All @@ -38,4 +42,3 @@ sub DYNAMIC(\name) is rw {
}
Dummy.HOW.set_autogen_proto(&Dummy::AUTOGEN);
}

3 changes: 3 additions & 0 deletions tools/build/Makefile-JVM.in
Expand Up @@ -192,6 +192,9 @@ CORE_SOURCES = \
src/core/Baggy.pm \
src/core/Bag.pm \
src/core/BagHash.pm \
src/core/Mixy.pm \
src/core/Mix.pm \
src/core/MixHash.pm \
src/core/set_operators.pm \
src/core/ObjAt.pm \
src/core/Version.pm \
Expand Down
3 changes: 3 additions & 0 deletions tools/build/Makefile-Parrot.in
Expand Up @@ -238,6 +238,9 @@ CORE_SOURCES = \
src/core/Baggy.pm \
src/core/Bag.pm \
src/core/BagHash.pm \
src/core/Mixy.pm \
src/core/Mix.pm \
src/core/MixHash.pm \
src/core/set_operators.pm \
src/core/ObjAt.pm \
src/core/Version.pm \
Expand Down

0 comments on commit 61580f2

Please sign in to comment.