Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
initial attempt at labels/goto. limitations: can't goto into/from a b…
…lock if the block declares lexicals; can't forward goto (will aim at fixing this soon)
  • Loading branch information
diakopter committed May 12, 2012
1 parent 17cc549 commit c98f22b
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
33 changes: 33 additions & 0 deletions src/NQP/Actions.pm
Expand Up @@ -126,6 +126,30 @@ class NQP::Actions is HLL::Actions {
make $past;
}

method label($/) {
my $name := 'VNDUNVD84VN'~$<identifier>;
my $BLOCK := $*W.cur_lexpad();
if $BLOCK.symbol($name) {
$/.CURSOR.panic("Redeclaration of symbol ", $name);
}
$BLOCK.symbol($name, :scope('label') );
my $past := PAST::Label.new( :node($/), :name($name) );
make $past;
}

method goto($/) {
my $origname := $<identifier>;
my $name := 'VNDUNVD84VN'~$origname;
unless $*W.is_scope($name, 'label') {
$/.CURSOR.panic("missing label (no forward gotos) ", $origname);
}
my $past := PAST::Op.new(
:pasttype('goto'),
PAST::Label.new( :node($/), :name($name) )
);
make $past;
}

method statement($/, $key?) {
my $past;
if $<EXPR> {
Expand All @@ -150,6 +174,15 @@ class NQP::Actions is HLL::Actions {
}
}
elsif $<statement_control> { $past := $<statement_control>.ast; }
elsif $<label> {
$past := PAST::Stmts.new(
$<label>.ast,
$<statement>.ast
);
}
elsif $<goto> {
$past := $<goto>.ast;
}
else { $past := 0; }
make $past;
}
Expand Down
11 changes: 11 additions & 0 deletions src/NQP/Grammar.pm
Expand Up @@ -122,9 +122,20 @@ grammar NQP::Grammar is HLL::Grammar {
| [<statement><.eat_terminator> ]*
}

token label {
<identifier> ':' <?before \s> <.ws>
}

# not a real Perl 6 goto, so not a real &goto
token goto {
'goto' <?before \s> <.ws> <identifier>
}

token statement {
<!before <[\])}]> | $ >
[
| <goto>
| <label> <statement>
| <statement_control>
| <EXPR> <.ws>
[
Expand Down
53 changes: 51 additions & 2 deletions src/PAST/NQP.pir
Expand Up @@ -8,12 +8,63 @@
base = get_hll_global ['PAST'], 'Node'
p6meta.'new_class'('PAST::Want', 'parent'=>base)
p6meta.'new_class'('PAST::QAST', 'parent'=>base)
p6meta.'new_class'('PAST::Label', 'parent'=>base)
# add the nqp:: opcode map
.const 'Sub' nqpmap = 'nqpmap'
base.'map_add'('nqp', nqpmap)
.end
=head2 PAST::Label
A C<PAST::Label> node stores the name of a label. It
translates directly to a POST::Label.
=cut
=item as_post(PAST::Label)
Create the POST::Label.
=cut
.namespace ['PAST';'Compiler']
.sub 'as_post' :method :multi(_, ['PAST';'Label'])
.param pmc node
.param pmc options :slurpy :named
.local pmc label
.local string name
$P0 = get_hll_global ['POST'], 'Label'
name = node.'name'()
label = $P0.'new'('result'=>name)
.return (label)
.end
=item goto(PAST::Op)
implement the goto pasttype
=cut
.sub 'goto' :method :multi(_, ['PAST';'Op'])
.param pmc node
.param pmc options :slurpy :named
.local pmc lpast, ops, label
.local string name
lpast = node[0]
name = lpast.'name'()
$P0 = get_hll_global ['POST'], 'Ops'
ops = $P0.'new'('node'=>node)
$P0 = get_hll_global ['POST'], 'Label'
label = $P0.'new'('result'=>name)
ops.'push_pirop'('goto', label)
.return (ops)
.end
=head2 PAST::Want
Expand All @@ -37,8 +88,6 @@ Select a single past child based on rtype.
=cut
.namespace ['PAST';'Compiler']
.sub 'as_post' :method :multi(_, ['PAST';'Want'])
.param pmc node
.param pmc options :slurpy :named
Expand Down

0 comments on commit c98f22b

Please sign in to comment.