-
-
Save FROGGS/6f8989611659551dae1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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