@@ -40,6 +40,7 @@ class NQP::Actions is HLL::Actions {
40
40
}
41
41
42
42
method comp_unit ($/ ) {
43
+ resolve_gotos($/ );
43
44
my $ mainline := $ < statementlist > . ast;
44
45
my $ unit := $ * W . pop_lexpad();
45
46
@@ -127,25 +128,25 @@ class NQP::Actions is HLL::Actions {
127
128
}
128
129
129
130
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 ;
137
140
make $ past ;
138
141
}
139
142
140
143
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 );
146
147
my $ past := PAST::Op. new (
147
148
: pasttype(' goto' ),
148
- PAST::Label . new ( : node( $/ ), : name( $ name ) )
149
+ $ glabel
149
150
);
150
151
make $ past ;
151
152
}
@@ -714,10 +715,22 @@ class NQP::Actions is HLL::Actions {
714
715
715
716
}
716
717
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
+
717
729
method routine_declarator :sym <sub >($/ ) { make $ < routine_def > . ast; }
718
730
method routine_declarator :sym <method >($/ ) { make $ < method_def > . ast; }
719
731
720
732
method routine_def ($/ ) {
733
+ resolve_gotos($/ );
721
734
# If it's just got * as a body, make a multi-dispatch enterer.
722
735
# Otherwise, need to build a sub.
723
736
my $ past ;
@@ -852,6 +865,7 @@ class NQP::Actions is HLL::Actions {
852
865
853
866
854
867
method method_def ($/ ) {
868
+ resolve_gotos($/ );
855
869
# If it's just got * as a body, make a multi-dispatch enterer.
856
870
# Otherwise, build method block PAST.
857
871
my $ past ;
0 commit comments