Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: ebc730c249
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 87 lines (74 sloc) 2.073 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
# Method that we have on enumeration types.
my role Enumeration {
    has $.key;
    has $.value;
    
    multi method Numeric(::?CLASS:D:) { $!value.Numeric }
    
    method enums() {
        self.^enum_values
    }
    
    multi method gist(::?CLASS:D:) {
        $!key
    }
    
    method kv(::?CLASS:D:) { ($!key, $!value) }
    
    method pair(::?CLASS:D:) { $!key => $!value }
    
    method perl() {
        self.defined ??
            (self.^name ~ '::' ~ $!key) !!
            self.^name;
    }
    
    method pick(*@pos, *%named) {
        self.^enum_value_list.pick(|@pos, |%named)
    }
    method roll(*@pos, *%named) {
        self.^enum_value_list.roll(|@pos, |%named)
    }

    method Int(::?CLASS:D:) {
        self.value.Int
    }

    method postcircumfix:<( )>($ ($x)) {
        $x ~~ ::?CLASS ?? $x !! self.^enum_from_value($x)
    }
}

# Methods that we also have if the base type of an enumeration is
# Numeric.
my role NumericEnumeration {
    multi method Str(::?CLASS:D:) {
        self.key
    }
}
my role StringyEnumeration {
    multi method Str(::?CLASS:D:) {
        self.value
    }
}

sub ANON_ENUM(*@args) {
    my Mu $prev = -1;
    my %res;
    for @args {
        if .^isa(Enum) {
            %res{.key} = .value;
        }
        else {
            %res{$_} = $prev.=succ;
        }
    }
    my $r := nqp::create(EnumMap);
    nqp::bindattr($r, EnumMap, '$!storage',
        nqp::getattr(%res, EnumMap, '$!storage'));
    $r;
}

Metamodel::EnumHOW.set_composalizer(-> $type, $name, %enum_values {
    my Mu $r := Metamodel::ParametricRoleHOW.new_type(:name($name));
    $r.HOW.add_attribute($r, Attribute.new(
        :name('$!' ~ $name), :type(nqp::p6decont($type)),
        :has_accessor(1), :package($r)));
    for %enum_values.kv -> $key, $value {
        my $meth = method () { self."$name"() === $value }
        $meth.set_name($key);
        $r.HOW.add_method($r, $key, $meth);
    }
    $r.HOW.set_body_block($r,
        -> |c { nqp::list($r, nqp::hash('$?CLASS', c<$?CLASS>)) });
    $r.HOW.compose($r);
    $r
});
Something went wrong with that request. Please try again.