Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make EnumMap a first class citizen, skids++
EnumMap.new should now work like Hash.new.  There are still issues to be
resolved wrt to the immutability of the EnumMap.  Most of this patch consists
of moving methods "new" and STORE from Hash to EnumMap.
  • Loading branch information
lizmat committed Jan 19, 2015
1 parent 0bf4263 commit d78c678
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 44 deletions.
50 changes: 45 additions & 5 deletions src/core/EnumMap.pm
@@ -1,7 +1,15 @@
my class X::Hash::Store::OddNumber { ... }

my class EnumMap does Associative { # declared in BOOTSTRAP
# my class EnumMap is Iterable is Cool {
# has Mu $!storage;

method new(*@args) {
my %h := nqp::create(self);
%h.STORE(@args) if @args;
%h;
}

multi method Bool(EnumMap:D:) {
nqp::p6bool(nqp::defined($!storage) && nqp::elems($!storage));
}
Expand Down Expand Up @@ -39,9 +47,10 @@ my class EnumMap does Associative { # declared in BOOTSTRAP
}

multi method perl(EnumMap:D:) {
self.^name ~ '.new('
~ self.keys.map({ .perl ~ ', ' ~ self.at_key($_).perl ~ ', '}).join
~ ')';
self.^name
~ '.new('
~ self.pairs.pick(*).map({.perl}).join(', ')
~ ')';
}

method iterator(EnumMap:) { self.pairs.iterator }
Expand All @@ -63,13 +72,44 @@ my class EnumMap does Associative { # declared in BOOTSTRAP
(nqp::defined($!storage) ?? HashIter.invert(self) !! ()).list;
}

method at_key($key) is rw {
my str $skey = nqp::unbox_s($key.Str);
multi method at_key(EnumMap:D: \key) is rw {
my str $skey = nqp::unbox_s(key.Str);
nqp::defined($!storage) && nqp::existskey($!storage, $skey)
?? nqp::atkey($!storage, $skey)
!! Any
}

method STORE(\to_store) {
my $items = (to_store,).flat.eager;
$!storage := nqp::hash();

if $items.elems == 1 {
if nqp::istype($items[0],EnumMap) {
my Mu $x := $items.shift;
DEPRECATED(
self.VAR.name ~ ' = %(itemized hash)',
|<2014.07 2015.07>,
:what(self.VAR.name ~ ' = itemized hash')
) if nqp::iscont($x);
for $x.list { self.STORE_AT_KEY(.key, .value) }
return self;
}
}

while $items {
my Mu $x := $items.shift;
if nqp::istype($x,Enum) { self.STORE_AT_KEY($x.key, $x.value) }
elsif nqp::istype($x,EnumMap) and !nqp::iscont($x) {
for $x.list { self.STORE_AT_KEY(.key, .value) }
}
elsif $items { self.STORE_AT_KEY($x, $items.shift) }
else {
X::Hash::Store::OddNumber.new.throw
}
}
self
}

method STORE_AT_KEY(\key, Mu \value) is rw {
nqp::defined($!storage) ||
nqp::bindattr(self, EnumMap, '$!storage', nqp::hash());
Expand Down
39 changes: 0 additions & 39 deletions src/core/Hash.pm
@@ -1,15 +1,7 @@
my class X::Hash::Store::OddNumber { ... }

my class Hash { # declared in BOOTSTRAP
# my class Hash is EnumMap {
# has Mu $!descriptor;

method new(*@args) {
my %h := nqp::create(self);
%h.STORE(@args) if @args;
%h;
}

multi method at_key(Hash:D: \key) is rw {
my Mu $storage := nqp::getattr(self, EnumMap, '$!storage');
$storage := nqp::bindattr(self, EnumMap, '$!storage', nqp::hash())
Expand Down Expand Up @@ -79,37 +71,6 @@ my class Hash { # declared in BOOTSTRAP
nqp::findmethod(EnumMap, 'STORE_AT_KEY')(self, key, $v = $x);
}

method STORE(\to_store) {
my $items = (to_store,).flat.eager;
nqp::bindattr(self, EnumMap, '$!storage', nqp::hash());

if $items.elems == 1 {
if nqp::istype($items[0],EnumMap) {
my Mu $x := $items.shift;
DEPRECATED(
self.VAR.name ~ ' = %(itemized hash)',
|<2014.07 2015.07>,
:what(self.VAR.name ~ ' = itemized hash')
) if nqp::iscont($x);
for $x.list { self.STORE_AT_KEY(.key, .value) }
return self;
}
}

while $items {
my Mu $x := $items.shift;
if nqp::istype($x,Enum) { self.STORE_AT_KEY($x.key, $x.value) }
elsif nqp::istype($x,EnumMap) and !nqp::iscont($x) {
for $x.list { self.STORE_AT_KEY(.key, .value) }
}
elsif $items { self.STORE_AT_KEY($x, $items.shift) }
else {
X::Hash::Store::OddNumber.new.throw
}
}
self
}

# introspection
method name() {
my $d := $!descriptor;
Expand Down

0 comments on commit d78c678

Please sign in to comment.