Skip to content

Commit bda247f

Browse files
committed
enable forward gotos. can't have unused labels. can't jump into blocks, and can't jump out of blocks that declare their own lexicals.
1 parent f0bf33d commit bda247f

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

src/NQP/Actions.pm

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class NQP::Actions is HLL::Actions {
4040
}
4141

4242
method comp_unit($/) {
43+
resolve_gotos($/);
4344
my $mainline := $<statementlist>.ast;
4445
my $unit := $*W.pop_lexpad();
4546

@@ -127,25 +128,25 @@ class NQP::Actions is HLL::Actions {
127128
}
128129

129130
method label($/) {
130-
my $name := 'VNDUNVD84VN'~$<identifier>;
131-
my $BLOCK := $*W.cur_lexpad();
132-
if $BLOCK.symbol($name) {
133-
$/.CURSOR.panic("Redeclaration of symbol ", $name);
134-
}
135-
$BLOCK.symbol($name, :scope('label') );
136-
my $past := PAST::Label.new( :node($/), :name($name) );
131+
my $name := $<identifier>;
132+
if (%*LABELS{$name}) {
133+
$/.CURSOR.panic("Duplicate label: ", $name);
134+
}
135+
$*W.cur_lexpad().symbol($name, :scope('label') );
136+
$*LABEL_INDEX++;
137+
my $mangled := "nqp_label_"~$*LABEL_INDEX~'_'~$name;
138+
my $past := PAST::Label.new( :node($/), :name($mangled) );
139+
%*LABELS{$name} := $past;
137140
make $past;
138141
}
139142

140143
method goto($/) {
141-
my $origname := $<identifier>;
142-
my $name := 'VNDUNVD84VN'~$origname;
143-
unless $*W.is_scope($name, 'label') {
144-
$/.CURSOR.panic("missing label (no forward gotos) ", $origname);
145-
}
144+
my $name := $<identifier>;
145+
my $glabel := PAST::Label.new( :node($/), :name($name) );
146+
@*GOTOS.push($glabel);
146147
my $past := PAST::Op.new(
147148
:pasttype('goto'),
148-
PAST::Label.new( :node($/), :name($name) )
149+
$glabel
149150
);
150151
make $past;
151152
}
@@ -714,10 +715,22 @@ class NQP::Actions is HLL::Actions {
714715

715716
}
716717

718+
sub resolve_gotos($/) {
719+
for @*GOTOS {
720+
my $name := $_.name();
721+
my $label := %*LABELS{$name};
722+
unless $label {
723+
$/.CURSOR.panic('Could not find label '~$name~' for a goto');
724+
}
725+
$_.name($label.name());
726+
}
727+
}
728+
717729
method routine_declarator:sym<sub>($/) { make $<routine_def>.ast; }
718730
method routine_declarator:sym<method>($/) { make $<method_def>.ast; }
719731

720732
method routine_def($/) {
733+
resolve_gotos($/);
721734
# If it's just got * as a body, make a multi-dispatch enterer.
722735
# Otherwise, need to build a sub.
723736
my $past;
@@ -852,6 +865,7 @@ class NQP::Actions is HLL::Actions {
852865

853866

854867
method method_def($/) {
868+
resolve_gotos($/);
855869
# If it's just got * as a body, make a multi-dispatch enterer.
856870
# Otherwise, build method block PAST.
857871
my $past;

src/NQP/Grammar.pm

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ grammar NQP::Grammar is HLL::Grammar {
106106
:my $*HAS_YOU_ARE_HERE := 0;
107107
:my $*MAIN_SUB;
108108
<.newpad>
109-
109+
:my %*LABELS;
110+
:my @*GOTOS;
111+
:my $*LABEL_INDEX := 0;
110112
:my $*PACKAGE;
111113
:my $*GLOBALish;
112114
<.GLOBALish>
@@ -128,7 +130,7 @@ grammar NQP::Grammar is HLL::Grammar {
128130

129131
# not a real Perl 6 goto, so not a real &goto
130132
token goto {
131-
'goto' <?before \s> <.ws> <identifier>
133+
'goto' <?before \s> <.ws> <identifier> <.ws>
132134
}
133135

134136
token statement {
@@ -429,6 +431,9 @@ grammar NQP::Grammar is HLL::Grammar {
429431

430432
rule routine_def {
431433
:my $*RETURN_USED := 0;
434+
:my %*LABELS;
435+
:my @*GOTOS;
436+
:my $*LABEL_INDEX := 0;
432437
[ $<sigil>=['&'?]<deflongname> ]?
433438
<.newpad>
434439
[ '(' <signature> ')'
@@ -443,6 +448,9 @@ grammar NQP::Grammar is HLL::Grammar {
443448
rule method_def {
444449
:my $*RETURN_USED := 0;
445450
:my $*INVOCANT_OK := 1;
451+
:my %*LABELS;
452+
:my @*GOTOS;
453+
:my $*LABEL_INDEX := 0;
446454
$<private>=['!'?]
447455
<deflongname>?
448456
<.newpad>

0 commit comments

Comments
 (0)