Skip to content

Commit 4b6085d

Browse files
committed
Avoid overly-cautious initializations.
This teaches NQP to distinguish 'my @A := [...];' from a 'my @A'. In the first case, we need not initialize @A with an empty array that we immediately throw away. Same for %h. For scalars it's less of a waste as we allocate nothing, but still can avoid the work.
1 parent 8510360 commit 4b6085d

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/NQP/Actions.nqp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ class NQP::Actions is HLL::Actions {
167167
$past := QAST::Op.new($ml<cond>.ast, $past, :op(~$ml<sym>), :node($/) );
168168
}
169169
}
170+
if $past<var_initialized> {
171+
# Variable declared and unconditionally initialized; can strip
172+
# the added just-to-be-safe initialization of the lexical and
173+
# just have the var decl.
174+
my $decls := $*W.cur_lexpad()[0];
175+
$decls.push($decls.pop()[0]); # First child of bind node is var decl
176+
}
170177
}
171178
elsif $<statement> { $past := $<statement>.ast; }
172179
elsif $<statement_control> { $past := $<statement_control>.ast; }
@@ -718,6 +725,11 @@ class NQP::Actions is HLL::Actions {
718725
$/.CURSOR.panic("Redeclaration of symbol ", $name);
719726
}
720727
if $*SCOPE eq 'has' {
728+
# Initializer not allowed.
729+
if $<initializer> {
730+
$/.CURSOR.panic('Initiailizers not supported on has-scoped variables');
731+
}
732+
721733
# Locate the type of meta-attribute we need.
722734
unless nqp::existskey(%*HOW, $*PKGDECL ~ '-attr') {
723735
$/.CURSOR.panic("$*PKGDECL packages do not support attributes");
@@ -755,6 +767,9 @@ class NQP::Actions is HLL::Actions {
755767
$name := ~$<variable>;
756768
$past := lexical_package_lookup([$name], $/);
757769
$BLOCK.symbol($name, :scope('package') );
770+
if $<initializer> {
771+
$past := QAST::Op.new( :op('bind'), $past, $<initializer>.ast );
772+
}
758773
}
759774
else {
760775
my $type;
@@ -779,6 +794,10 @@ class NQP::Actions is HLL::Actions {
779794
QAST::Var.new( :name($name), :scope('lexical'), :decl('var'), :returns($type) ),
780795
$default
781796
));
797+
if $<initializer> {
798+
$past := QAST::Op.new( :op('bind'), :node($/), $past, $<initializer>.ast );
799+
$past<var_initialized> := 1;
800+
}
782801
$BLOCK.symbol($name, :scope('lexical'), :type($type) );
783802
}
784803

@@ -790,6 +809,10 @@ class NQP::Actions is HLL::Actions {
790809
make $past;
791810
}
792811

812+
method initializer($/) {
813+
make $<EXPR>.ast;
814+
}
815+
793816
method routine_declarator:sym<sub>($/) { make $<routine_def>.ast; }
794817
method routine_declarator:sym<method>($/) { make $<method_def>.ast; }
795818

src/NQP/Grammar.nqp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ grammar NQP::Grammar is HLL::Grammar {
473473
<variable>
474474
{ $*IN_DECL := 0; }
475475
<trait>*
476+
<initializer>?
477+
}
478+
479+
token initializer {
480+
':=' <.ws> [ <EXPR('f=')> || <.panic: "Malformed binding"> ]
476481
}
477482

478483
proto rule routine_declarator { <...> }

0 commit comments

Comments
 (0)