Skip to content

Commit

Permalink
further enum cleanup
Browse files Browse the repository at this point in the history
Enums no long backtrack on failure to find an initializer, causing
mysterious undefined enum function errors.  Fixes #67942 even though
it was closed...

Only the setting uses the special-cased enum actions for bootstrapping
purposes.  All subsequent enums just use the standard evaluator to
prevent recurring surprises that used to happen when a special case is
hit before the normal case.  Fixes #122929 and 128017.

In support of using only the happy path outside of the setting, the type
of the first pair's value can now be determined from the actual value,
not just from the AST, since we don't take the special-cased setting
path for infix:<,> in normal code anymore.

An empty initializer using a variable now warns that it was probably
not declared properly as a constant. Fixes #130446.
  • Loading branch information
TimToady committed Nov 29, 2017
1 parent e7c0a64 commit 754664e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 26 deletions.
58 changes: 33 additions & 25 deletions src/Perl6/Actions.nqp
Expand Up @@ -4614,7 +4614,7 @@ class Perl6::Actions is HLL::Actions does STDActions {
# Get list of either values or pairs; fail if we can't.
my $Pair := $*W.find_symbol(['Pair']);
my @values;
my $term_ast := WANTED($<term>.ast,'enum');
my $term_ast := $<term>.ast;

# remove val call on a single item
if $term_ast.isa(QAST::Op) && $term_ast.name eq '&val' {
Expand All @@ -4624,33 +4624,31 @@ class Perl6::Actions is HLL::Actions does STDActions {
if $term_ast.isa(QAST::Stmts) && +@($term_ast) == 1 {
$term_ast := $term_ast[0];
}
if $term_ast.isa(QAST::Op) && $term_ast.name eq '&infix:<,>' {
wantall($term_ast, 'enum');
for @($term_ast) {
my $item_ast := $_;
if $item_ast.isa(QAST::Op) && $item_ast.name eq '&val' {
$item_ast := $item_ast[0];
}
$term_ast := WANTED($term_ast,'enum');
if $*COMPILING_CORE_SETTING { # must handle bootstrapping enums here
if $term_ast.isa(QAST::Op) && $term_ast.name eq '&infix:<,>' {
wantall($term_ast, 'enum');
for @($term_ast) {
my $item_ast := $_;
if $item_ast.isa(QAST::Op) && $item_ast.name eq '&val' {
$item_ast := $item_ast[0];
}

if istype($item_ast.returns(), $Pair) && $item_ast[1].has_compile_time_value {
@values.push($item_ast);
}
elsif $item_ast.has_compile_time_value {
@values.push($item_ast);
}
else {
@values.push($*W.compile_time_evaluate($<term>, $item_ast));
if istype($item_ast.returns(), $Pair) && $item_ast[1].has_compile_time_value {
@values.push($item_ast);
}
elsif $item_ast.has_compile_time_value {
@values.push($item_ast);
}
else {
@values.push($*W.compile_time_evaluate($<term>, $item_ast));
}
}
}
}
elsif $term_ast.has_compile_time_value {
@values.push($term_ast);
}
elsif istype($term_ast.returns, $Pair) && $term_ast[1].has_compile_time_value {
@values.push($term_ast);
}
else {
@values := $*W.compile_time_evaluate($<term>, $<term>.ast).List.FLATTENABLE_LIST;
# After we finish compiling the setting, everyone uses the same evaluator without special cases.
unless @values {
@values := $*W.compile_time_evaluate($<term>, $term_ast).List.FLATTENABLE_LIST;
}

# Now we have them, we can go about computing the value
Expand All @@ -4661,6 +4659,11 @@ class Perl6::Actions is HLL::Actions does STDActions {
my @redecl;
my $block := $*W.cur_lexpad();
my $index := -1;
unless nqp::elems(@values) {
my $term := $<term>.Str;
$term := nqp::substr($term,1,nqp::chars($term) - 2);
$<term>.worry("No values supplied to enum (does $term need to be declared constant?)") if $term ~~ /\w/;
}
for @values {
# If it's a pair, take that as the value; also find
# key.
Expand All @@ -4686,7 +4689,12 @@ class Perl6::Actions is HLL::Actions does STDActions {
}
else {
unless $has_base_type {
$base_type := $*W.find_symbol(['Int']);
if nqp::istype($_, $Pair) {
$base_type := $_.value.WHAT;
}
else {
$base_type := $*W.find_symbol(['Int']);
}
make_type_obj($base_type);
$has_base_type := 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Perl6/Grammar.nqp
Expand Up @@ -3259,7 +3259,7 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
<.ws>
<trait>*
:my %*MYSTERY;
<?[<(«]> <term> <.ws>
[ <?[<(«]> <term> <.ws> || <.panic: 'An enum must supply an expression using <>, «», or ()'> ]
<.explain_mystery> <.cry_sorrows>
}
Expand Down

0 comments on commit 754664e

Please sign in to comment.