Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Turn Bool into a proper enum
  • Loading branch information
niner committed Oct 3, 2015
1 parent 03a9e73 commit 398f255
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 39 deletions.
26 changes: 21 additions & 5 deletions src/Perl6/Metamodel/BOOTSTRAP.nqp
Expand Up @@ -67,7 +67,7 @@ my stub Array metaclass Perl6::Metamodel::ClassHOW { ... };
my stub Map metaclass Perl6::Metamodel::ClassHOW { ... };
my stub Hash metaclass Perl6::Metamodel::ClassHOW { ... };
my stub Capture metaclass Perl6::Metamodel::ClassHOW { ... };
my stub Bool metaclass Perl6::Metamodel::ClassHOW { ... };
my stub Bool metaclass Perl6::Metamodel::EnumHOW { ... };
my stub ObjAt metaclass Perl6::Metamodel::ClassHOW { ... };
my stub Stash metaclass Perl6::Metamodel::ClassHOW { ... };
my stub PROCESS metaclass Perl6::Metamodel::ModuleHOW { ... };
Expand Down Expand Up @@ -2701,13 +2701,23 @@ BEGIN {
Junction.HOW.add_attribute(Junction, scalar_attr('$!type', Mu, Junction));
Junction.HOW.compose_repr(Junction);

# class Bool is Cool {
# class Bool is Int {
# has str $!key;
# has int $!value;
Bool.HOW.add_parent(Bool, Cool);
Bool.HOW.add_attribute(Bool, BOOTSTRAPATTR.new(:name<$!value>, :type(int), :box_target(1), :package(Bool)));
Bool.HOW.set_base_type(Bool, Int);
Bool.HOW.add_attribute(Bool, BOOTSTRAPATTR.new(:name<$!key>, :type(str), :package(Bool)));
Bool.HOW.add_attribute(Bool, BOOTSTRAPATTR.new(:name<$!value>, :type(int), :package(Bool)));
Bool.HOW.set_boolification_mode(Bool, 1);
Bool.HOW.publish_boolification_spec(Bool);
Bool.HOW.compose_repr(Bool);
Bool.HOW.add_method(Bool, 'key', nqp::getstaticcode(sub ($self) {
nqp::getattr_s(nqp::decont($self),
Bool, '$!key');
}));
Bool.HOW.add_method(Bool, 'value', nqp::getstaticcode(sub ($self) {
nqp::getattr_i(nqp::decont($self),
Bool, '$!value');
}));

# class ObjAt is Any {
# has str $!value;
Expand Down Expand Up @@ -2759,7 +2769,7 @@ BEGIN {
Perl6::Metamodel::NativeRefHOW.add_stash(IntPosRef);
Perl6::Metamodel::NativeRefHOW.add_stash(NumPosRef);
Perl6::Metamodel::NativeRefHOW.add_stash(StrPosRef);
Perl6::Metamodel::ClassHOW.add_stash(Bool);
Perl6::Metamodel::EnumHOW.add_stash(Bool);
Perl6::Metamodel::ClassHOW.add_stash(Stash);
Perl6::Metamodel::ClassHOW.add_stash(List);
Perl6::Metamodel::ClassHOW.add_stash(Slip);
Expand Down Expand Up @@ -2803,10 +2813,16 @@ BEGIN {

# Bool::False and Bool::True.
my $false := nqp::create(Bool);
nqp::bindattr_s($false, Bool, '$!key', 'False');
nqp::bindattr_i($false, Bool, '$!value', 0);
nqp::bindattr_i($false, Int, '$!value', 0);
Bool.HOW.add_enum_value(Bool, $false);
(Bool.WHO)<False> := $false;
my $true := nqp::create(Bool);
nqp::bindattr_s($true, Bool, '$!key', 'True');
nqp::bindattr_i($true, Bool, '$!value', 1);
nqp::bindattr_i($true, Int, '$!value', 1);
Bool.HOW.add_enum_value(Bool, $true);
(Bool.WHO)<True> := $true;

# Setup some regexy/grammary bits.
Expand Down
4 changes: 2 additions & 2 deletions src/Perl6/Metamodel/EnumHOW.nqp
Expand Up @@ -49,11 +49,11 @@ class Perl6::Metamodel::EnumHOW
nqp::findmethod(NQPMu, 'BUILDALL')(nqp::create(self), |%named)
}

method new_type(:$name!, :$base_type!) {
method new_type(:$name!, :$base_type?) {
my $meta := self.new();
my $obj := nqp::settypehll(nqp::newtype($meta, 'P6opaque'), 'perl6');
$meta.set_name($obj, $name);
$meta.set_base_type($meta, $base_type);
$meta.set_base_type($meta, $base_type) unless $base_type =:= NQPMu;
self.add_stash($obj);
}

Expand Down
87 changes: 55 additions & 32 deletions src/core/Bool.pm
@@ -1,49 +1,72 @@
my class Bool { # declared in BOOTSTRAP
# class Bool is Cool {
# has int $!value;

multi method Bool(Bool:D:) { self }
multi method Numeric(Bool:D:) { self ?? 1 !! 0 }
multi method Str(Bool:D:) { self ?? 'True' !! 'False' }
multi method gist(Bool:D:) { self ?? 'True' !! 'False' }
multi method DUMP(Bool:D:) { self.Str }

method Int() { self ?? 1 !! 0 }

method pred() { Bool::False }
method succ() { Bool::True }

method key() { self.Str }
method value() { self.Numeric }

proto method pick(|) { * }
multi method pick(Bool:U:) { nqp::p6bool(nqp::isge_n(nqp::rand_n(2e0), 1e0)) }
multi method pick(Bool:U: $n) { (Bool::True,Bool::False).pick($n) }

proto method roll(|) { * }
multi method roll(Bool:U:) { nqp::p6bool(nqp::isge_n(nqp::rand_n(2e0), 1e0)) }
multi method roll(Bool:U: $n) { (Bool::True,Bool::False).roll($n) }
# enum Bool declared in BOOTSTRAP
{
Bool.^add_method('Bool', my proto method Bool(|) { * });
Bool.^add_method('gist', my proto method gist(|) { * });
Bool.^add_method('Str', my proto method Str(|) { * });
Bool.^add_method('Numeric', my proto method Numeric(|) { * });
Bool.^add_method('ACCEPTS', my proto method ACCEPTS(|) { * });
Bool.^add_method('pick', my proto method pick(|) { * });
Bool.^add_method('roll', my proto method roll(|) { * });
Bool.^add_method('perl', my proto method perl(|) { * });
}
{
Bool.^add_multi_method('Bool', my multi method Bool(Bool:D:) { self });
Bool.^add_multi_method('gist', my multi method gist(Bool:D:) { self ?? 'True' !! 'False' });
Bool.^add_multi_method('Str', my multi method Str(Bool:D:) { self ?? 'True' !! 'False' });
Bool.^add_multi_method('Numeric', my multi method Numeric(Bool:D:) { self ?? 1 !! 0 });
Bool.^add_multi_method('ACCEPTS', my multi method ACCEPTS(Bool:D: Mu \topic ) { self });
Bool.^add_multi_method('perl', my multi method perl(Bool:D:) { self ?? 'Bool::True' !! 'Bool::False' });

Bool.^add_multi_method('pick', my multi method pick(Bool:U:) { nqp::p6bool(nqp::isge_n(nqp::rand_n(2e0), 1e0)) });
Bool.^add_multi_method('roll', my multi method roll(Bool:U:) { nqp::p6bool(nqp::isge_n(nqp::rand_n(2e0), 1e0)) });
}
{
Bool.^add_multi_method('Bool', my multi method Bool(Bool:U:) { Bool::False });
Bool.^add_multi_method('ACCEPTS', my multi method ACCEPTS(Bool:U: Mu \topic ) { nqp::istype(topic, Bool) });
Bool.^add_multi_method('gist', my multi method gist(Bool:U:) { '(Bool)' });
Bool.^add_multi_method('perl', my multi method perl(Bool:U:) { 'Bool' });

multi method ACCEPTS(Bool:D: Mu \topic ) { self }
Bool.^add_multi_method('pick', my multi method pick(Bool:U: $n) { (Bool::True,Bool::False).pick($n) });
Bool.^add_multi_method('roll', my multi method roll(Bool:U: $n) { (Bool::True,Bool::False).roll($n) });

multi method perl(Bool:D:) { self ?? 'Bool::True' !! 'Bool::False' }
Bool.^add_method('pred', my method pred() { Bool::False });
Bool.^add_method('succ', my method succ() { Bool::True });

method enums() {
my % = False => 0, True => 1
}
Bool.^compose;
}

multi sub prefix:<++>(Bool:U $a is rw) { $a = True; }
multi sub prefix:<-->(Bool:U $a is rw) { $a = False; }
multi sub prefix:<++>(Bool $a is rw) { $a = True; }
multi sub prefix:<-->(Bool $a is rw) { $a = False; }
multi sub postfix:<++>(Bool:U $a is rw) { $a = True; False; }
multi sub postfix:<-->(Bool:U $a is rw) { $a = False; }

multi sub postfix:<++>(Bool:D $a is rw) {
if $a {
True
}
else {
$a = True;
False
}
}
multi sub postfix:<-->(Bool:D $a is rw) {
if $a {
$a = False;
True
}
else {
False
}
}

proto sub prefix:<?>(Mu $) is pure { * }
multi sub prefix:<?>(Bool:D \a) { a }
multi sub prefix:<?>(Bool:U \a) { Bool::False }
multi sub prefix:<?>(Mu \a) { a.Bool }

proto sub prefix:<so>(Mu $) is pure { * }
multi sub prefix:<so>(Bool:D \a) { a }
multi sub prefix:<so>(Bool:U \a) { Bool::False }
multi sub prefix:<so>(Mu \a) { a.Bool }

proto sub prefix:<!>(Mu $) is pure { * }
Expand Down

0 comments on commit 398f255

Please sign in to comment.