Skip to content

Instantly share code, notes, and snippets.

@FROGGS
Last active December 27, 2015 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FROGGS/6f8989611659551dae1f to your computer and use it in GitHub Desktop.
Save FROGGS/6f8989611659551dae1f to your computer and use it in GitHub Desktop.
diff --git a/src/Perl6/Actions.nqp b/src/Perl6/Actions.nqp
index 5dc9f41..ac7690d 100644
--- a/src/Perl6/Actions.nqp
+++ b/src/Perl6/Actions.nqp
@@ -179,7 +179,7 @@ class Perl6::Actions is HLL::Actions does STDActions {
# attribute/lexpad), bind constraint (what could we bind to this
# slot later), and if specified a constraint on the inner value
# and a default value.
- sub container_type_info($/, $sigil, @value_type, $shape?) {
+ our sub container_type_info($/, $sigil, @value_type, $shape?) {
my %info;
if $sigil eq '@' {
%info<container_base> := $*W.find_symbol(['Array']);
diff --git a/src/Perl6/Grammar.nqp b/src/Perl6/Grammar.nqp
index 83f1578..ed5dba9 100644
--- a/src/Perl6/Grammar.nqp
+++ b/src/Perl6/Grammar.nqp
@@ -278,10 +278,61 @@ role STD {
}
if !$*IN_DECL && nqp::istype($varast, QAST::Var) && $varast.scope eq 'lexical' {
my $name := $varast.name;
- if $name ne '%_' && $name ne '@_' && !$*W.is_lexical($name) {
+ my $BLOCK := $*W.cur_lexpad();
+
+ my $current_block := $BLOCK;
+ my $is_lexical := 0;
+ my $is_lax := 0;
+ while $current_block {
+ my %sym := $current_block.symbol($name);
+ if +%sym {
+ $is_lexical := %sym<scope> eq 'lexical';
+ $is_lax := %sym<lax>;
+ last;
+ }
+ $current_block := $current_block<outer>
+ }
+
+ if $*STRICT && $is_lax {
+ my @suggestions := $*W.suggest_lexicals($name);
+ $*W.throw($var, ['X', 'Undeclared'], symbol => $varast.name(), suggestions => @suggestions);
+ }
+ if $name ne '%_' && $name ne '@_' && !$is_lexical {
if $var<sigil> ne '&' {
- my @suggestions := $*W.suggest_lexicals($name);
- $*W.throw($var, ['X', 'Undeclared'], symbol => $varast.name(), suggestions => @suggestions);
+ if !$*STRICT {
+ # Create a container descriptor. Default to rw and set a
+ # type if we have one; a trait may twiddle with that later.
+ my %cont_info := Perl6::Actions::container_type_info($/, $var<sigil>, $*OFTYPE ?? [$*OFTYPE.ast] !! []);
+ my $descriptor := $*W.create_container_descriptor(%cont_info<value_type>, 1, $name);
+
+ $*W.install_lexical_container($BLOCK, $name, %cont_info, $descriptor,
+ :scope('our'), :package($*PACKAGE));
+
+ # Set scope and type on container, and if needed emit code to
+ # reify a generic type.
+ if $varast.isa(QAST::Var) {
+ $varast.name($name);
+ $varast.scope('lexical');
+ $varast.returns(%cont_info<bind_constraint>);
+ if %cont_info<bind_constraint>.HOW.archetypes.generic {
+ $varast := QAST::Op.new(
+ :op('callmethod'), :name('instantiate_generic'),
+ QAST::Op.new( :op('p6var'), $varast ),
+ QAST::Op.new( :op('curlexpad') ));
+ }
+
+ $BLOCK[0].push(QAST::Op.new(
+ :op('bind'),
+ $varast,
+ $*W.symbol_lookup([$name], $/, :package_only(1), :lvalue(1))
+ ));
+ $BLOCK.symbol($name, :lax(1));
+ }
+ }
+ else {
+ my @suggestions := $*W.suggest_lexicals($name);
+ $*W.throw($var, ['X', 'Undeclared'], symbol => $varast.name(), suggestions => @suggestions);
+ }
}
else {
$var.CURSOR.add_mystery($varast.name, $var.to, 'var');
@@ -810,6 +861,7 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
:my $*PKGDECL; # what type of package we're in, if any
:my %*MYSTERY; # names we assume may be post-declared functions
:my $*CCSTATE := '';
+ :my $*STRICT := nqp::getlexdyn('$?FILES') ne '-e';
# Error related. There are three levels: worry (just a warning), sorry
# (fatal but not immediately so) and panic (immediately deadly). There
@@ -1001,8 +1053,9 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
}
rule statementlist {
- :my %*LANG := self.shallow_copy(nqp::getlexdyn('%*LANG'));
- :my %*HOW := self.shallow_copy(nqp::getlexdyn('%*HOW'));
+ :my %*LANG := self.shallow_copy(nqp::getlexdyn('%*LANG'));
+ :my %*HOW := self.shallow_copy(nqp::getlexdyn('%*HOW'));
+ :my $*STRICT := nqp::getlexdyn('$*STRICT');
:dba('statement list')
''
[
@@ -1255,6 +1308,30 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
}
}
+ token statement_control:sym<6> {
+ <?{ $*begin_compunit }> <sym> <?[;]> <.ws> <!!{ $*STRICT := 0; 1 }>
+ }
+
+ token statement_control:sym<no> {
+ :my $longname;
+ <sym> <.ws>
+ [
+ | <module_name>
+ {
+ $longname := $<module_name><longname>;
+
+ if $longname.Str eq 'strict' {
+ # Turn on lax mode.
+ $*STRICT := 0;
+ }
+ else {
+ nqp::die("Unknown pragma '$longname'");
+ }
+ }
+ ]
+ <.ws>
+ }
+
token statement_control:sym<use> {
:my $longname;
:my $*IN_DECL := 'use';
@@ -1263,7 +1340,7 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
$<doc>=[ 'DOC' \h+ ]**0..1
<sym> <.ws>
[
- | <version>
+ | <version> <!!{ $*STRICT := 1 if $*begin_compunit && ~$<version><vnum>[0] eq '6'; 1 }>
| <module_name>
{
$longname := $<module_name><longname>;
@@ -1280,6 +1357,11 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
$*SOFT := 1;
$longname := "";
}
+ elsif $longname.Str eq 'strict' {
+ # Turn off lax mode.
+ $*STRICT := 1;
+ $longname := "";
+ }
elsif $longname.Str eq 'FORBID_PIR' ||
$longname.Str eq 'Devel::Trace' ||
$longname.Str eq 'fatal' {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment