Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: nom
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 96 lines (82 sloc) 2.337 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 87 88 89 90 91 92 93 94 95
# 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.defined
          ?? self xx +?( @pos[0] // 1 )
          !! self.^enum_value_list.pick(|@pos, |%named);
    }
    method roll(*@pos, *%named) {
        self.defined
          ?? self xx ( @pos[0] // 1 )
          !! self.^enum_value_list.roll(|@pos, |%named);
    }

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

    method postcircumfix:<( )>(|) {
        my $x := nqp::atpos(nqp::p6argvmarray(), 1).at_pos(0);
        nqp::istype($x, ::?CLASS)
            ?? $x
            !! self.HOW.enum_from_value(self, $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::decont($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
});

# vim: ft=perl6 expandtab sw=4
Something went wrong with that request. Please try again.