Skip to content

Commit

Permalink
basic implementation of anonymous enums
Browse files Browse the repository at this point in the history
  • Loading branch information
Carl Masak committed Feb 17, 2010
1 parent 761d05a commit f592840
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/Makefile.in
Expand Up @@ -76,6 +76,7 @@ SOURCES = \
BUILTINS_PIR = \
src/glue/contextuals.pir \
src/glue/dispatch.pir \
src/glue/enum.pir \
src/glue/phasers.pir \
src/glue/role.pir \
src/glue/run.pir \
Expand Down
11 changes: 11 additions & 0 deletions src/Perl6/Actions.pm
Expand Up @@ -469,6 +469,7 @@ method term:sym<scope_declarator>($/) { make $<scope_declarator>.ast; }
method term:sym<routine_declarator>($/) { make $<routine_declarator>.ast; }
method term:sym<multi_declarator>($/) { make $<multi_declarator>.ast; }
method term:sym<regex_declarator>($/) { make $<regex_declarator>.ast; }
method term:sym<type_declarator>($/) { make $<type_declarator>.ast; }
method term:sym<statement_prefix>($/) { make $<statement_prefix>.ast; }
method term:sym<lambda>($/) { make create_code_object($<pblock>.ast, 'Block', 0, ''); }

Expand Down Expand Up @@ -1047,6 +1048,16 @@ method regex_declarator($/, $key?) {
}
}

method type_declarator:sym<enum>($/) {
my $values := $<circumfix>.ast;

make PAST::Op.new(
:pasttype('call'),
:name('!create_anon_enum'),
$values
);
}

method capterm($/) {
# Construct a Parcel, and then call .Capture to coerce it to a capture.
my $past := $<termish> ?? $<termish>.ast !!
Expand Down
10 changes: 10 additions & 0 deletions src/Perl6/Grammar.pm
Expand Up @@ -755,6 +755,14 @@ rule regex_declarator {
]
}

proto token type_declarator { <...> }

token type_declarator:sym<enum> {
<sym> <.ws>
<name>? <.ws>
<?before '(' | '<' | '<<' | '«' > <circumfix>
}

rule trait {
:my $*IN_DECL := '';
[
Expand Down Expand Up @@ -884,6 +892,8 @@ token typename {
[<.ws> 'of' <.ws> <typename> ]?
}

token term:sym<type_declarator> { <type_declarator> }

proto token quote { <...> }
token quote:sym<apos> { <?[']> <quote_EXPR: ':q'> }
token quote:sym<dblq> { <?["]> <quote_EXPR: ':qq'> }
Expand Down
60 changes: 60 additions & 0 deletions src/glue/enum.pir
@@ -0,0 +1,60 @@
=head1 NAME

src/glue/enum.pir -- internal handling of enums

=head2 Subs

=over 4

=item !create_anon_enum(value_list)

Constructs a EnumMap, based upon the values list.

=cut

.sub '!create_anon_enum'
.param pmc values

# Put the values into list context, so case of a single valued enum works.
values = values.'list'()

# For now, we assume integer type, unless we have a first pair that says
# otherwise.
.local pmc cur_val
cur_val = box 0

# Iterate over values and make mapping.
.local pmc enumhash, values_it, cur_item
enumhash = root_new ['parrot';'Hash']
values_it = iter values
values_loop:
unless values_it goto values_loop_end
cur_item = shift values_it
$I0 = isa cur_item, 'Perl6Pair'
if $I0 goto pair

nonpair:
enumhash[cur_item] = cur_val
cur_val = cur_val.'succ'()
goto values_loop

pair:
cur_val = cur_item.'value'()
$P0 = cur_item.'key'()
enumhash[$P0] = cur_val
cur_val = clone cur_val # XXX Don't know if this is needed
cur_val = cur_val.'succ'()
goto values_loop

values_loop_end:
.local pmc result
$P0 = get_hll_global 'EnumMap'
result = $P0.'new'(enumhash :flat :named)
.return (result)
.end

# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

0 comments on commit f592840

Please sign in to comment.