Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
implement labels for while loops
This allows the declaration of labels for all statements, and
adds next/redo/last LABEL functionality for while loops.
  • Loading branch information
FROGGS committed Nov 24, 2013
1 parent 2339be2 commit 3203a9f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
35 changes: 31 additions & 4 deletions src/NQP/Actions.nqp
Expand Up @@ -290,7 +290,10 @@ class NQP::Actions is HLL::Actions {
method statement_control:sym<while>($/) {
my $past := xblock_immediate( $<xblock>.ast );
$past.op(~$<sym>);
unless $*CONTROL_USED {
if $*LABEL {
$past.push(QAST::WVal.new( :value($*W.find_sym([$*LABEL])), :named('label') ));
}
elsif !$*CONTROL_USED {
$past.push(QAST::IVal.new( :value(1), :named('nohandler') ));
}
make $past;
Expand Down Expand Up @@ -1574,9 +1577,33 @@ class NQP::Actions is HLL::Actions {
);
}

method term:sym<next>($/) { make QAST::Op.new( :op('control'), :name('next') ) }
method term:sym<last>($/) { make QAST::Op.new( :op('control'), :name('last') ) }
method term:sym<redo>($/) { make QAST::Op.new( :op('control'), :name('redo') ) }
method term:sym<next>($/) {
my $ast := QAST::Op.new( :op('control'), :name('next') );

if $<identifier> {
$ast.push(QAST::WVal.new( :value($*W.find_sym([$<identifier>])), :named('label') ));
}

make $ast
}
method term:sym<last>($/) {
my $ast := QAST::Op.new( :op('control'), :name('last') );

if $<identifier> {
$ast.push(QAST::WVal.new( :value($*W.find_sym([$<identifier>])), :named('label') ));
}

make $ast
}
method term:sym<redo>($/) {
my $ast := QAST::Op.new( :op('control'), :name('redo') );

if $<identifier> {
$ast.push(QAST::WVal.new( :value($*W.find_sym([$<identifier>])), :named('label') ));
}

make $ast
}

method infix:sym<~~>($/) {
make QAST::Op.new( :op<callmethod>, :name<ACCEPTS>, :node($/) );
Expand Down
17 changes: 11 additions & 6 deletions src/NQP/Grammar.nqp
Expand Up @@ -152,14 +152,19 @@ grammar NQP::Grammar is HLL::Grammar {
}

token label {
:my $label;
<identifier> ':' <?[\s]> <.ws>
{
$*LABEL := ~$<identifier>;
my $label := $*W.find_sym(['NQPLabel']).new();
$*W.add_object($label);
$*W.install_lexical_symbol($*W.cur_lexpad(), $*LABEL, $label);
}
}

token statement {
token statement($*LABEL = '') {
<!before <[\])}]> | $ >
[
| <label> <statement>
| <label> <statement($*LABEL)> { $*LABEL := '' if $*LABEL }
| <statement_control>
| <EXPR> <.ws>
[
Expand Down Expand Up @@ -311,9 +316,9 @@ grammar NQP::Grammar is HLL::Grammar {
token term:sym<regex_declarator> { <regex_declarator> }
token term:sym<statement_prefix> { <statement_prefix> }
token term:sym<lambda> { <?lambda> <pblock> }
token term:sym<last> { <sym> <!identifier> { $*CONTROL_USED := 1 } }
token term:sym<next> { <sym> <!identifier> { $*CONTROL_USED := 1 } }
token term:sym<redo> { <sym> <!identifier> { $*CONTROL_USED := 1 } }
token term:sym<last> { <sym> [<.ws> <identifier> <?{ $*W.is_lexical(~$<identifier>) }>]? { $*CONTROL_USED := 1 } }
token term:sym<next> { <sym> [<.ws> <identifier> <?{ $*W.is_lexical(~$<identifier>) }>]? { $*CONTROL_USED := 1 } }
token term:sym<redo> { <sym> [<.ws> <identifier> <?{ $*W.is_lexical(~$<identifier>) }>]? { $*CONTROL_USED := 1 } }

token fatarrow {
<key=.identifier> \h* '=>' <.ws> <val=.EXPR('i=')>
Expand Down
2 changes: 2 additions & 0 deletions src/core/NQPMu.nqp
Expand Up @@ -134,3 +134,5 @@ nqp::sethllconfig('nqp', nqp::hash(
'hash_iter', NQPHashIter
));
#?endif

my class NQPLabel { }

0 comments on commit 3203a9f

Please sign in to comment.